aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h24
-rw-r--r--networking/inetd.c15
-rw-r--r--networking/ip.c37
-rw-r--r--networking/libiproute/ip_common.h24
-rw-r--r--networking/libiproute/ip_parse_common_args.c84
-rw-r--r--networking/libiproute/ipaddress.c51
-rw-r--r--networking/libiproute/iplink.c98
-rw-r--r--networking/libiproute/iproute.c29
-rw-r--r--networking/libiproute/iprule.c24
-rw-r--r--networking/libiproute/iptunnel.c32
-rw-r--r--networking/libiproute/utils.h4
11 files changed, 210 insertions, 212 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 2593c3ad2..3bec43233 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -289,6 +289,30 @@ void xpipe(int filedes[2]);
289off_t xlseek(int fd, off_t offset, int whence); 289off_t xlseek(int fd, off_t offset, int whence);
290off_t fdlength(int fd); 290off_t fdlength(int fd);
291 291
292/* Useful for having small structure members/global variables */
293typedef int8_t socktype_t;
294typedef int8_t family_t;
295struct BUG_too_small {
296 char BUG_socktype_t_too_small[(0
297 | SOCK_STREAM
298 | SOCK_DGRAM
299 | SOCK_RDM
300 | SOCK_SEQPACKET
301 | SOCK_RAW
302 ) <= 127 ? 1 : -1];
303 char BUG_family_t_too_small[(0
304 | AF_UNSPEC
305 | AF_INET
306 | AF_INET6
307 | AF_UNIX
308 | AF_PACKET
309 | AF_NETLINK
310 /* | AF_DECnet */
311 /* | AF_IPX */
312 ) <= 127 ? 1 : -1];
313};
314
315
292int xsocket(int domain, int type, int protocol); 316int xsocket(int domain, int type, int protocol);
293void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); 317void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
294void xlisten(int s, int backlog); 318void xlisten(int s, int backlog);
diff --git a/networking/inetd.c b/networking/inetd.c
index d76b75d5a..5d3774639 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -206,21 +206,6 @@ extern char **environ;
206# define INETD_SETPROCTITLE 206# define INETD_SETPROCTITLE
207#endif 207#endif
208 208
209typedef int8_t socktype_t;
210typedef int8_t family_t;
211struct BUG_too_small {
212 char BUG_socktype_t_too_small[(0
213 | SOCK_STREAM
214 | SOCK_DGRAM
215 | SOCK_RDM
216 | SOCK_SEQPACKET
217 | SOCK_RAW) <= 127 ? 1 : -1];
218 char BUG_family_t_too_small[(0
219 | AF_INET
220 | AF_INET6
221 | AF_UNIX) <= 127 ? 1 : -1];
222};
223
224typedef struct servtab_t { 209typedef struct servtab_t {
225 /* The most frequently referenced one: */ 210 /* The most frequently referenced one: */
226 int se_fd; /* open descriptor */ 211 int se_fd; /* open descriptor */
diff --git a/networking/ip.c b/networking/ip.c
index 3ea1b62e1..182813d4e 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -24,57 +24,50 @@
24 || ENABLE_FEATURE_IP_TUNNEL \ 24 || ENABLE_FEATURE_IP_TUNNEL \
25 || ENABLE_FEATURE_IP_RULE 25 || ENABLE_FEATURE_IP_RULE
26 26
27static int ATTRIBUTE_NORETURN ip_print_help(int ATTRIBUTE_UNUSED ac, char ATTRIBUTE_UNUSED **av) 27static int ATTRIBUTE_NORETURN ip_print_help(char ATTRIBUTE_UNUSED **argv)
28{ 28{
29 bb_show_usage(); 29 bb_show_usage();
30} 30}
31 31
32static int (*ip_func)(int argc, char **argv) = ip_print_help; 32static int ip_do(int (*ip_func)(char **argv), char **argv)
33
34static int ip_do(int argc, char **argv)
35{ 33{
36 ip_parse_common_args(&argc, &argv); 34 argv = ip_parse_common_args(argv);
37 return ip_func(argc-1, argv+1); 35 return ip_func(argv);
38} 36}
39 37
40#if ENABLE_FEATURE_IP_ADDRESS 38#if ENABLE_FEATURE_IP_ADDRESS
41int ipaddr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 39int ipaddr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
42int ipaddr_main(int argc, char **argv) 40int ipaddr_main(int argc, char **argv)
43{ 41{
44 ip_func = do_ipaddr; 42 return ip_do(do_ipaddr, argv);
45 return ip_do(argc, argv);
46} 43}
47#endif 44#endif
48#if ENABLE_FEATURE_IP_LINK 45#if ENABLE_FEATURE_IP_LINK
49int iplink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 46int iplink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
50int iplink_main(int argc, char **argv) 47int iplink_main(int argc, char **argv)
51{ 48{
52 ip_func = do_iplink; 49 return ip_do(do_iplink, argv);
53 return ip_do(argc, argv);
54} 50}
55#endif 51#endif
56#if ENABLE_FEATURE_IP_ROUTE 52#if ENABLE_FEATURE_IP_ROUTE
57int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 53int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
58int iproute_main(int argc, char **argv) 54int iproute_main(int argc, char **argv)
59{ 55{
60 ip_func = do_iproute; 56 return ip_do(do_iproute, argv);
61 return ip_do(argc, argv);
62} 57}
63#endif 58#endif
64#if ENABLE_FEATURE_IP_RULE 59#if ENABLE_FEATURE_IP_RULE
65int iprule_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 60int iprule_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
66int iprule_main(int argc, char **argv) 61int iprule_main(int argc, char **argv)
67{ 62{
68 ip_func = do_iprule; 63 return ip_do(do_iprule, argv);
69 return ip_do(argc, argv);
70} 64}
71#endif 65#endif
72#if ENABLE_FEATURE_IP_TUNNEL 66#if ENABLE_FEATURE_IP_TUNNEL
73int iptunnel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 67int iptunnel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
74int iptunnel_main(int argc, char **argv) 68int iptunnel_main(int argc, char **argv)
75{ 69{
76 ip_func = do_iptunnel; 70 return ip_do(do_iptunnel, argv);
77 return ip_do(argc, argv);
78} 71}
79#endif 72#endif
80 73
@@ -97,12 +90,12 @@ int ip_main(int argc, char **argv)
97 USE_FEATURE_IP_RULE(IP_rule,) 90 USE_FEATURE_IP_RULE(IP_rule,)
98 IP_none 91 IP_none
99 }; 92 };
93 int (*ip_func)(char **argv) = ip_print_help;
100 94
101 ip_parse_common_args(&argc, &argv); 95 argv = ip_parse_common_args(argv + 1);
102 if (argc > 1) { 96 if (*argv) {
103 int key = index_in_substrings(keywords, argv[1]); 97 int key = index_in_substrings(keywords, *argv);
104 argc -= 2; 98 argv++;
105 argv += 2;
106#if ENABLE_FEATURE_IP_ADDRESS 99#if ENABLE_FEATURE_IP_ADDRESS
107 if (key == IP_addr) 100 if (key == IP_addr)
108 ip_func = do_ipaddr; 101 ip_func = do_ipaddr;
@@ -124,7 +117,7 @@ int ip_main(int argc, char **argv)
124 ip_func = do_iprule; 117 ip_func = do_iprule;
125#endif 118#endif
126 } 119 }
127 return ip_func(argc, argv); 120 return ip_func(argv);
128} 121}
129 122
130#endif /* any of ENABLE_FEATURE_IP_xxx is 1 */ 123#endif /* any of ENABLE_FEATURE_IP_xxx is 1 */
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h
index 97101079f..c04735608 100644
--- a/networking/libiproute/ip_common.h
+++ b/networking/libiproute/ip_common.h
@@ -13,20 +13,20 @@
13#include <linux/if_link.h> 13#include <linux/if_link.h>
14#endif 14#endif
15 15
16extern void ip_parse_common_args(int *argcp, char ***argvp); 16extern char **ip_parse_common_args(char **argv);
17extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); 17extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
18extern int ipaddr_list_or_flush(int argc, char **argv, int flush); 18extern int ipaddr_list_or_flush(char **argv, int flush);
19extern int iproute_monitor(int argc, char **argv); 19extern int iproute_monitor(char **argv);
20extern void iplink_usage(void) ATTRIBUTE_NORETURN; 20extern void iplink_usage(void) ATTRIBUTE_NORETURN;
21extern void ipneigh_reset_filter(void); 21extern void ipneigh_reset_filter(void);
22 22
23extern int do_ipaddr(int argc, char **argv); 23extern int do_ipaddr(char **argv);
24extern int do_iproute(int argc, char **argv); 24extern int do_iproute(char **argv);
25extern int do_iprule(int argc, char **argv); 25extern int do_iprule(char **argv);
26extern int do_ipneigh(int argc, char **argv); 26extern int do_ipneigh(char **argv);
27extern int do_iptunnel(int argc, char **argv); 27extern int do_iptunnel(char **argv);
28extern int do_iplink(int argc, char **argv); 28extern int do_iplink(char **argv);
29extern int do_ipmonitor(int argc, char **argv); 29extern int do_ipmonitor(char **argv);
30extern int do_multiaddr(int argc, char **argv); 30extern int do_multiaddr(char **argv);
31extern int do_multiroute(int argc, char **argv); 31extern int do_multiroute(char **argv);
32#endif /* ip_common.h */ 32#endif /* ip_common.h */
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index ff333993f..294bde540 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -18,71 +18,67 @@
18#include "ip_common.h" /* #include "libbb.h" is inside */ 18#include "ip_common.h" /* #include "libbb.h" is inside */
19#include "utils.h" 19#include "utils.h"
20 20
21int preferred_family = AF_UNSPEC; 21family_t preferred_family = AF_UNSPEC;
22smallint oneline; 22smallint oneline;
23char _SL_; 23char _SL_;
24 24
25void ip_parse_common_args(int *argcp, char ***argvp) 25char **ip_parse_common_args(char **argv)
26{ 26{
27 int argc = *argcp;
28 char **argv = *argvp;
29 static const char ip_common_commands[] ALIGN1 = 27 static const char ip_common_commands[] ALIGN1 =
30 "-family\0""inet\0""inet6\0""link\0" 28 "oneline" "\0"
31 "-4\0""-6\0""-0\0""-oneline\0"; 29 "family" "\0"
30 "4" "\0"
31 "6" "\0"
32 "0" "\0"
33 ;
32 enum { 34 enum {
33 ARG_family = 1, 35 ARG_oneline,
34 ARG_inet, 36 ARG_family,
35 ARG_inet6,
36 ARG_link,
37 ARG_IPv4, 37 ARG_IPv4,
38 ARG_IPv6, 38 ARG_IPv6,
39 ARG_packet, 39 ARG_packet,
40 ARG_oneline
41 }; 40 };
42 smalluint arg; 41 static const family_t af_numbers[] = { AF_INET, AF_INET6, AF_PACKET };
42 int arg;
43 43
44 while (argc > 1) { 44 while (*argv) {
45 char *opt = argv[1]; 45 char *opt = *argv;
46 46
47 if (strcmp(opt,"--") == 0) {
48 argc--;
49 argv++;
50 break;
51 }
52 if (opt[0] != '-') 47 if (opt[0] != '-')
53 break; 48 break;
54 if (opt[1] == '-') 49 opt++;
50 if (opt[0] == '-') {
55 opt++; 51 opt++;
56 arg = index_in_strings(ip_common_commands, opt) + 1; 52 if (!opt[0]) { /* "--" */
53 argv++;
54 break;
55 }
56 }
57 arg = index_in_strings(ip_common_commands, opt);
58 if (arg < 0)
59 bb_show_usage();
60 if (arg == ARG_oneline) {
61 oneline = 1;
62 argv++;
63 continue;
64 }
57 if (arg == ARG_family) { 65 if (arg == ARG_family) {
58 argc--; 66 static const char families[] ALIGN1 =
67 "inet" "\0" "inet6" "\0" "link" "\0";
59 argv++; 68 argv++;
60 if (!argv[1]) 69 if (!*argv)
61 bb_show_usage(); 70 bb_show_usage();
62 arg = index_in_strings(ip_common_commands, argv[1]) + 1; 71 arg = index_in_strings(families, *argv);
63 if (arg == ARG_inet) 72 if (arg < 0)
64 preferred_family = AF_INET; 73 invarg(*argv, "protocol family");
65 else if (arg == ARG_inet6) 74 /* now arg == 0, 1 or 2 */
66 preferred_family = AF_INET6;
67 else if (arg == ARG_link)
68 preferred_family = AF_PACKET;
69 else
70 invarg(argv[1], "protocol family");
71 } else if (arg == ARG_IPv4) {
72 preferred_family = AF_INET;
73 } else if (arg == ARG_IPv6) {
74 preferred_family = AF_INET6;
75 } else if (arg == ARG_packet) {
76 preferred_family = AF_PACKET;
77 } else if (arg == ARG_oneline) {
78 ++oneline;
79 } else { 75 } else {
80 bb_show_usage(); 76 arg -= ARG_IPv4;
77 /* now arg == 0, 1 or 2 */
81 } 78 }
82 argc--; 79 preferred_family = af_numbers[arg];
83 argv++; 80 argv++;
84 } 81 }
85 _SL_ = oneline ? '\\' : '\n'; 82 _SL_ = oneline ? '\\' : '\n';
86 *argcp = argc; 83 return argv;
87 *argvp = argv;
88} 84}
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index b25981900..044538aca 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -410,7 +410,7 @@ static void ipaddr_reset_filter(int _oneline)
410} 410}
411 411
412/* Return value becomes exitcode. It's okay to not return at all */ 412/* Return value becomes exitcode. It's okay to not return at all */
413int ipaddr_list_or_flush(int argc, char **argv, int flush) 413int ipaddr_list_or_flush(char **argv, int flush)
414{ 414{
415 static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0"; 415 static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";
416 416
@@ -428,7 +428,7 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
428 filter.family = preferred_family; 428 filter.family = preferred_family;
429 429
430 if (flush) { 430 if (flush) {
431 if (argc <= 0) { 431 if (!*argv) {
432 bb_error_msg_and_die(bb_msg_requires_arg, "flush"); 432 bb_error_msg_and_die(bb_msg_requires_arg, "flush");
433 } 433 }
434 if (filter.family == AF_PACKET) { 434 if (filter.family == AF_PACKET) {
@@ -436,7 +436,7 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
436 } 436 }
437 } 437 }
438 438
439 while (argc > 0) { 439 while (*argv) {
440 const int option_num = index_in_strings(option, *argv); 440 const int option_num = index_in_strings(option, *argv);
441 switch (option_num) { 441 switch (option_num) {
442 case 0: /* to */ 442 case 0: /* to */
@@ -477,7 +477,6 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
477 filter_dev = *argv; 477 filter_dev = *argv;
478 } 478 }
479 argv++; 479 argv++;
480 argc--;
481 } 480 }
482 481
483 xrtnl_open(&rth); 482 xrtnl_open(&rth);
@@ -517,26 +516,26 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
517 516
518 if (filter.family && filter.family != AF_PACKET) { 517 if (filter.family && filter.family != AF_PACKET) {
519 struct nlmsg_list **lp; 518 struct nlmsg_list **lp;
520 lp=&linfo; 519 lp = &linfo;
521 520
522 if (filter.oneline) 521 if (filter.oneline)
523 no_link = 1; 522 no_link = 1;
524 523
525 while ((l=*lp)!=NULL) { 524 while ((l = *lp) != NULL) {
526 int ok = 0; 525 int ok = 0;
527 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 526 struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
528 struct nlmsg_list *a; 527 struct nlmsg_list *a;
529 528
530 for (a=ainfo; a; a=a->next) { 529 for (a = ainfo; a; a = a->next) {
531 struct nlmsghdr *n = &a->h; 530 struct nlmsghdr *n = &a->h;
532 struct ifaddrmsg *ifa = NLMSG_DATA(n); 531 struct ifaddrmsg *ifa = NLMSG_DATA(n);
533 532
534 if (ifa->ifa_index != ifi->ifi_index || 533 if (ifa->ifa_index != ifi->ifi_index ||
535 (filter.family && filter.family != ifa->ifa_family)) 534 (filter.family && filter.family != ifa->ifa_family))
536 continue; 535 continue;
537 if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 536 if ((filter.scope ^ ifa->ifa_scope) & filter.scopemask)
538 continue; 537 continue;
539 if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 538 if ((filter.flags ^ ifa->ifa_flags) & filter.flagmask)
540 continue; 539 continue;
541 if (filter.pfx.family || filter.label) { 540 if (filter.pfx.family || filter.label) {
542 struct rtattr *tb[IFA_MAX+1]; 541 struct rtattr *tb[IFA_MAX+1];
@@ -581,7 +580,6 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
581 if (filter.family != AF_PACKET) 580 if (filter.family != AF_PACKET)
582 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 581 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
583 } 582 }
584 fflush(stdout); /* why? */
585 } 583 }
586 584
587 return 0; 585 return 0;
@@ -597,7 +595,7 @@ static int default_scope(inet_prefix *lcl)
597} 595}
598 596
599/* Return value becomes exitcode. It's okay to not return at all */ 597/* Return value becomes exitcode. It's okay to not return at all */
600static int ipaddr_modify(int cmd, int argc, char **argv) 598static int ipaddr_modify(int cmd, char **argv)
601{ 599{
602 static const char option[] ALIGN1 = 600 static const char option[] ALIGN1 =
603 "peer\0""remote\0""broadcast\0""brd\0" 601 "peer\0""remote\0""broadcast\0""brd\0"
@@ -625,7 +623,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
625 req.n.nlmsg_type = cmd; 623 req.n.nlmsg_type = cmd;
626 req.ifa.ifa_family = preferred_family; 624 req.ifa.ifa_family = preferred_family;
627 625
628 while (argc > 0) { 626 while (*argv) {
629 const int option_num = index_in_strings(option, *argv); 627 const int option_num = index_in_strings(option, *argv);
630 switch (option_num) { 628 switch (option_num) {
631 case 0: /* peer */ 629 case 0: /* peer */
@@ -653,8 +651,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
653 } 651 }
654 if (LONE_CHAR(*argv, '+')) { 652 if (LONE_CHAR(*argv, '+')) {
655 brd_len = -1; 653 brd_len = -1;
656 } 654 } else if (LONE_DASH(*argv)) {
657 else if (LONE_DASH(*argv)) {
658 brd_len = -2; 655 brd_len = -2;
659 } else { 656 } else {
660 get_addr(&addr, *argv, req.ifa.ifa_family); 657 get_addr(&addr, *argv, req.ifa.ifa_family);
@@ -713,12 +710,11 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
713 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); 710 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
714 local_len = lcl.bytelen; 711 local_len = lcl.bytelen;
715 } 712 }
716 argc--;
717 argv++; 713 argv++;
718 } 714 }
719 715
720 if (d == NULL) { 716 if (d == NULL) {
721 bb_error_msg(bb_msg_requires_arg,"\"dev\""); 717 bb_error_msg(bb_msg_requires_arg, "\"dev\"");
722 return -1; 718 return -1;
723 } 719 }
724 if (l && strncmp(d, l, strlen(d)) != 0) { 720 if (l && strncmp(d, l, strlen(d)) != 0) {
@@ -766,7 +762,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
766} 762}
767 763
768/* Return value becomes exitcode. It's okay to not return at all */ 764/* Return value becomes exitcode. It's okay to not return at all */
769int do_ipaddr(int argc, char **argv) 765int do_ipaddr(char **argv)
770{ 766{
771 static const char commands[] ALIGN1 = 767 static const char commands[] ALIGN1 =
772 "add\0""delete\0""list\0""show\0""lst\0""flush\0"; 768 "add\0""delete\0""list\0""show\0""lst\0""flush\0";
@@ -775,17 +771,16 @@ int do_ipaddr(int argc, char **argv)
775 771
776 if (*argv) { 772 if (*argv) {
777 command_num = index_in_substrings(commands, *argv); 773 command_num = index_in_substrings(commands, *argv);
774 if (command_num < 0 || command_num > 5)
775 bb_error_msg_and_die("unknown command %s", *argv);
776 argv++;
778 } 777 }
779 if (command_num < 0 || command_num > 5)
780 bb_error_msg_and_die("unknown command %s", *argv);
781 --argc;
782 ++argv;
783 if (command_num == 0) /* add */ 778 if (command_num == 0) /* add */
784 return ipaddr_modify(RTM_NEWADDR, argc, argv); 779 return ipaddr_modify(RTM_NEWADDR, argv);
785 else if (command_num == 1) /* delete */ 780 if (command_num == 1) /* delete */
786 return ipaddr_modify(RTM_DELADDR, argc, argv); 781 return ipaddr_modify(RTM_DELADDR, argv);
787 else if (command_num == 5) /* flush */ 782 if (command_num == 5) /* flush */
788 return ipaddr_list_or_flush(argc, argv, 1); 783 return ipaddr_list_or_flush(argv, 1);
789 else /* 2 == list, 3 == show, 4 == lst */ 784 /* 2 == list, 3 == show, 4 == lst */
790 return ipaddr_list_or_flush(argc, argv, 0); 785 return ipaddr_list_or_flush(argv, 0);
791} 786}
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index e1c9c6043..494b223bf 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -21,12 +21,6 @@
21/* taken from linux/sockios.h */ 21/* taken from linux/sockios.h */
22#define SIOCSIFNAME 0x8923 /* set interface name */ 22#define SIOCSIFNAME 0x8923 /* set interface name */
23 23
24static void on_off(const char *msg) ATTRIBUTE_NORETURN;
25static void on_off(const char *msg)
26{
27 bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg);
28}
29
30/* Exits on error */ 24/* Exits on error */
31static int get_ctl_fd(void) 25static int get_ctl_fd(void)
32{ 26{
@@ -158,8 +152,14 @@ static void set_address(struct ifreq *ifr, int brd)
158} 152}
159 153
160 154
155static void die_must_be_on_off(const char *msg) ATTRIBUTE_NORETURN;
156static void die_must_be_on_off(const char *msg)
157{
158 bb_error_msg_and_die("argument of \"%s\" must be \"on\" or \"off\"", msg);
159}
160
161/* Return value becomes exitcode. It's okay to not return at all */ 161/* Return value becomes exitcode. It's okay to not return at all */
162static int do_set(int argc, char **argv) 162static int do_set(char **argv)
163{ 163{
164 char *dev = NULL; 164 char *dev = NULL;
165 uint32_t mask = 0; 165 uint32_t mask = 0;
@@ -172,53 +172,63 @@ static int do_set(int argc, char **argv)
172 char *newname = NULL; 172 char *newname = NULL;
173 int htype, halen; 173 int htype, halen;
174 static const char keywords[] ALIGN1 = 174 static const char keywords[] ALIGN1 =
175 "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0" 175 "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0";
176 "on\0""off\0"; 176 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
177 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp, 177 ARG_addr, ARG_dev };
178 ARG_addr, ARG_dev, PARM_on, PARM_off }; 178 static const char str_on_off[] ALIGN1 = "on\0""off\0";
179 enum { PARM_on = 0, PARM_off };
179 smalluint key; 180 smalluint key;
180 181
181 while (argc > 0) { 182 while (*argv) {
182 key = index_in_strings(keywords, *argv) + 1; 183 key = index_in_strings(keywords, *argv);
183 if (key == ARG_up) { 184 if (key == ARG_up) {
184 mask |= IFF_UP; 185 mask |= IFF_UP;
185 flags |= IFF_UP; 186 flags |= IFF_UP;
186 } else if (key == ARG_down) { 187 }
188 if (key == ARG_down) {
187 mask |= IFF_UP; 189 mask |= IFF_UP;
188 flags &= ~IFF_UP; 190 flags &= ~IFF_UP;
189 } else if (key == ARG_name) { 191 }
192 if (key == ARG_name) {
190 NEXT_ARG(); 193 NEXT_ARG();
191 newname = *argv; 194 newname = *argv;
192 } else if (key == ARG_mtu) { 195 }
196 if (key == ARG_mtu) {
193 NEXT_ARG(); 197 NEXT_ARG();
194 if (mtu != -1) 198 if (mtu != -1)
195 duparg("mtu", *argv); 199 duparg("mtu", *argv);
196 if (get_integer(&mtu, *argv, 0)) 200 if (get_integer(&mtu, *argv, 0))
197 invarg(*argv, "mtu"); 201 invarg(*argv, "mtu");
198 } else if (key == ARG_multicast) { 202 }
203 if (key == ARG_multicast) {
204 int param;
199 NEXT_ARG(); 205 NEXT_ARG();
200 mask |= IFF_MULTICAST; 206 mask |= IFF_MULTICAST;
201 key = index_in_strings(keywords, *argv) + 1; 207 param = index_in_strings(str_on_off, *argv);
202 if (key == PARM_on) { 208 if (param < 0)
209 die_must_be_on_off("multicast");
210 if (param == PARM_on)
203 flags |= IFF_MULTICAST; 211 flags |= IFF_MULTICAST;
204 } else if (key == PARM_off) { 212 else
205 flags &= ~IFF_MULTICAST; 213 flags &= ~IFF_MULTICAST;
206 } else 214 }
207 on_off("multicast"); 215 if (key == ARG_arp) {
208 } else if (key == ARG_arp) { 216 int param;
209 NEXT_ARG(); 217 NEXT_ARG();
210 mask |= IFF_NOARP; 218 mask |= IFF_NOARP;
211 key = index_in_strings(keywords, *argv) + 1; 219 param = index_in_strings(str_on_off, *argv);
212 if (key == PARM_on) { 220 if (param < 0)
221 die_must_be_on_off("arp");
222 if (param == PARM_on)
213 flags &= ~IFF_NOARP; 223 flags &= ~IFF_NOARP;
214 } else if (key == PARM_off) { 224 else
215 flags |= IFF_NOARP; 225 flags |= IFF_NOARP;
216 } else 226 }
217 on_off("arp"); 227 if (key == ARG_addr) {
218 } else if (key == ARG_addr) {
219 NEXT_ARG(); 228 NEXT_ARG();
220 newaddr = *argv; 229 newaddr = *argv;
221 } else { 230 }
231 if (key >= ARG_dev) {
222 if (key == ARG_dev) { 232 if (key == ARG_dev) {
223 NEXT_ARG(); 233 NEXT_ARG();
224 } 234 }
@@ -226,7 +236,7 @@ static int do_set(int argc, char **argv)
226 duparg2("dev", *argv); 236 duparg2("dev", *argv);
227 dev = *argv; 237 dev = *argv;
228 } 238 }
229 argc--; argv++; 239 argv++;
230 } 240 }
231 241
232 if (!dev) { 242 if (!dev) {
@@ -266,26 +276,26 @@ static int do_set(int argc, char **argv)
266 return 0; 276 return 0;
267} 277}
268 278
269static int ipaddr_list_link(int argc, char **argv) 279static int ipaddr_list_link(char **argv)
270{ 280{
271 preferred_family = AF_PACKET; 281 preferred_family = AF_PACKET;
272 return ipaddr_list_or_flush(argc, argv, 0); 282 return ipaddr_list_or_flush(argv, 0);
273} 283}
274 284
275/* Return value becomes exitcode. It's okay to not return at all */ 285/* Return value becomes exitcode. It's okay to not return at all */
276int do_iplink(int argc, char **argv) 286int do_iplink(char **argv)
277{ 287{
278 static const char keywords[] ALIGN1 = 288 static const char keywords[] ALIGN1 =
279 "set\0""show\0""lst\0""list\0"; 289 "set\0""show\0""lst\0""list\0";
280 smalluint key; 290 int key;
281 if (argc <= 0) 291 if (!*argv)
282 return ipaddr_list_link(0, NULL); 292 return ipaddr_list_link(argv);
283 key = index_in_substrings(keywords, *argv) + 1; 293 key = index_in_substrings(keywords, *argv);
284 if (key == 0) 294 if (key < 0)
285 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 295 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
286 argc--; argv++; 296 argv++;
287 if (key == 1) /* set */ 297 if (key == 0) /* set */
288 return do_set(argc, argv); 298 return do_set(argv);
289 else /* show, lst, list */ 299 /* show, lst, list */
290 return ipaddr_list_link(argc, argv); 300 return ipaddr_list_link(argv);
291} 301}
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 91811117c..ec0952668 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -292,7 +292,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
292} 292}
293 293
294/* Return value becomes exitcode. It's okay to not return at all */ 294/* Return value becomes exitcode. It's okay to not return at all */
295static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 295static int iproute_modify(int cmd, unsigned flags, char **argv)
296{ 296{
297 static const char keywords[] ALIGN1 = 297 static const char keywords[] ALIGN1 =
298 "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0") 298 "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0")
@@ -344,7 +344,7 @@ USE_FEATURE_IP_RULE(ARG_table,)
344 mxrta->rta_type = RTA_METRICS; 344 mxrta->rta_type = RTA_METRICS;
345 mxrta->rta_len = RTA_LENGTH(0); 345 mxrta->rta_len = RTA_LENGTH(0);
346 346
347 while (argc > 0) { 347 while (*argv) {
348 arg = index_in_substrings(keywords, *argv); 348 arg = index_in_substrings(keywords, *argv);
349 if (arg == ARG_src) { 349 if (arg == ARG_src) {
350 inet_prefix addr; 350 inet_prefix addr;
@@ -417,7 +417,7 @@ USE_FEATURE_IP_RULE(ARG_table,)
417 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); 417 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
418 } 418 }
419 } 419 }
420 argc--; argv++; 420 argv++;
421 } 421 }
422 422
423 xrtnl_open(&rth); 423 xrtnl_open(&rth);
@@ -511,7 +511,7 @@ static void iproute_reset_filter(void)
511} 511}
512 512
513/* Return value becomes exitcode. It's okay to not return at all */ 513/* Return value becomes exitcode. It's okay to not return at all */
514static int iproute_list_or_flush(int argc, char **argv, int flush) 514static int iproute_list_or_flush(char **argv, int flush)
515{ 515{
516 int do_ipv6 = preferred_family; 516 int do_ipv6 = preferred_family;
517 struct rtnl_handle rth; 517 struct rtnl_handle rth;
@@ -534,10 +534,10 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
534 iproute_reset_filter(); 534 iproute_reset_filter();
535 filter.tb = RT_TABLE_MAIN; 535 filter.tb = RT_TABLE_MAIN;
536 536
537 if (flush && argc <= 0) 537 if (flush && !*argv)
538 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\""); 538 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
539 539
540 while (argc > 0) { 540 while (*argv) {
541 arg = index_in_substrings(keywords, *argv); 541 arg = index_in_substrings(keywords, *argv);
542 if (arg == ARG_proto) { 542 if (arg == ARG_proto) {
543 uint32_t prot = 0; 543 uint32_t prot = 0;
@@ -602,7 +602,6 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
602 filter.rdst = filter.mdst; 602 filter.rdst = filter.mdst;
603 } 603 }
604 } 604 }
605 argc--;
606 argv++; 605 argv++;
607 } 606 }
608 607
@@ -667,7 +666,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
667 666
668 667
669/* Return value becomes exitcode. It's okay to not return at all */ 668/* Return value becomes exitcode. It's okay to not return at all */
670static int iproute_get(int argc, char **argv) 669static int iproute_get(char **argv)
671{ 670{
672 struct rtnl_handle rth; 671 struct rtnl_handle rth;
673 struct { 672 struct {
@@ -698,7 +697,7 @@ static int iproute_get(int argc, char **argv)
698 req.r.rtm_dst_len = 0; 697 req.r.rtm_dst_len = 0;
699 req.r.rtm_tos = 0; 698 req.r.rtm_tos = 0;
700 699
701 while (argc > 0) { 700 while (*argv) {
702 switch (index_in_strings(options, *argv)) { 701 switch (index_in_strings(options, *argv)) {
703 case 0: /* from */ 702 case 0: /* from */
704 { 703 {
@@ -744,7 +743,7 @@ static int iproute_get(int argc, char **argv)
744 } 743 }
745 req.r.rtm_dst_len = addr.bitlen; 744 req.r.rtm_dst_len = addr.bitlen;
746 } 745 }
747 argc--; argv++; 746 argv++;
748 } 747 }
749 } 748 }
750 749
@@ -822,7 +821,7 @@ static int iproute_get(int argc, char **argv)
822} 821}
823 822
824/* Return value becomes exitcode. It's okay to not return at all */ 823/* Return value becomes exitcode. It's okay to not return at all */
825int do_iproute(int argc, char **argv) 824int do_iproute(char **argv)
826{ 825{
827 static const char ip_route_commands[] ALIGN1 = 826 static const char ip_route_commands[] ALIGN1 =
828 /*0-3*/ "add\0""append\0""change\0""chg\0" 827 /*0-3*/ "add\0""append\0""change\0""chg\0"
@@ -852,10 +851,10 @@ int do_iproute(int argc, char **argv)
852 cmd = RTM_DELROUTE; 851 cmd = RTM_DELROUTE;
853 break; 852 break;
854 case 5: /* get */ 853 case 5: /* get */
855 return iproute_get(argc-1, argv+1); 854 return iproute_get(argv+1);
856 case 6: /* list */ 855 case 6: /* list */
857 case 7: /* show */ 856 case 7: /* show */
858 return iproute_list_or_flush(argc-1, argv+1, 0); 857 return iproute_list_or_flush(argv+1, 0);
859 case 8: /* prepend */ 858 case 8: /* prepend */
860 flags = NLM_F_CREATE; 859 flags = NLM_F_CREATE;
861 break; 860 break;
@@ -866,10 +865,10 @@ int do_iproute(int argc, char **argv)
866 flags = NLM_F_EXCL; 865 flags = NLM_F_EXCL;
867 break; 866 break;
868 case 11: /* flush */ 867 case 11: /* flush */
869 return iproute_list_or_flush(argc-1, argv+1, 1); 868 return iproute_list_or_flush(argv+1, 1);
870 default: 869 default:
871 bb_error_msg_and_die("unknown command %s", *argv); 870 bb_error_msg_and_die("unknown command %s", *argv);
872 } 871 }
873 872
874 return iproute_modify(cmd, flags, argc-1, argv+1); 873 return iproute_modify(cmd, flags, argv+1);
875} 874}
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 3c276e666..6442992b4 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -161,7 +161,7 @@ static int print_rule(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
161} 161}
162 162
163/* Return value becomes exitcode. It's okay to not return at all */ 163/* Return value becomes exitcode. It's okay to not return at all */
164static int iprule_list(int argc, char **argv) 164static int iprule_list(char **argv)
165{ 165{
166 struct rtnl_handle rth; 166 struct rtnl_handle rth;
167 int af = preferred_family; 167 int af = preferred_family;
@@ -169,9 +169,9 @@ static int iprule_list(int argc, char **argv)
169 if (af == AF_UNSPEC) 169 if (af == AF_UNSPEC)
170 af = AF_INET; 170 af = AF_INET;
171 171
172 if (argc > 0) { 172 if (*argv) {
173 //bb_error_msg("\"rule show\" needs no arguments"); 173 //bb_error_msg("\"rule show\" needs no arguments");
174 bb_warn_ignoring_args(argc); 174 bb_warn_ignoring_args(1);
175 return -1; 175 return -1;
176 } 176 }
177 177
@@ -184,7 +184,7 @@ static int iprule_list(int argc, char **argv)
184} 184}
185 185
186/* Return value becomes exitcode. It's okay to not return at all */ 186/* Return value becomes exitcode. It's okay to not return at all */
187static int iprule_modify(int cmd, int argc, char **argv) 187static int iprule_modify(int cmd, char **argv)
188{ 188{
189 static const char keywords[] ALIGN1 = 189 static const char keywords[] ALIGN1 =
190 "from\0""to\0""preference\0""order\0""priority\0" 190 "from\0""to\0""preference\0""order\0""priority\0"
@@ -220,7 +220,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
220 req.r.rtm_type = RTN_UNICAST; 220 req.r.rtm_type = RTN_UNICAST;
221 } 221 }
222 222
223 while (argc > 0) { 223 while (*argv) {
224 key = index_in_substrings(keywords, *argv) + 1; 224 key = index_in_substrings(keywords, *argv) + 1;
225 if (key == 0) /* no match found in keywords array, bail out. */ 225 if (key == 0) /* no match found in keywords array, bail out. */
226 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 226 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
@@ -291,7 +291,6 @@ static int iprule_modify(int cmd, int argc, char **argv)
291 invarg(*argv, "type"); 291 invarg(*argv, "type");
292 req.r.rtm_type = type; 292 req.r.rtm_type = type;
293 } 293 }
294 argc--;
295 argv++; 294 argv++;
296 } 295 }
297 296
@@ -310,17 +309,16 @@ static int iprule_modify(int cmd, int argc, char **argv)
310} 309}
311 310
312/* Return value becomes exitcode. It's okay to not return at all */ 311/* Return value becomes exitcode. It's okay to not return at all */
313int do_iprule(int argc, char **argv) 312int do_iprule(char **argv)
314{ 313{
315 static const char ip_rule_commands[] ALIGN1 = 314 static const char ip_rule_commands[] ALIGN1 =
316 "add\0""delete\0""list\0""show\0"; 315 "add\0""delete\0""list\0""show\0";
317 int cmd = 2; /* list */ 316 int cmd = 2; /* list */
318 317
319 if (argc < 1) 318 if (!*argv)
320 return iprule_list(0, NULL); 319 return iprule_list(argv);
321 if (*argv)
322 cmd = index_in_substrings(ip_rule_commands, *argv);
323 320
321 cmd = index_in_substrings(ip_rule_commands, *argv);
324 switch (cmd) { 322 switch (cmd) {
325 case 0: /* add */ 323 case 0: /* add */
326 cmd = RTM_NEWRULE; 324 cmd = RTM_NEWRULE;
@@ -330,10 +328,10 @@ int do_iprule(int argc, char **argv)
330 break; 328 break;
331 case 2: /* list */ 329 case 2: /* list */
332 case 3: /* show */ 330 case 3: /* show */
333 return iprule_list(argc-1, argv+1); 331 return iprule_list(argv+1);
334 break; 332 break;
335 default: 333 default:
336 bb_error_msg_and_die("unknown command %s", *argv); 334 bb_error_msg_and_die("unknown command %s", *argv);
337 } 335 }
338 return iprule_modify(cmd, argc-1, argv+1); 336 return iprule_modify(cmd, argv+1);
339} 337}
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index a45e64d60..ad909ff21 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -126,7 +126,7 @@ static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
126} 126}
127 127
128/* Dies on error */ 128/* Dies on error */
129static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 129static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
130{ 130{
131 static const char keywords[] ALIGN1 = 131 static const char keywords[] ALIGN1 =
132 "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0" 132 "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0"
@@ -157,7 +157,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
157#endif 157#endif
158 p->iph.frag_off = htons(IP_DF); 158 p->iph.frag_off = htons(IP_DF);
159 159
160 while (argc > 0) { 160 while (*argv) {
161 key = index_in_strings(keywords, *argv); 161 key = index_in_strings(keywords, *argv);
162 if (key == ARG_mode) { 162 if (key == ARG_mode) {
163 NEXT_ARG(); 163 NEXT_ARG();
@@ -289,7 +289,6 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
289 } 289 }
290 } 290 }
291 count++; 291 count++;
292 argc--;
293 argv++; 292 argv++;
294 } 293 }
295 294
@@ -327,11 +326,11 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
327 326
328 327
329/* Return value becomes exitcode. It's okay to not return at all */ 328/* Return value becomes exitcode. It's okay to not return at all */
330static int do_add(int cmd, int argc, char **argv) 329static int do_add(int cmd, char **argv)
331{ 330{
332 struct ip_tunnel_parm p; 331 struct ip_tunnel_parm p;
333 332
334 parse_args(argc, argv, cmd, &p); 333 parse_args(argv, cmd, &p);
335 334
336 if (p.iph.ttl && p.iph.frag_off == 0) { 335 if (p.iph.ttl && p.iph.frag_off == 0) {
337 bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible"); 336 bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible");
@@ -350,11 +349,11 @@ static int do_add(int cmd, int argc, char **argv)
350} 349}
351 350
352/* Return value becomes exitcode. It's okay to not return at all */ 351/* Return value becomes exitcode. It's okay to not return at all */
353static int do_del(int argc, char **argv) 352static int do_del(char **argv)
354{ 353{
355 struct ip_tunnel_parm p; 354 struct ip_tunnel_parm p;
356 355
357 parse_args(argc, argv, SIOCDELTUNNEL, &p); 356 parse_args(argv, SIOCDELTUNNEL, &p);
358 357
359 switch (p.iph.protocol) { 358 switch (p.iph.protocol) {
360 case IPPROTO_IPIP: 359 case IPPROTO_IPIP:
@@ -487,12 +486,12 @@ static void do_tunnels_list(struct ip_tunnel_parm *p)
487} 486}
488 487
489/* Return value becomes exitcode. It's okay to not return at all */ 488/* Return value becomes exitcode. It's okay to not return at all */
490static int do_show(int argc, char **argv) 489static int do_show(char **argv)
491{ 490{
492 int err; 491 int err;
493 struct ip_tunnel_parm p; 492 struct ip_tunnel_parm p;
494 493
495 parse_args(argc, argv, SIOCGETTUNNEL, &p); 494 parse_args(argv, SIOCGETTUNNEL, &p);
496 495
497 switch (p.iph.protocol) { 496 switch (p.iph.protocol) {
498 case IPPROTO_IPIP: 497 case IPPROTO_IPIP:
@@ -517,25 +516,24 @@ static int do_show(int argc, char **argv)
517} 516}
518 517
519/* Return value becomes exitcode. It's okay to not return at all */ 518/* Return value becomes exitcode. It's okay to not return at all */
520int do_iptunnel(int argc, char **argv) 519int do_iptunnel(char **argv)
521{ 520{
522 static const char keywords[] ALIGN1 = 521 static const char keywords[] ALIGN1 =
523 "add\0""change\0""delete\0""show\0""list\0""lst\0"; 522 "add\0""change\0""delete\0""show\0""list\0""lst\0";
524 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst }; 523 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
525 int key; 524 int key;
526 525
527 if (argc) { 526 if (*argv) {
528 key = index_in_substrings(keywords, *argv); 527 key = index_in_substrings(keywords, *argv);
529 if (key < 0) 528 if (key < 0)
530 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 529 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
531 --argc; 530 argv++;
532 ++argv;
533 if (key == ARG_add) 531 if (key == ARG_add)
534 return do_add(SIOCADDTUNNEL, argc, argv); 532 return do_add(SIOCADDTUNNEL, argv);
535 if (key == ARG_change) 533 if (key == ARG_change)
536 return do_add(SIOCCHGTUNNEL, argc, argv); 534 return do_add(SIOCCHGTUNNEL, argv);
537 if (key == ARG_del) 535 if (key == ARG_del)
538 return do_del(argc, argv); 536 return do_del(argv);
539 } 537 }
540 return do_show(argc, argv); 538 return do_show(argv);
541} 539}
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h
index 2c4dffd95..cd650492d 100644
--- a/networking/libiproute/utils.h
+++ b/networking/libiproute/utils.h
@@ -6,7 +6,7 @@
6#include "ll_map.h" 6#include "ll_map.h"
7#include "rtm_map.h" 7#include "rtm_map.h"
8 8
9extern int preferred_family; 9extern family_t preferred_family;
10extern smallint show_stats; /* UNUSED */ 10extern smallint show_stats; /* UNUSED */
11extern smallint show_details; /* UNUSED */ 11extern smallint show_details; /* UNUSED */
12extern smallint show_raw; /* UNUSED */ 12extern smallint show_raw; /* UNUSED */
@@ -26,7 +26,7 @@ extern char _SL_;
26 26
27extern void incomplete_command(void) ATTRIBUTE_NORETURN; 27extern void incomplete_command(void) ATTRIBUTE_NORETURN;
28 28
29#define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while (0) 29#define NEXT_ARG() do { if (!*++argv) incomplete_command(); } while (0)
30 30
31typedef struct 31typedef struct
32{ 32{