2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
25 int debug_packet (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
27 cli_debug
= CLI_DEBUG_PACKET
;
28 cli_print (cli
, "Packet debugging enabled\n");
35 // Enter packet config mode:
37 // 1) either with an optional packet slot number => modify existing slot
38 // 2) or without number to allocate a new slot entry
40 int enter_packet (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
44 if (argc
==0) { // Allocate new packet
45 if ((clipkt
= mops_alloc_packet(mp_head
)) == NULL
) { // Problem, memory full?
46 cli_print(cli
, "Holy flying spaghetti monster! Cannot allocate additional memory!\n");
49 // OK, created a new packet
50 snprintf(prompt
, 16, "pkt-%i",clipkt
->id
);
51 cli_print(cli
, "Allocated new packet %s at slot %i",clipkt
->packet_name
, clipkt
->id
);
52 // mops_set_defaults(clipkt); //// implicitly done by mops_alloc_packet
53 } else if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>1) ) {
54 cli_print(cli
, "<CR> create a new packet slot\r");
55 cli_print(cli
, "NAME enter packet slot of packet with name NAME\r");
56 cli_print(cli
, "ID enter packet slot of packet with number ID\n");
58 } else { // user specified a unique packet_name
59 if ( (clipkt
= mops_search_name (mp_head
, argv
[0]))==NULL
) { // packet name does not exist
60 if ( (clipkt
= mops_search_id (mp_head
, (int) str2int(argv
[0])))==NULL
) { // packet id does not exist
61 cli_print(cli
, "Packet does not exist\n");
65 if (mops_is_any_active(clipkt
)) { // don't allow to configure packets which are active!
66 cli_print(cli
, "The selected packet is currently in active state!\r");
67 cli_print(cli
, "In order to configure this packet, please stop the associated packet process first.\n");
70 snprintf(prompt
, 16, "pkt-%i",clipkt
->id
);
71 cli_print(cli
, "Modify packet parameters for packet %s [%i]",clipkt
->packet_name
, clipkt
->id
);
73 cli_set_configmode(cli
, MZ_MODE_PACKET
, prompt
);
74 //cli_print(cli, "Packet configuration mode - called %s with %s\r\n", __FUNCTION__, command);
84 // Specify the type and enter the appropriate configuration mode
85 // NOTE that we also reset and create the p_desc here!
86 int cmd_packet_type(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
90 char wrn
[] = "Error: Could not create mops extension handle\n";
92 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) )
94 cli_print(cli
, "Specify a packet type from the following list:\r\n");
95 cli_print(cli
, " arp\r");
96 cli_print(cli
, " bpdu\r");
97 // cli_print(cli, " cdp (not supported in this version)\r");
98 // cli_print(cli, " icmp (not supported in this version)\r");
99 cli_print(cli
, " igmp\r");
100 cli_print(cli
, " ip\r");
101 cli_print(cli
, " lldp\r");
102 cli_print(cli
, " rtp\r");
103 // cli_print(cli, " syslog (not supported in this version)\r");
104 cli_print(cli
, " tcp\r");
105 cli_print(cli
, " udp\r");
109 if (mz_strcmp(argv
[0],"arp",3) == 0)
111 if (mops_ext_add_pdesc (clipkt
, MOPS_ARP
))
112 cli_print(cli
, "%s", wrn
);
115 ret
=mops_clear_layers(clipkt
,
116 MOPS_SNAP
|MOPS_MPLS
|MOPS_IP
|MOPS_UDP
|MOPS_TCP
);
117 clipkt
->use_ETHER
= 1;
118 clipkt
->eth_type
= 0x806;
119 sprintf(prompt
, "pkt-%i-arp",clipkt
->id
);
120 cli_set_configmode(cli
, MZ_MODE_PACKET_ARP
, prompt
);
121 mops_update_arp(clipkt
);
122 mops_set_conf(clipkt
);
126 else if (mz_strcmp(argv
[0],"dns",3) == 0)
128 if (mops_ext_add_pdesc (clipkt
, MOPS_DNS
))
129 cli_print(cli
, "%s", wrn
);
132 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
);
133 clipkt
->use_ETHER
= 1;
136 sprintf(prompt
, "pkt-%i-dns",clipkt
->id
);
137 cli_set_configmode(cli
, MZ_MODE_PACKET_DNS
, prompt
);
138 mops_set_conf(clipkt
);
141 else if (mz_strcmp(argv
[0],"icmp",3) == 0)
143 if (mops_ext_add_pdesc (clipkt
, MOPS_ICMP
))
144 cli_print(cli
, "%s", wrn
);
147 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
|MOPS_UDP
);
148 clipkt
->use_ETHER
= 1;
150 sprintf(prompt
, "pkt-%i-icmp",clipkt
->id
);
151 cli_set_configmode(cli
, MZ_MODE_PACKET_ICMP
, prompt
);
152 mops_set_conf(clipkt
);
155 else if (mz_strcmp(argv
[0],"igmp",3) == 0)
157 if (mops_ext_add_pdesc (clipkt
, MOPS_IGMP
))
158 cli_print(cli
, "%s", wrn
);
161 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
|MOPS_UDP
);
162 clipkt
->use_ETHER
= 1;
164 clipkt
->ip_proto
= 2;
165 mops_ip_option_ra(clipkt
, 0); // add router alert option to IP header
166 sprintf(prompt
, "pkt-%i-igmp",clipkt
->id
);
167 cli_set_configmode(cli
, MZ_MODE_PACKET_IGMP
, prompt
);
168 mops_update_igmp(clipkt
);
169 mops_set_conf(clipkt
);
173 else if (mz_strcmp(argv
[0],"cdp",3) == 0)
175 if (mops_ext_add_pdesc (clipkt
, MOPS_CDP
))
176 cli_print(cli
, "%s", wrn
);
179 ret
=mops_clear_layers(clipkt
, MOPS_ALL
);
180 clipkt
->use_ETHER
= 1;
181 sprintf(prompt
, "pkt-%i-cdp",clipkt
->id
);
182 cli_set_configmode(cli
, MZ_MODE_PACKET_CDP
, prompt
);
183 mops_set_conf(clipkt
);
186 else if (mz_strcmp(argv
[0],"bpdu",3) == 0)
188 if (mops_ext_add_pdesc (clipkt
, MOPS_BPDU
))
189 cli_print(cli
, "%s", wrn
);
192 ret
=mops_clear_layers(clipkt
, MOPS_MPLS
|MOPS_IP
|MOPS_UDP
|MOPS_TCP
);
193 clipkt
->use_ETHER
= 1;
194 clipkt
->use_SNAP
= 1;
195 sprintf(prompt
, "pkt-%i-bpdu",clipkt
->id
);
196 cli_set_configmode(cli
, MZ_MODE_PACKET_BPDU
, prompt
);
197 mops_update_bpdu(clipkt
);
198 mops_set_conf(clipkt
);
201 else if (mz_strcmp(argv
[0],"ip",2) == 0)
203 ret
=mops_clear_layers(clipkt
, MOPS_TCP
|MOPS_UDP
);
204 clipkt
->use_ETHER
= 1;
206 sprintf(prompt
, "pkt-%i-ip",clipkt
->id
);
207 cli_set_configmode(cli
, MZ_MODE_PACKET_IP
, prompt
);
208 mops_set_conf(clipkt
);
210 else if (mz_strcmp(argv
[0],"udp",3) == 0)
212 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
);
213 clipkt
->use_ETHER
= 1;
216 clipkt
->ip_proto
= 17;
217 sprintf(prompt
, "pkt-%i-udp",clipkt
->id
);
218 cli_set_configmode(cli
, MZ_MODE_PACKET_UDP
, prompt
);
219 mops_set_conf(clipkt
);
221 else if (mz_strcmp(argv
[0],"tcp",3) == 0)
223 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_UDP
);
224 clipkt
->use_ETHER
= 1;
227 clipkt
->ip_proto
= 6;
228 sprintf(prompt
, "pkt-%i-tcp",clipkt
->id
);
229 cli_set_configmode(cli
, MZ_MODE_PACKET_TCP
, prompt
);
230 mops_set_conf(clipkt
);
232 else if (mz_strcmp(argv
[0],"syslog",3) == 0)
234 if (mops_ext_add_pdesc (clipkt
, MOPS_SYSLOG
))
235 cli_print(cli
, "%s", wrn
);
238 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
);
239 clipkt
->use_ETHER
= 1;
242 sprintf(prompt
, "pkt-%i-syslog",clipkt
->id
);
243 cli_set_configmode(cli
, MZ_MODE_PACKET_SYSLOG
, prompt
);
244 mops_set_conf(clipkt
);
247 else if (mz_strcmp(argv
[0],"lldp",3) == 0)
249 if (mops_ext_add_pdesc (clipkt
, MOPS_LLDP
))
250 cli_print(cli
, "%s", wrn
);
253 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_IP
|MOPS_UDP
|MOPS_TCP
);
254 clipkt
->use_ETHER
= 1;
255 sprintf(prompt
, "pkt-%i-lldp",clipkt
->id
);
256 cli_set_configmode(cli
, MZ_MODE_PACKET_LLDP
, prompt
);
257 mops_set_conf(clipkt
);
260 else if (mz_strcmp(argv
[0],"rtp",3) == 0)
262 if (mops_ext_add_pdesc (clipkt
, MOPS_RTP
))
263 cli_print(cli
, "%s", wrn
);
266 ret
=mops_clear_layers(clipkt
, MOPS_SNAP
|MOPS_TCP
);
267 clipkt
->use_ETHER
= 1;
270 sprintf(prompt
, "pkt-%i-rtp",clipkt
->id
);
271 cli_set_configmode(cli
, MZ_MODE_PACKET_RTP
, prompt
);
272 mops_set_conf(clipkt
);
276 else // wrong user input
278 cli_print(cli
, "Unknown type\n");
283 cli_print(cli
, "Note that the following layer(2) have configured information:\r");
284 if (ret
& 1) cli_print(cli
, " - Ethernet or 802.3\r");
285 if (ret
& 2) cli_print(cli
, " - SNAP\r");
286 if (ret
& 4) cli_print(cli
, " - 802.1Q\r");
287 if (ret
& 8) cli_print(cli
, " - MPLS\r");
288 if (ret
& 16) cli_print(cli
, " - IP\r");
289 if (ret
& 32) cli_print(cli
, " - UDP\r");
290 if (ret
& 64) cli_print(cli
, " - TCP\r");
301 int cmd_packet_end(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
303 cli_set_configmode(cli
, MODE_CONFIG
, NULL
);
311 int cmd_packet_clone (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
318 // Reserved words: "all", "slot"
319 int cmd_packet_name (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
321 if (strncmp(argv
[0], "?", 2) == 0)
323 cli_print(cli
, "Assign a packet name (max 16 chars)\n");
329 cli_print(cli
, "Packet name must not contain spaces\n");
333 if (strlen(argv
[0])>MAX_MOPS_PACKET_NAME_LEN
)
335 cli_print(cli
, "Packet name is limited to %i chars. You might use the 'description' command.\n",MAX_MOPS_PACKET_NAME_LEN
);
339 if (mz_strcmp(argv
[0], "all", 3)==0)
341 cli_print(cli
, "This is a reserved word. Please choose another\n");
345 strncpy(clipkt
->packet_name
, argv
[0], MAX_MOPS_PACKET_NAME_LEN
);
346 clipkt
->packet_name
[MAX_MOPS_PACKET_NAME_LEN
-1] = 0x00;
347 // cli_print(cli, "Changed packet name to '%s'\n", clipkt->packet_name);
352 int cmd_packet_description (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
354 if (strncmp(argv
[argc
-1], "?", 2) == 0)
356 cli_print(cli
, "Assign a packet description (max %i chars)\n", MAX_MOPS_DESCRIPTION_LEN
);
360 if (mops_pdesc_mstrings (clipkt
->description
, argv
, argc
, MAX_MOPS_DESCRIPTION_LEN
))
362 cli_print(cli
, "String too long. Currently the description is limited to %i characters.\n",
363 MAX_MOPS_DESCRIPTION_LEN
);
364 cli_print(cli
, "Current description is:\n%s\n", clipkt
->description
);
370 int cmd_packet_count (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
373 if (strncmp(argv
[argc
-1], "?", 2) == 0)
375 cli_print(cli
,"Specify the packet count. Zero means infinity.\n");
380 clipkt
->count
= (unsigned long) str2int(argv
[0]);
383 clipkt
->cntx
= clipkt
->count
; // count is finite: cntx will count down
387 clipkt
->cntx
= 0; // infinity: cntx will count up
391 cli_print(cli
,"Specify a packet count.\n");
396 int cmd_packet_delay (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
401 if (strncmp(argv
[argc
-1], "?", 2) == 0) {
402 cli_print(cli
, "delay <value> [hour | min | sec | msec | usec | nsec]\n");
403 cli_print(cli
, "Specify the inter-packet delay in hours, minutes, seconds, milliseconds, microseconds,\r");
404 cli_print(cli
, "or nanoseconds. The default unit is milliseconds (i. e. when no unit is given).\n");
409 case 1: // only one argument, but may contain an unit (such as '314sec')
410 ret
= delay_parse(&clipkt
->ndelay
, argv
[0], NULL
);
413 case 2: // user specified two arguments such as '100 msec'
414 ret
= delay_parse(&clipkt
->ndelay
, argv
[0], argv
[1]);
417 cli_print(cli
, "Too many arguments! Expected delay value and unit, such as '10 msec'\n");
423 cli_print(cli
, "Invalid unit! Use one of {nsec, usec, msec, sec, min, hours}\n");
427 cli_print(cli
, "Value too large! Supported range is from 0 to 999999999\n");
431 sprintf(str
, "Inter-packet delay set to %lu sec and %lu nsec", clipkt
->ndelay
.tv_sec
, clipkt
->ndelay
.tv_nsec
);
432 cli_print(cli
, "%s\n", str
);
439 int cmd_packet_bind (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
443 if (strncmp(argv
[argc
-1], "?", 2) == 0)
445 cli_print(cli
,"<DEVICE> Change the packet's network interface\r");
446 cli_print(cli
,"default Use interface settings as packet default\n");
451 if (mz_strcmp(argv
[0], "default", 3)==0)
453 i
= mops_get_device_index(clipkt
->device
);
454 // Copy device_list[i].ip_mops and .mac_mops to clipkt->ip_src and ->eth_src
455 memcpy((void *) &clipkt
->eth_src
, (void *) &device_list
[i
].mac_mops
[0], 6);
456 memcpy((void *) &clipkt
->ip_src
, (void *) &device_list
[i
].ip_mops
[0], 4);
460 i
= mops_get_device_index(argv
[0]);
464 strncpy(clipkt
->device
, argv
[0], 16); // assign device to this mops
465 mops_use_device(clipkt
, i
);
468 cli_print(cli
, "Unknown device, will stick on %s\n", clipkt
->device
);
472 cli_print(cli
, "Nothing specified, will stick on %s\n", clipkt
->device
);
483 // FORMAT: <VLAN>:<CoS> such as: "100:3 17:5 ..."
484 // NOTE: LEFTMOST TAG = OUTER TAG IN FRAME
485 // CFI is set/unset separately (see ? below)
486 // Transmission format: 0x8100 plus CoS (3) CFI(1) VLAN(12)
487 int cmd_packet_dot1q (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
491 char Vlan
[64], CoS
[64];
494 if (strcmp(argv
[argc
-1],"?")==0)
496 cli_print(cli
, "Configure 802.1Q tags:\n");
497 cli_print(cli
, " VLAN[:CoS] [VLAN[:CoS]] ... The leftmost tag is the outer tag in the frame\r");
498 cli_print(cli
, " remove <tag-nr> | all Remove one or more tags (<tag-nr> starts with 1),\r");
499 cli_print(cli
, " by default the first (=leftmost,outer) tag is removed,\r");
500 cli_print(cli
, " keyword 'all' can be used instead of tag numbers.\r");
501 cli_print(cli
, " cfi | nocfi [<tag-nr>] Set or unset the CFI-bit in any tag (by default\r");
502 cli_print(cli
, " assuming the first tag).\n");
508 cli_print(cli
, "Specify one or more VLAN-IDs, optionally with CoS values\n");
512 n
= clipkt
->dot1Q_s
/4; // n = number of tags
514 //////////////////////////////////////////
515 if (mz_strcmp(argv
[0], "remove", 2)==0)
520 cli_print(cli
, "Too many arguments!\n");
526 cli_print(cli
, "No 802.1Q tags present. None to be removed.\n");
530 if ((argc
==2) && (mz_strcmp(argv
[1], "all", 1)==0))
532 mops_dot1Q_remove(clipkt
, 0);
536 if (argc
==1) // no tag-nr specified => assume first tag
542 j
= (unsigned int) str2int(argv
[1]); // take first argument
545 cli_print(cli
, "The tag-nr must be within {1..%i}\n", n
);
551 if (mops_dot1Q_remove(clipkt
, j
))
553 cli_print(cli
, "The packet only consists of %i tag(s)!\n", n
);
559 /////////////////////////////////////////
560 if (mz_strcmp(argv
[0], "nocfi", 2)==0)
564 cli_print(cli
, "There are no 802.1Q tags yet!\n");
570 cli_print(cli
, "Invalid format!\n");
574 if (argc
==1) // no tag-nr specified => assume first tag
580 j
= (unsigned int) str2int(argv
[1]);
583 if (mops_dot1Q_nocfi(clipkt
, j
))
585 cli_print(cli
, "The packet only consists of %i tags!\n",k
);
590 ///////////////////////////////////////
591 if (mz_strcmp(argv
[0], "cfi", 2)==0)
595 cli_print(cli
, "There are no 802.1Q tags yet!\n");
601 cli_print(cli
, "Invalid format!\n");
605 if (argc
==1) // no tag-nr specified => assume first tag
611 j
= (unsigned int) str2int(argv
[1]);
614 if (mops_dot1Q_cfi(clipkt
, j
))
616 cli_print(cli
, "The packet only consists of %i tags!\n",k
);
622 /////////////////////////
623 for (i
=0; i
<argc
; i
++) // scan through all user tokens
627 if (mz_tok(argv
[i
],":",2, Vlan
, CoS
) == -1)
629 cli_print(cli
, "Invalid format. Correct format: VLAN[:CoS] [VLAN[:CoS] ...]\n");
635 cli_print(cli
, "[tag %i] Missing VLAN number\n", i
+1);
640 v
= (u_int16_t
) str2int(Vlan
);
643 cli_print(cli
, "[tag %i] VLAN number must not exceed 4095.\n", i
+1);
654 c
= (u_int16_t
) str2int(CoS
);
657 cli_print(cli
, "[tag %i] CoS must not exceed 7.\n", i
+1);
662 mops_dot1Q (clipkt
, i
, 1, v
, c
); // 3rd param '1' means 'new stack, also set dot1Q_s'
668 // MPLS transmission format: Label(20) EXP(3) BoS(1) TTL(8)
669 // -- where BoS=0 indicate MORE labels, BoS=1 means last (bottom) label
671 // NOTE: The EtherType must be 0x8847 which identifies 'IP over MPLS' that is
672 // we do NOT need to set 0x800 for IP somewhere! Instead, mops_update()
673 // will always correctly set the single EtherType, if necessary after
674 // 802.1Q tags. For example when VLAN tags are present, the frame looks
675 // like this:----------------------------------vvvv-----------------------
676 // DMAC-SMAC-8100VLAN1-...-8100VLANn-EtherType(8847)-MPLS1-...-MPLSn-IP...
678 // MPLS Multicast packets are indicated by EtherType 8848 (!)
679 // See also RFC 5332 which allows both 'Codepoints' to carry MPLS multicast
680 // while 0x8848 only indicates multiaccess media.
682 // NOTE: If all MPLS labels are removed again, the original EtherType is restored again!
683 // The original EtherType is stored in mp->eth_type_backup
684 int cmd_packet_mpls (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
687 char LabelS
[64], ExpS
[64], TTLS
[64];
693 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
==0) )
695 cli_print(cli
, "Configure one or more MPLS labels:\r");
696 cli_print(cli
, " LABEL[:EXP[:TTL]] [LABEL[:EXP[:TTL]]] ... The leftmost tag is the outer tag in frame\r");
697 cli_print(cli
, " remove <tag-nr> | all Remove tag with number <tag-nr> (starts with 1) or all.\r");
698 cli_print(cli
, " bos | nobos [<tag-nr>] Set/unset BoS flag, by default in last (rightmost) label\r");
699 cli_print(cli
, " unicast|multicast Choose EtherType 0x8847 or 0x8848 respectively\n");
700 cli_print(cli
, "Examples:\r");
701 cli_print(cli
, " tag mpls 100 200 300 Specify three tags, 100,200,300 \r");
702 cli_print(cli
, " tag mpls 100:5 200:5:1 Let first tag have CoS 5, second tag additionally uses TTL=1\r");
703 cli_print(cli
, " tag mpls 100::8 Let first tag have TTL=8\n");
704 cli_print(cli
, "Reserved label numbers:\r");
705 cli_print(cli
, " 0 ... explicit NULL (IPv4)\r");
706 cli_print(cli
, " 1 ... Router Alert\r");
707 cli_print(cli
, " 2 ... explicit NULL (IPv6)\r");
708 cli_print(cli
, " 3 ... implicit NULL (only announced within LDP)\r");
709 cli_print(cli
, " 14 ... OAM Alert (ITU-T Y.1711, RFC 3429)\n");
713 ///////////////////////////////////////////
714 if (mz_strcmp(argv
[0], "unicast", 2)==0)
716 if (clipkt
->use_MPLS
==0)
718 cli_print(cli
, "First configure an MPLS label stack.");
724 cli_print(cli
, "This command does not support any argument.\n");
727 clipkt
->eth_type
= 0x8847;
731 /////////////////////////////////////////////
732 if (mz_strcmp(argv
[0], "multicast", 2)==0)
734 if (clipkt
->use_MPLS
==0)
736 cli_print(cli
, "First configure an MPLS label stack.");
742 cli_print(cli
, "This command does not support any argument.\n");
745 clipkt
->eth_type
= 0x8848;
749 k
= clipkt
->mpls_s
/4; // number of available tags
751 //////////////////////////////////////////
752 if (mz_strcmp(argv
[0], "remove", 2)==0)
756 cli_print(cli
, "Too many arguments!\n");
760 if ((argc
==2) && (mz_strcmp(argv
[1], "all", 1)==0))
762 if (mops_mpls_remove(clipkt
, 0))
763 cli_print(cli
, "No MPLS label stack present. Nothing removed\n");
767 if (argc
==1) // no tag-nr specified => assume first tag
770 cli_print(cli
, "Currently the packet has no tag that can be removed.\n");
776 j
= (unsigned int) str2int(argv
[1]); // take first argument
778 if (mops_mpls_remove(clipkt
, j
))
779 cli_print(cli
, "The tag number must be within 1..%i\n",k
);
784 ///////////////////////////////////////
785 if (mz_strcmp(argv
[0], "bos", 2)==0)
789 cli_print(cli
, "Too many arguments\n");
794 i
= (int) str2int(argv
[1]);
797 cli_print(cli
, "Tag number exceeds actual number of tags (%i)\n",a
);
801 else // argc==1 (no tag number specified)
803 i
= k
; // default: last tag!
806 mops_mpls_bos (clipkt
, i
);
810 if (mz_strcmp(argv
[0], "nobos", 2)==0)
814 cli_print(cli
, "Too many arguments\n");
819 i
= (int) str2int(argv
[1]);
822 cli_print(cli
, "Tag number exceeds actual number of tags (%i)\n",k
);
826 else // argc==1 (no tag number specified)
828 i
= k
; // default: last tag!
830 mops_mpls_nobos (clipkt
, i
);
835 ////////////////////////////////////////////
836 for (i
=0;i
<argc
;i
++) // Get all labels
838 if (mz_tok(argv
[i
], ":", 3, LabelS
, ExpS
, TTLS
) < 0)
840 cli_print(cli
, "[Tag %i]Incorrect label specification! Use format LABEL[:EXP[:TTL]]\n", i
+1);
847 cli_print(cli
, "[Tag %i] Invalid label value!\n", i
+1);
852 Label
= (u_int32_t
) str2int (LabelS
);
855 cli_print(cli
, "[Tag %i] Label value cannot exceed 1048575\n", i
+1);
866 Exp
= (u_int8_t
) str2int(ExpS
);
869 cli_print(cli
, "[Tag %i] EXP value must be within range 0..7\n", i
+1);
881 if (str2int(TTLS
)>255)
883 cli_print(cli
, "[Tag%i] TTL value must be within range 0..255\n", i
+1);
886 TTL
= (u_int8_t
) str2int(TTLS
);
890 mops_mpls(clipkt
, i
, argc
, Label
, Exp
, TTL
);
899 // payload hex ff:00:01:02:aa:bb:cc:dd aa:bb:cc
900 // payload hex file tmp/dump.dat
902 int cmd_packet_payload_hex (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
904 char str
[MAX_MOPS_MSG_SIZE
*3];
907 if (strncmp(argv
[argc
-1], "?", 2)==0)
909 cli_print(cli
, "Specify a payload in hexadecimal format:\n");
910 cli_print(cli
, " XX:XX:XX:... Either directly as sequence of digits, separated by colon or space\r");
911 cli_print(cli
, " file <filename> Or specify a filename with hexadecimal digits as content\r");
912 cli_print(cli
, " (Also in the file the separator can be either a colon or a space)\n");
913 cli_print(cli
, "Example: \r");
914 cli_print(cli
, "payload hex ff:ff:ff:ff:ff:ff 00:12:34:56:67:89 08:00 ca:fe:ba:be\n");
920 cli_print(cli
, "Specify an ascii payload\n");
925 if (mz_strcmp(argv
[0],"file", 2)==0)
927 // > > > > > ******* TODO: Open file and configure mops with filepointer ******** < < < < < < < <
928 cli_print(cli
, "This feature is currently not supported.\n");
932 // Get byte sequence - first copy into str
933 if (mops_pdesc_mstrings (str
, argv
, argc
, MAX_MOPS_MSG_SIZE
*3))
935 cli_print(cli
, "Payload too long (limited to %i bytes).\n", MAX_MOPS_MSG_SIZE
);
937 else // str contains byte sequence now - convert into msg and set msg_s
940 for (i
=0; i
<len
; i
++)
944 cli_print(cli
, "Specify hexadecimal digits {1234567890abcdef} or separators\n");
948 if ( (!isxdigit(str
[i
])) && // Only allow "1234567890abcdefABCDEF", ":", ".", "-", and SPACE.
949 (!isspace(str
[i
])) &&
954 cli_print(cli
, "Invalid character at position %i\n", i
+1);
959 len
= str2hex (str
, clipkt
->msg
, MAX_MOPS_MSG_SIZE
);
962 cli_print(cli
, "Invalid byte sequence. Each byte must be specified with two hexadecimal digits.\n");
966 clipkt
->msg_s
= (u_int32_t
) len
;
974 int cmd_packet_payload_ascii (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
976 char str
[MAX_MOPS_MSG_SIZE
*3];
979 if (strncmp(argv
[argc
-1], "?", 2)==0)
981 cli_print(cli
, "Specify a payload in ascii format.\r");
982 cli_print(cli
, "Note that multiple white spaces are replaced by a single white space. If you\r");
983 cli_print(cli
, "really want to specify multiple white spaces then use a dash '-' instead of\r");
984 cli_print(cli
, "a white space. If you want to specify a dash then use a caret '^' as escape\r");
985 cli_print(cli
, "character.\n");
992 cli_print(cli
, "Specify an ascii payload\n");
997 if (mz_strcmp(argv
[0],"file", 2)==0)
999 // > > > > > ******* TODO: Open file and configure mops with filepointer ******** < < < < < < < <
1000 cli_print(cli
, "This feature is currently not supported.\n");
1004 // Get byte sequence - first copy into str
1005 if (mops_pdesc_mstrings (str
, argv
, argc
, MAX_MOPS_MSG_SIZE
))
1007 cli_print(cli
, "Payload too long (limited to %i bytes).\n", MAX_MOPS_MSG_SIZE
);
1009 else // str contains byte sequence now - convert into msg and set msg_s
1012 for (i
=0; i
<len
; i
++) // Replace
1016 if ((i
>0) && (str
[i
-1]=='^'))
1018 memcpy((void*) &str
[i
-1], (void*) &str
[i
], len
-i
+1);
1027 len
--; // to eliminate the trailing space (created by mops_pdesc_mstring)
1028 memcpy((void*) clipkt
->msg
, (void*) str
, len
);
1029 clipkt
->msg_s
= len
;
1035 int cmd_packet_payload_raw (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1043 int cmd_packet_interval (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1045 unsigned long long iv
, tv_sec
=0;
1047 if (strncmp(argv
[argc
-1], "?", 1)==0) {
1048 cli_print(cli
, "Configure a greater packet interval in days, hours, minutes, or seconds\n");
1049 cli_print(cli
, "Arguments: <value> <days | hours | minutes | seconds>\n");
1050 cli_print(cli
, "Use a zero value to disable an interval.\n");
1055 cli_print(cli
,"Enter a value and an unit\n");
1060 if (mz_strisnum(argv
[0])==0) {
1061 cli_print(cli
,"Invalid value\n");
1065 iv
= str2lint(argv
[0]);
1068 cli_print(cli
,"Interval disabled.\n");
1069 clipkt
->interval_used
= 0;
1073 if (mz_strcmp(argv
[1], "days", 1)==0) {
1075 cli_print(cli
, "Supported range: 1..365 days\n");
1078 tv_sec
= 86400 * iv
;
1081 if (mz_strcmp(argv
[1], "hours", 1)==0) {
1083 cli_print(cli
, "Supported range: 1..1000 hours\n");
1089 if (mz_strcmp(argv
[1], "minutes", 1)==0) {
1091 cli_print(cli
, "Supported range: 1..1000 minutes\n");
1097 if (mz_strcmp(argv
[1], "seconds", 1)==0) {
1099 cli_print(cli
, "Supported range: 1..999999 seconds\n");
1105 if (clipkt
->count
==0) {
1106 cli_print(cli
, "Note: reconfigured count value from 0 (infinity) to 1.\n");
1110 if ((clipkt
->count
* clipkt
->ndelay
.tv_sec
)>tv_sec
) {
1111 cli_print(cli
, "Error: intervals are smaller than packet trains.\r");
1112 cli_print(cli
, "Reduce either count or delay, or both\n");
1116 clipkt
->interval
.tv_sec
= tv_sec
;
1117 clipkt
->interval_used
= 1;