dev: mark paths likely/unlikely
[netsniff-ng.git] / staging / cli_ip.c
blob55f5683c65cbee1367594995603e9e19c2d6ff3c
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
4 *
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.
8 *
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
12 * details.
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
21 #include "mz.h"
22 #include "cli.h"
23 #include "mops.h"
26 // ------- TOC ---------
27 //
28 // int cmd_ip_address_source (struct cli_def *cli, char *command, char *argv[], int argc)
29 // int cmd_ip_address_destination (struct cli_def *cli, char *command, char *argv[], int argc)
30 // int cmd_ip_version (struct cli_def *cli, char *command, char *argv[], int argc)
31 // int cmd_ip_ttl (struct cli_def *cli, char *command, char *argv[], int argc)
32 // int cmd_ip_protocol (struct cli_def *cli, char *command, char *argv[], int argc)
33 // int cmd_ip_hlen (struct cli_def *cli, char *command, char *argv[], int argc)
34 // int cmd_ip_len (struct cli_def *cli, char *command, char *argv[], int argc)
35 // int cmd_ip_id (struct cli_def *cli, char *command, char *argv[], int argc)
36 // int cmd_ip_offset (struct cli_def *cli, char *command, char *argv[], int argc)
37 // int cmd_ip_sum (struct cli_def *cli, char *command, char *argv[], int argc)
38 // int cmd_ip_tos (struct cli_def *cli, char *command, char *argv[], int argc)
39 // int cmd_ip_dscp (struct cli_def *cli, char *command, char *argv[], int argc)
40 // int cmd_ip_rsv (struct cli_def *cli, char *command, char *argv[], int argc)
41 // int cmd_ip_df (struct cli_def *cli, char *command, char *argv[], int argc)
42 // int cmd_ip_mf (struct cli_def *cli, char *command, char *argv[], int argc)
43 // int cmd_ip_option (struct cli_def *cli, char *command, char *argv[], int argc)
47 // ip-address source default|<IP>|rand|range
48 //
49 // default
50 // random
51 // A.B.C.D
52 // A.B.C.D /24
53 // A.B.C.D E.F.G.H
54 int cmd_ip_address_source (struct cli_def *cli, const char *command, char *argv[], int argc)
56 u_int8_t IP1[4], IP2[4];
57 u_int32_t ip1, ip2;
58 unsigned int prefix;
59 u_int32_t mask, invmask;
60 int i,r;
62 if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
64 cli_print(cli, "A.B.C.D configure a source IP address\n");
65 cli_print(cli, "Optionally you may specify\r");
66 cli_print(cli, "- a range of addresses, such as: 192.168.0.0 /16\r");
67 cli_print(cli, " or: 192.168.0.1 192.168.255.255\r");
68 cli_print(cli, "- 'random' for a randomly generated source address\r");
69 cli_print(cli, "- 'default' for the interface default settings\n");
70 return CLI_OK;
73 switch (argc)
75 case 1:
76 if (mz_strcmp(argv[0], "default", 3)==0)
78 // find index of device_list with the device configured in clipkt:
79 i=0;
80 while (strncmp(device_list[i].dev, clipkt->device, 10) && (i<device_list_entries)) i++;
81 clipkt->ip_src = device_list[i].ip_mops[3]
82 + device_list[i].ip_mops[2] * 256
83 + device_list[i].ip_mops[1] * 256 * 256
84 + device_list[i].ip_mops[0] * 256 * 256 * 256;
85 clipkt->ip_src_israndom = 0;
86 clipkt->ip_src_isrange = 0;
88 else if (mz_strcmp(argv[0], "random", 3)==0)
90 clipkt->ip_src_israndom = 1;
91 clipkt->ip_src_isrange = 0;
93 else if (mops_pdesc_ip (IP1, argv[0])==0) // check if format is really an IP address
95 clipkt->ip_src = str2ip32(argv[0]);
96 clipkt->ip_src_israndom = 0;
97 clipkt->ip_src_isrange = 0;
99 else // wrong input
101 cli_print(cli,"Invalid address/keyword\n");
103 break;
104 case 2: // MUST be either like '10.1.1.0 /24' or '10.1.1.1 10.1.1.254'
105 if (mops_pdesc_ip (IP1, argv[0])==0) // check if format is really an IP address
107 clipkt->ip_src_start = str2ip32(argv[0]);
108 if (strlen(argv[1])<4) // probably prefix?
110 r=sscanf(argv[1],"/%u",&prefix);
111 if ((r==EOF) || (r==0) || (prefix<1) || (prefix>31))
112 cli_print(cli, "Invalid prefix!\n");
113 else
115 mask = 0xffffffff;
116 mask <<= (32-prefix);
117 invmask = 0xffffffff - mask;
118 ip1 = ((str2ip32 (argv[0])) & mask) +1; // the '+1' is to ensure that we do not start with the net-id
119 ip2 = ip1 | invmask;
120 clipkt->ip_src_start = ip1;
121 clipkt->ip_src_stop = ip2;
122 clipkt->ip_src_isrange = 1;
123 clipkt->ip_src_israndom = 0;
126 else if (mops_pdesc_ip (IP2, argv[1])==0) // probably 2nd IP address?
128 if (str2ip32(argv[1]) > clipkt->ip_src_start)
130 clipkt->ip_src_stop = str2ip32(argv[1]);
131 clipkt->ip_src_isrange = 1;
132 clipkt->ip_src_israndom = 0;
134 else
136 cli_print(cli, "Invalid range! The second IP address must be greater than the first!\n");
139 else
141 cli_print(cli, "Second parameter must be either a valid IP address or a prefix length \n");
144 else // first string is not a valid IP address
146 cli_print(cli, "First parameter must be a valid IP address\n");
148 break;
149 default:
150 cli_print(cli, "Invalid format!\n");
153 return CLI_OK;
158 // ip-address destination <IP>|range
159 int cmd_ip_address_destination (struct cli_def *cli, const char *command, char *argv[], int argc)
161 u_int8_t IP1[4], IP2[4];
162 u_int32_t ip1, ip2;
163 unsigned int prefix;
164 u_int32_t mask, invmask;
165 int r;
167 if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
169 cli_print(cli, "A.B.C.D configure a destination IP address\n");
170 cli_print(cli, "Optionally specify a range of addresses, such as: 192.168.0.0 /16\r");
171 cli_print(cli, " or: 192.168.0.1 192.168.255.255\n");
172 return CLI_OK;
175 switch (argc)
177 case 1:
178 if (mops_pdesc_ip (IP1, argv[0])==0) // check if format is really an IP address
180 clipkt->ip_dst = str2ip32(argv[0]);
181 clipkt->ip_dst_isrange = 0;
183 else // wrong input
185 cli_print(cli,"Invalid address/range\n");
187 break;
188 case 2: // MUST be either like '10.1.1.0 /24' or '10.1.1.1 10.1.1.254'
189 if (mops_pdesc_ip (IP1, argv[0])==0) // check if format is really an IP address
191 clipkt->ip_dst_start = str2ip32(argv[0]);
192 if (strlen(argv[1])<4) // probably prefix?
194 r=sscanf(argv[1],"/%u",&prefix);
195 if ((r==EOF) || (r==0) || (prefix<1) || (prefix>31))
196 cli_print(cli, "Invalid prefix!\n");
197 else
199 mask = 0xffffffff;
200 mask <<= (32-prefix);
201 invmask = 0xffffffff - mask;
202 ip1 = ((str2ip32 (argv[0])) & mask) +1; // the '+1' is to ensure that we do not start with the net-id
203 ip2 = ip1 | invmask;
204 clipkt->ip_dst_start = ip1;
205 clipkt->ip_dst_stop = ip2;
206 clipkt->ip_dst_isrange = 1;
209 else if (mops_pdesc_ip (IP2, argv[1])==0) // probably 2nd IP address?
211 if (str2ip32(argv[1]) > clipkt->ip_dst_start)
213 clipkt->ip_dst_stop = str2ip32(argv[1]);
214 clipkt->ip_dst_isrange = 1;
216 else
218 cli_print(cli, "Range requirement: The second IP address must be greater than the first!\n");
221 else
223 cli_print(cli, "Second parameter must be either a valid IP address or a prefix length \n");
226 else // first string is not a valid IP address
228 cli_print(cli, "First parameter must be a valid IP address\n");
230 break;
231 default:
232 cli_print(cli, "Invalid IP or range specification!\n");
235 return CLI_OK;
241 int cmd_ip_version (struct cli_def *cli, const char *command, char *argv[], int argc)
243 int ver;
245 if (strncmp(argv[argc-1], "?", 2)==0)
247 cli_print(cli, "Specify the IP version (default: 4).\n");
248 return CLI_OK;
251 ver = (int) str2int(argv[0]);
253 if (ver>15)
255 cli_print(cli, "Version must be within range 0..15\n");
256 return CLI_OK;
259 clipkt->ip_version = ver;
261 return CLI_OK;
266 int cmd_ip_ttl (struct cli_def *cli, const char *command, char *argv[], int argc)
268 int ttl;
270 if (strncmp(argv[argc-1], "?", 2)==0)
272 cli_print(cli, "Specify the TTL (default: 255).\n");
274 return CLI_OK;
277 ttl = (int) str2int(argv[0]);
279 if (ttl>255)
281 cli_print(cli, "TTL must be within range 0..255\n");
282 return CLI_OK;
285 clipkt->ip_ttl = ttl;
288 return CLI_OK;
293 int cmd_ip_protocol (struct cli_def *cli, const char *command, char *argv[], int argc)
295 int proto;
297 if (strncmp(argv[argc-1], "?", 2)==0)
299 cli_print(cli, "Specify the protocol number (default: 0).\n");
301 return CLI_OK;
304 proto = (int) str2int(argv[0]);
306 if (proto>255)
308 cli_print(cli, "The protocol number must be within range 0..255\n");
309 return CLI_OK;
312 clipkt->ip_proto = proto;
314 return CLI_OK;
321 int cmd_ip_hlen (struct cli_def *cli, const char *command, char *argv[], int argc)
323 int ihl;
325 if (strncmp(argv[argc-1], "?", 2)==0)
327 cli_print(cli, "Specify the header length in multiple of 4 bytes.\n");
329 return CLI_OK;
332 ihl = (int) str2int(argv[0]);
334 if (ihl>15)
336 cli_print(cli, "The IHL must be within range 0..15\n");
337 return CLI_OK;
340 clipkt->ip_IHL = ihl;
342 return CLI_OK;
349 int cmd_ip_len (struct cli_def *cli, const char *command, char *argv[], int argc)
351 int len;
353 if (strncmp(argv[argc-1], "?", 2)==0)
355 cli_print(cli, "Specify the total packet length (0..65535).\n");
357 return CLI_OK;
360 len = (int) str2int(argv[0]);
362 if (len>65535)
364 cli_print(cli, "The packet length must be within range 0..65535\n");
365 return CLI_OK;
368 clipkt->ip_len = len;
370 return CLI_OK;
377 int cmd_ip_id (struct cli_def *cli, const char *command, char *argv[], int argc)
380 u_int32_t id;
382 if (strncmp(argv[argc-1], "?", 2)==0)
384 cli_print(cli, "Specify the packet identification number (0..4294967295).\n");
385 return CLI_OK;
388 if (mz_strcmp(argv[0], "hex", 2)==0)
390 id = xstr2int (argv[1]);
392 else
394 id = str2int (argv[0]);
397 clipkt->ip_id = id;
399 return CLI_OK;
407 int cmd_ip_offset (struct cli_def *cli, const char *command, char *argv[], int argc)
410 int offset;
412 if (strncmp(argv[argc-1], "?", 2)==0) {
413 cli_print(cli, "Specify the fragment offset in multiples of 8 bytes.\n");
414 return CLI_OK;
417 offset = (int) str2int(argv[0]);
419 if (offset>8191) {
420 cli_print(cli, "The fragment offset must be within range 0..8191\n");
421 return CLI_OK;
424 clipkt->ip_frag_offset = offset;
426 return CLI_OK;
433 int cmd_ip_sum (struct cli_def *cli, const char *command, char *argv[], int argc)
435 int sum;
437 if (strncmp(argv[argc-1], "?", 2)==0)
439 cli_print(cli, "Specify the IP checksum in hexadecimal or use the keyword 'auto'.\r");
440 cli_print(cli, "By default, the checksum is computed automatically.\n");
441 return CLI_OK;
444 if (mz_strcmp(argv[0], "auto", 2)==0)
446 clipkt->ip_sum_false=0;
447 return CLI_OK;
450 sum = (int) xstr2int(argv[0]);
452 if (sum>0xffff)
454 cli_print(cli, "The checksum must be within range 0..ffff\n");
455 return CLI_OK;
458 clipkt->ip_sum = (u_int16_t) sum;
459 clipkt->ip_sum_false=1;
461 return CLI_OK;
470 int cmd_ip_tos (struct cli_def *cli, const char *command, char *argv[], int argc)
472 char *tmp;
474 if (strncmp(argv[argc-1], "?", 2)==0)
476 cli_print(cli, "Specify the Type of Service field: <IPP> [<ToS>] [MBZ]\n");
477 cli_print(cli, " - IP precedence (IPP) 0..7\r");
478 cli_print(cli, " - ToS: delay/throughput/reliability/cost 0..15\r");
479 cli_print(cli, " - MBZ ('must be zero' - however, not with Mausezahn...)\r");
480 cli_print(cli, "Or, alternatively, configure the whole byte in hex.\n");
481 cli_print(cli, "EXAMPLES:\n");
482 cli_print(cli, " 5 ... IPP = 5\r");
483 cli_print(cli, " 5 9 ... IPP = 5 and ToS = 9\r");
484 cli_print(cli, " 5 MBZ ... IPP = 5 and MBZ is set\r");
485 cli_print(cli, " 5 9 MBZ ... All three fields configured\r");
486 cli_print(cli, " hex a8 ... the whole byte is set to 10101000\r");
487 cli_print(cli, " 10101000 ... the whole byte in binary\n");
488 return CLI_OK;
491 if ((argc==1) && (mz_strisbinary(argv[0])==8))
493 clipkt->ip_tos = (u_int8_t) str2bin8 (argv[0]);
494 return CLI_OK;
497 if ((argc==2) && (mz_strcmp(argv[0], "hex", 2)==0))
499 tmp = argv[1];
501 if (strlen(tmp)!=2)
503 cli_print(cli, "You must specify a 2-digit hexadecimal value\n");
504 return CLI_OK;
507 if (!(isxdigit(tmp[0])) || (!(isxdigit(tmp[1]))))
509 cli_print(cli, "Non-hexadecimal value!\n");
510 return CLI_OK;
513 clipkt->ip_tos = (u_int8_t) xstr2int (tmp);
514 return CLI_OK;
517 switch (argc)
519 case 1:
520 if (mz_strcmp(argv[0], "mbz", 1)==0)
522 mops_ip_tos(clipkt, -1, -1, 1);
524 else
526 if (mops_ip_tos(clipkt, (int)str2int(argv[0]), -1, 0))
527 cli_print(cli, "Invalid IP Precedence value\n");
529 break;
531 case 2:
532 if (mz_strcmp(argv[1], "mbz", 1)==0)
534 if (mops_ip_tos(clipkt, (int)str2int(argv[0]), -1, 1))
535 cli_print(cli, "Invalid IP Precedence value\n");
537 else
539 if (mops_ip_tos(clipkt, (int)str2int(argv[0]), (int)str2int(argv[1]), 0))
540 cli_print(cli, "Invalid values\n");
542 break;
544 case 3:
545 if (mz_strcmp(argv[2], "mbz", 1)!=0)
546 cli_print(cli, "In this case the 3rd argument must be 'mbz'\n");
547 else
548 if (mops_ip_tos(clipkt, (int)str2int(argv[0]), (int)str2int(argv[1]), 1))
549 cli_print(cli, "Invalid values\n");
550 break;
553 return CLI_OK;
562 int cmd_ip_dscp (struct cli_def *cli, const char *command, char *argv[], int argc)
564 if ((argc!=1) || (strncmp(argv[argc-1], "?", 2)==0))
566 cli_print(cli, "Specify the Type of Service field using the DSCP format.\r");
567 cli_print(cli, "Multiple notations are supported.\n");
568 cli_print(cli, "Examples:\r");
569 cli_print(cli, " AF32 .... specify AF codepoint with class 3 and drop probability 2\r");
570 cli_print(cli, " EF .... specify Expedited Forwarding\r");
571 cli_print(cli, " CS7 .... specify Code Selector 7\r");
572 cli_print(cli, " 101110 .... specify the DSCP in binary\r");
573 cli_print(cli, " 56 .... specify the DSCP in decimal\r");
574 cli_print(cli, "\r");
575 return CLI_OK;
578 switch (mops_ip_dscp(clipkt, argv[0]))
580 case -1:
581 cli_print(cli, "Invalid DSCP specification (use '?')\n");
582 break;
583 case 1:
584 cli_print(cli, "Invalid AF code point (use '?')\n");
585 break;
586 case 2:
587 cli_print(cli, "Invalid Code Selector (CS0..CS7)\n");
588 break;
589 case 3:
590 cli_print(cli, "Invalid DSCP value (0..63)\n");
591 break;
594 return CLI_OK;
601 int cmd_ip_rsv (struct cli_def *cli, const char *command, char *argv[], int argc)
604 if (strncmp(argv[argc-1], "?", 2)==0)
606 cli_print(cli, "Set or unset the reserved flag.\n");
607 return CLI_OK;
610 if (argc!=1)
612 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
613 return CLI_OK;
617 if (mz_strcmp(argv[0], "set", 1)==0)
619 clipkt->ip_flags_RS = 1;
620 return CLI_OK;
623 if (mz_strcmp(argv[0], "unset", 1)==0)
625 clipkt->ip_flags_RS = 0;
626 return CLI_OK;
629 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
631 return CLI_OK;
639 int cmd_ip_df (struct cli_def *cli, const char *command, char *argv[], int argc)
642 if (strncmp(argv[argc-1], "?", 2)==0)
644 cli_print(cli, "Set or unset the don't fragment flag.\n");
646 return CLI_OK;
649 if (argc!=1)
651 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
652 return CLI_OK;
656 if (mz_strcmp(argv[0], "set", 1)==0)
658 clipkt->ip_flags_DF = 1;
659 return CLI_OK;
662 if (mz_strcmp(argv[0], "unset", 1)==0)
664 clipkt->ip_flags_DF = 0;
665 return CLI_OK;
668 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
671 return CLI_OK;
679 int cmd_ip_mf (struct cli_def *cli, const char *command, char *argv[], int argc)
682 if (strncmp(argv[argc-1], "?", 2)==0)
684 cli_print(cli, "Set or unset the more fragments flag.\n");
686 return CLI_OK;
689 if (argc!=1)
691 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
692 return CLI_OK;
696 if (mz_strcmp(argv[0], "set", 1)==0)
698 clipkt->ip_flags_MF = 1;
699 return CLI_OK;
702 if (mz_strcmp(argv[0], "unset", 1)==0)
704 clipkt->ip_flags_MF = 0;
705 return CLI_OK;
708 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
710 return CLI_OK;
715 int cmd_ip_fragsize (struct cli_def *cli, const char *command, char *argv[], int argc)
717 u_int32_t fragsize=0;
719 if (strncmp(argv[argc-1], "?", 2)==0) {
720 cli_print(cli, "Enable fragmentation by configuring a fragment size.\n");
721 cli_print(cli, "Note that the fragment size specifies the number of bytes in the IP payload\r");
722 cli_print(cli, "and NOT the assumed MTU on that link. The total packet size of each fragment\r");
723 cli_print(cli, "will be 20 bytes larger (=size of IP header if no IP options are used).\n");
724 cli_print(cli, "WARNING: The fragment size SHOULD be a multiple of 8 bytes if you expect\r");
725 cli_print(cli, " a valid result.\n");
726 cli_print(cli, "ARGUMENTS: <frag-size>\n");
727 return CLI_OK;
730 if (argc!=1) {
731 cli_print(cli, "Specify the fragment size in bytes.\n");
732 return CLI_OK;
736 fragsize = (u_int32_t) str2int(argv[0]);
738 if ((fragsize<0) || (fragsize>8000)) {
739 cli_print(cli, "The fragment size must be within range 0..8000\n");
740 return CLI_OK;
743 if (fragsize%8) {
744 cli_print(cli, "Warning: The fragment-size is not a multiple of 8.\n");
747 clipkt->ip_fragsize = fragsize;
749 return CLI_OK;
755 int cmd_ip_fragoverlap (struct cli_def *cli, const char *command, char *argv[], int argc)
757 u_int32_t overlap=0;
759 if (strncmp(argv[argc-1], "?", 2)==0) {
760 cli_print(cli, "Specify how many bytes should overlap when IP fragmentation is enabled.\n");
761 cli_print(cli, "NOTE: The number of overlap bytes is either 0 (default, no overlap) or\r");
762 cli_print(cli, " a multiple of 8 bytes but smaller than frag-size.\n");
763 cli_print(cli, "ARGUMENTS: <overlap>\n");
764 return CLI_OK;
767 if (argc!=1) {
768 cli_print(cli, "Specify how many bytes should overlap between successive IP fragments.\n");
769 return CLI_OK;
773 overlap = (u_int32_t) str2int(argv[0]);
775 if (clipkt->ip_fragsize == 0) {
776 cli_print(cli, "Please configure the fragment size first.\n");
777 return CLI_OK;
780 if ((overlap>clipkt->ip_fragsize) || (overlap%8)) {
781 cli_print(cli, "The overlap MUST be a multiple of 8 and MUST NOT exceed frag-size!\n");
782 return CLI_OK;
785 clipkt->ip_frag_overlap = overlap;
787 return CLI_OK;
794 int cmd_ip_option (struct cli_def *cli, const char *command, char *argv[], int argc)
796 int val=0;
798 if ((strncmp(argv[argc-1], "?", 2)==0) || (argc==0)) {
799 cli_print(cli, "Add or delete IP options.\n");
800 cli_print(cli, "You can only add one option after the other; if you want to configure multiple\r");
801 cli_print(cli, "options then repeat this command. The options are added to the IP header in the\r");
802 cli_print(cli, "same order as you configure them.\n");
803 cli_print(cli, "Currently the following options are supported:\n");
804 cli_print(cli, "router-alert [<value>] ... signal transit routers to examine the content of this\r");
805 cli_print(cli, " packet.\r");
806 cli_print(cli, "\n");
807 cli_print(cli, "clear ..................... remove all options from the packet\n");
808 return CLI_OK;
811 if (mz_strcmp(argv[0], "router-alert", 3)==0) {
812 switch (argc) {
813 case 1:
814 val=0;
815 break;
816 case 2:
817 val = (int) str2int(argv[1]);
818 break;
819 default:
820 cli_print(cli, "Too many arguments!\n");
821 return CLI_OK;
823 if (mops_ip_option_ra (clipkt, val)) {
824 cli_print(cli, "Value must be within 0..65535\n");
825 return CLI_OK;
828 } else if (mz_strcmp(argv[0], "loose-source-route", 3)==0) {
829 cli_print(cli, "Currently not implemented\n");
830 return CLI_OK;
831 } else if (mz_strcmp(argv[0], "record-route", 3)==0) {
832 cli_print(cli, "Currently not implemented\n");
833 return CLI_OK;
836 else if (mz_strcmp(argv[0], "clear", 2)==0) {
837 mops_ip_option_remove_all (clipkt);
840 return CLI_OK;
845 // By default we use ARP to determine the destination MAC and therefore support
846 // automatic (in)direct delivery of IP packets. Alternatively the user may turn
847 // this off and may configure an arbitrary destination MAC address
849 int cmd_ip_delivery (struct cli_def *cli, const char *command, char *argv[], int argc)
851 char str[16];
852 if (strncmp(argv[argc-1], "?", 2)==0) {
853 cli_print(cli, "Enable or disable IP auto-delivery.\n");
854 sprintf(str, "%s", (clipkt->auto_delivery_off) ? "DISABLED" : "ENABLED");
855 cli_print(cli, "Currently, IP auto-delivery is %s\n", str);
856 return CLI_OK;
859 if (argc!=1) {
860 cli_print(cli, "Argument missing. Enter either 'enable' or 'disable'\n");
861 return CLI_OK;
864 if (mz_strcmp(argv[0], "enable", 1)==0)
865 clipkt->auto_delivery_off=0;
866 else if (mz_strcmp(argv[0], "disable", 1)==0)
867 clipkt->auto_delivery_off=1;
868 else {
869 cli_print(cli, "Unknown keyword. Enter either 'enable' or 'disable'\n");
870 return CLI_OK;
873 sprintf(str, "%s", (clipkt->auto_delivery_off) ? "DISABLED" : "ENABLED");
874 cli_print(cli, "IP auto-delivery is now %s\n", str);
876 return CLI_OK;
882 int cmd_ip_end(struct cli_def *cli, const char *command, char *argv[], int argc)
884 char prompt[16];
885 sprintf(prompt, "pkt-%i",clipkt->id);
886 cli_set_configmode(cli, MZ_MODE_PACKET, prompt);
887 return CLI_OK;