summaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-07 01:14:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-07 01:14:45 +0000
commit540a2a1f3b056ddaea72f84c5a9b7ec947d75c8e (patch)
tree1d5e5c26d7bcffe29d58d50305ca1e2408f1985a /networking
parentfbd2918f5c91723063ed698026217a77a0fe565b (diff)
downloadbusybox-w32-540a2a1f3b056ddaea72f84c5a9b7ec947d75c8e.tar.gz
busybox-w32-540a2a1f3b056ddaea72f84c5a9b7ec947d75c8e.tar.bz2
busybox-w32-540a2a1f3b056ddaea72f84c5a9b7ec947d75c8e.zip
libiproute: audit callgraph, shortcut error paths into die() functions.
Kill a few statics, made other globals smaller: oneline is smallint, _SL_ is char function old new delta print_tunnel 693 731 +38 print_route 1775 1777 +2 print_addrinfo 1495 1497 +2 ipaddr_list_or_flush 2826 2828 +2 oneline 4 1 -3 _SL_ 4 1 -3 ipaddr_modify 1476 1472 -4 parse_address 124 119 -5 ip_parse_common_args 429 423 -6 on_off 53 46 -7 do_del_ioctl 113 106 -7 do_add_ioctl 120 113 -7 do_show 864 856 -8 iprule_list 157 148 -9 do_iptunnel 310 299 -11 do_add 143 126 -17 get_ctl_fd 95 76 -19 set_address 108 84 -24 ip_main 351 323 -28 static.ifr 32 - -32 parse_args 1992 1949 -43 iproute_list_or_flush 1673 1582 -91 do_iplink 1583 1485 -98 filter 280 - -280 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 4/18 up/down: 44/-702) Total: -658 bytes
Diffstat (limited to 'networking')
-rw-r--r--networking/ip.c43
-rw-r--r--networking/libiproute/ip_common.h5
-rw-r--r--networking/libiproute/ip_parse_common_args.c6
-rw-r--r--networking/libiproute/ipaddress.c71
-rw-r--r--networking/libiproute/iplink.c166
-rw-r--r--networking/libiproute/iproute.c107
-rw-r--r--networking/libiproute/iprule.c15
-rw-r--r--networking/libiproute/iptunnel.c121
-rw-r--r--networking/libiproute/ll_map.c12
-rw-r--r--networking/libiproute/utils.c5
-rw-r--r--networking/libiproute/utils.h15
11 files changed, 247 insertions, 319 deletions
diff --git a/networking/ip.c b/networking/ip.c
index fdd848049..d51689542 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -20,31 +20,28 @@
20int ip_main(int argc, char **argv); 20int ip_main(int argc, char **argv);
21int ip_main(int argc, char **argv) 21int ip_main(int argc, char **argv)
22{ 22{
23 int ret = EXIT_FAILURE;
24
25 ip_parse_common_args(&argc, &argv); 23 ip_parse_common_args(&argc, &argv);
26 24
27 if (argc > 1) { 25 if (argc <= 1)
28 if (ENABLE_FEATURE_IP_ADDRESS && matches(argv[1], "address") == 0) {
29 ret = do_ipaddr(argc-2, argv+2);
30 }
31 if (ENABLE_FEATURE_IP_ROUTE && matches(argv[1], "route") == 0) {
32 ret = do_iproute(argc-2, argv+2);
33 }
34 if (ENABLE_FEATURE_IP_LINK && matches(argv[1], "link") == 0) {
35 ret = do_iplink(argc-2, argv+2);
36 }
37 if (ENABLE_FEATURE_IP_TUNNEL
38 && (matches(argv[1], "tunnel") == 0 || strcmp(argv[1], "tunl") == 0)
39 ) {
40 ret = do_iptunnel(argc-2, argv+2);
41 }
42 if (ENABLE_FEATURE_IP_RULE && matches(argv[1], "rule") == 0) {
43 ret = do_iprule(argc-2, argv+2);
44 }
45 }
46 if (ret) {
47 bb_show_usage(); 26 bb_show_usage();
27
28 if (ENABLE_FEATURE_IP_ADDRESS && matches(argv[1], "address") == 0) {
29 return do_ipaddr(argc-2, argv+2);
30 }
31 if (ENABLE_FEATURE_IP_ROUTE && matches(argv[1], "route") == 0) {
32 return do_iproute(argc-2, argv+2);
48 } 33 }
49 return EXIT_SUCCESS; 34 if (ENABLE_FEATURE_IP_LINK && matches(argv[1], "link") == 0) {
35 return do_iplink(argc-2, argv+2);
36 }
37 if (ENABLE_FEATURE_IP_TUNNEL
38 && (matches(argv[1], "tunnel") == 0 || strcmp(argv[1], "tunl") == 0)
39 ) {
40 return do_iptunnel(argc-2, argv+2);
41 }
42 if (ENABLE_FEATURE_IP_RULE && matches(argv[1], "rule") == 0) {
43 return do_iprule(argc-2, argv+2);
44 }
45
46 bb_show_usage();
50} 47}
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h
index 05a6a95f5..96df6100a 100644
--- a/networking/libiproute/ip_common.h
+++ b/networking/libiproute/ip_common.h
@@ -13,16 +13,13 @@
13#include <linux/if_link.h> 13#include <linux/if_link.h>
14#endif 14#endif
15 15
16extern int preferred_family;
17//FIXME! Appears in two .h files!
18extern const char * _SL_;
19
20extern void ip_parse_common_args(int *argcp, char ***argvp); 16extern void ip_parse_common_args(int *argcp, char ***argvp);
21extern 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);
22extern int ipaddr_list_or_flush(int argc, char **argv, int flush); 18extern int ipaddr_list_or_flush(int argc, char **argv, int flush);
23extern int iproute_monitor(int argc, char **argv); 19extern int iproute_monitor(int argc, char **argv);
24extern void iplink_usage(void) ATTRIBUTE_NORETURN; 20extern void iplink_usage(void) ATTRIBUTE_NORETURN;
25extern void ipneigh_reset_filter(void); 21extern void ipneigh_reset_filter(void);
22
26extern int do_ipaddr(int argc, char **argv); 23extern int do_ipaddr(int argc, char **argv);
27extern int do_iproute(int argc, char **argv); 24extern int do_iproute(int argc, char **argv);
28extern int do_iprule(int argc, char **argv); 25extern int do_iprule(int argc, char **argv);
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index 00a891232..6efbc6912 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -23,8 +23,8 @@
23 23
24 24
25int preferred_family = AF_UNSPEC; 25int preferred_family = AF_UNSPEC;
26int oneline = 0; 26smallint oneline;
27const char * _SL_ = NULL; 27char _SL_;
28 28
29void ip_parse_common_args(int *argcp, char ***argvp) 29void ip_parse_common_args(int *argcp, char ***argvp)
30{ 30{
@@ -73,7 +73,7 @@ void ip_parse_common_args(int *argcp, char ***argvp)
73 argc--; 73 argc--;
74 argv++; 74 argv++;
75 } 75 }
76 _SL_ = oneline ? "\\" : "\n" ; 76 _SL_ = oneline ? '\\' : '\n' ;
77 *argcp = argc; 77 *argcp = argc;
78 *argvp = argv; 78 *argvp = argv;
79} 79}
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index bc9963f1f..ab9706492 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -26,8 +26,7 @@
26#include "ip_common.h" 26#include "ip_common.h"
27 27
28 28
29static struct 29typedef struct filter_t {
30{
31 int ifindex; 30 int ifindex;
32 int family; 31 int family;
33 int oneline; 32 int oneline;
@@ -42,7 +41,10 @@ static struct
42 int flushp; 41 int flushp;
43 int flushe; 42 int flushe;
44 struct rtnl_handle *rth; 43 struct rtnl_handle *rth;
45} filter; 44} filter_t;
45
46#define filter (*(filter_t*)&bb_common_bufsiz1)
47
46 48
47static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) 49static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
48{ 50{
@@ -88,7 +90,7 @@ static void print_queuelen(char *name)
88 memset(&ifr, 0, sizeof(ifr)); 90 memset(&ifr, 0, sizeof(ifr));
89 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 91 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
90 if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 92 if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
91 perror("SIOCGIFXQLEN"); 93 bb_perror_msg("SIOCGIFXQLEN");
92 close(s); 94 close(s);
93 return; 95 return;
94 } 96 }
@@ -125,10 +127,12 @@ static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
125 bb_error_msg("nil ifname"); 127 bb_error_msg("nil ifname");
126 return -1; 128 return -1;
127 } 129 }
128 if (filter.label && 130 if (filter.label
129 (!filter.family || filter.family == AF_PACKET) && 131 && (!filter.family || filter.family == AF_PACKET)
130 fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 132 && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
133 ) {
131 return 0; 134 return 0;
135 }
132 136
133 if (n->nlmsg_type == RTM_DELLINK) 137 if (n->nlmsg_type == RTM_DELLINK)
134 fprintf(fp, "Deleted "); 138 fprintf(fp, "Deleted ");
@@ -166,8 +170,7 @@ static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
166 170
167 if (!filter.family || filter.family == AF_PACKET) { 171 if (!filter.family || filter.family == AF_PACKET) {
168 SPRINT_BUF(b1); 172 SPRINT_BUF(b1);
169 fprintf(fp, "%s", _SL_); 173 fprintf(fp, "%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
170 fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
171 174
172 if (tb[IFLA_ADDRESS]) { 175 if (tb[IFLA_ADDRESS]) {
173 fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 176 fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
@@ -186,7 +189,7 @@ static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
186 b1, sizeof(b1))); 189 b1, sizeof(b1)));
187 } 190 }
188 } 191 }
189 fprintf(fp, "\n"); 192 fputc('\n', fp);
190 fflush(fp); 193 fflush(fp);
191 return 0; 194 return 0;
192} 195}
@@ -194,7 +197,7 @@ static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
194static int flush_update(void) 197static int flush_update(void)
195{ 198{
196 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 199 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
197 perror("Failed to send flush request\n"); 200 bb_perror_msg("failed to send flush request");
198 return -1; 201 return -1;
199 } 202 }
200 filter.flushp = 0; 203 filter.flushp = 0;
@@ -341,7 +344,7 @@ static int print_addrinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
341 if (rta_tb[IFA_CACHEINFO]) { 344 if (rta_tb[IFA_CACHEINFO]) {
342 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 345 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
343 char buf[128]; 346 char buf[128];
344 fprintf(fp, "%s", _SL_); 347 fputc(_SL_, fp);
345 if (ci->ifa_valid == 0xFFFFFFFFU) 348 if (ci->ifa_valid == 0xFFFFFFFFU)
346 sprintf(buf, "valid_lft forever"); 349 sprintf(buf, "valid_lft forever");
347 else 350 else
@@ -352,7 +355,7 @@ static int print_addrinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
352 sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered); 355 sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered);
353 fprintf(fp, " %s", buf); 356 fprintf(fp, " %s", buf);
354 } 357 }
355 fprintf(fp, "\n"); 358 fputc('\n', fp);
356 fflush(fp); 359 fflush(fp);
357 return 0; 360 return 0;
358} 361}
@@ -366,7 +369,7 @@ struct nlmsg_list
366 369
367static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) 370static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
368{ 371{
369 for ( ;ainfo ; ainfo = ainfo->next) { 372 for (; ainfo; ainfo = ainfo->next) {
370 struct nlmsghdr *n = &ainfo->h; 373 struct nlmsghdr *n = &ainfo->h;
371 struct ifaddrmsg *ifa = NLMSG_DATA(n); 374 struct ifaddrmsg *ifa = NLMSG_DATA(n);
372 375
@@ -412,6 +415,7 @@ static void ipaddr_reset_filter(int _oneline)
412 filter.oneline = _oneline; 415 filter.oneline = _oneline;
413} 416}
414 417
418/* Return value becomes exitcode. It's okay to not return at all */
415int ipaddr_list_or_flush(int argc, char **argv, int flush) 419int ipaddr_list_or_flush(int argc, char **argv, int flush)
416{ 420{
417 static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 }; 421 static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 };
@@ -431,12 +435,10 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
431 435
432 if (flush) { 436 if (flush) {
433 if (argc <= 0) { 437 if (argc <= 0) {
434 bb_error_msg(bb_msg_requires_arg, "flush"); 438 bb_error_msg_and_die(bb_msg_requires_arg, "flush");
435 return -1;
436 } 439 }
437 if (filter.family == AF_PACKET) { 440 if (filter.family == AF_PACKET) {
438 bb_error_msg("cannot flush link addresses"); 441 bb_error_msg_and_die("cannot flush link addresses");
439 return -1;
440 } 442 }
441 } 443 }
442 444
@@ -498,8 +500,7 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
498 if (filter_dev) { 500 if (filter_dev) {
499 filter.ifindex = ll_name_to_index(filter_dev); 501 filter.ifindex = ll_name_to_index(filter_dev);
500 if (filter.ifindex <= 0) { 502 if (filter.ifindex <= 0) {
501 bb_error_msg("device \"%s\" does not exist", filter_dev); 503 bb_error_msg_and_die("device \"%s\" does not exist", filter_dev);
502 return -1;
503 } 504 }
504 } 505 }
505 506
@@ -513,20 +514,17 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
513 514
514 for (;;) { 515 for (;;) {
515 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 516 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
516 perror("Cannot send dump request"); 517 bb_perror_msg_and_die("cannot send dump request");
517 exit(1);
518 } 518 }
519 filter.flushed = 0; 519 filter.flushed = 0;
520 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { 520 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) {
521 fprintf(stderr, "Flush terminated\n"); 521 bb_error_msg_and_die("flush terminated");
522 exit(1);
523 } 522 }
524 if (filter.flushed == 0) { 523 if (filter.flushed == 0) {
525 fflush(stdout);
526 return 0; 524 return 0;
527 } 525 }
528 if (flush_update() < 0) 526 if (flush_update() < 0)
529 exit(1); 527 return 1;
530 } 528 }
531 } 529 }
532 530
@@ -601,16 +599,16 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
601 } 599 }
602 } 600 }
603 601
604 for (l=linfo; l; l = l->next) { 602 for (l = linfo; l; l = l->next) {
605 if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { 603 if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
606 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 604 struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
607 if (filter.family != AF_PACKET) 605 if (filter.family != AF_PACKET)
608 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 606 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
609 } 607 }
610 fflush(stdout); 608 fflush(stdout); /* why? */
611 } 609 }
612 610
613 exit(0); 611 return 0;
614} 612}
615 613
616static int default_scope(inet_prefix *lcl) 614static int default_scope(inet_prefix *lcl)
@@ -622,6 +620,7 @@ static int default_scope(inet_prefix *lcl)
622 return 0; 620 return 0;
623} 621}
624 622
623/* Return value becomes exitcode. It's okay to not return at all */
625static int ipaddr_modify(int cmd, int argc, char **argv) 624static int ipaddr_modify(int cmd, int argc, char **argv)
626{ 625{
627 static const char *const option[] = { 626 static const char *const option[] = {
@@ -763,8 +762,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
763 inet_prefix brd; 762 inet_prefix brd;
764 int i; 763 int i;
765 if (req.ifa.ifa_family != AF_INET) { 764 if (req.ifa.ifa_family != AF_INET) {
766 bb_error_msg("broadcast can be set only for IPv4 addresses"); 765 bb_error_msg_and_die("broadcast can be set only for IPv4 addresses");
767 return -1;
768 } 766 }
769 brd = peer; 767 brd = peer;
770 if (brd.bitlen <= 30) { 768 if (brd.bitlen <= 30) {
@@ -786,17 +784,18 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
786 784
787 ll_init_map(&rth); 785 ll_init_map(&rth);
788 786
789 if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 787 req.ifa.ifa_index = ll_name_to_index(d);
790 bb_error_msg("cannot find device \"%s\"", d); 788 if (req.ifa.ifa_index == 0) {
791 return -1; 789 bb_error_msg_and_die("cannot find device \"%s\"", d);
792 } 790 }
793 791
794 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 792 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
795 exit(2); 793 return 2;
796 794
797 exit(0); 795 return 0;
798} 796}
799 797
798/* Return value becomes exitcode. It's okay to not return at all */
800int do_ipaddr(int argc, char **argv) 799int do_ipaddr(int argc, char **argv)
801{ 800{
802 static const char *const commands[] = { 801 static const char *const commands[] = {
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index cb6ee962b..0943726e1 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -22,63 +22,54 @@
22#include "utils.h" 22#include "utils.h"
23#include "ip_common.h" 23#include "ip_common.h"
24 24
25/* take from linux/sockios.h */ 25/* taken from linux/sockios.h */
26#define SIOCSIFNAME 0x8923 /* set interface name */ 26#define SIOCSIFNAME 0x8923 /* set interface name */
27 27
28static int on_off(const char *msg) 28static void on_off(const char *msg) ATTRIBUTE_NORETURN;
29static void on_off(const char *msg)
29{ 30{
30 bb_error_msg("error: argument of \"%s\" must be \"on\" or \"off\"", msg); 31 bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg);
31 return -1;
32} 32}
33 33
34/* Exits on error */
34static int get_ctl_fd(void) 35static int get_ctl_fd(void)
35{ 36{
36 int s_errno;
37 int fd; 37 int fd;
38 38
39 fd = socket(PF_INET, SOCK_DGRAM, 0); 39 fd = socket(PF_INET, SOCK_DGRAM, 0);
40 if (fd >= 0) 40 if (fd >= 0)
41 return fd; 41 return fd;
42 s_errno = errno;
43 fd = socket(PF_PACKET, SOCK_DGRAM, 0); 42 fd = socket(PF_PACKET, SOCK_DGRAM, 0);
44 if (fd >= 0) 43 if (fd >= 0)
45 return fd; 44 return fd;
46 fd = socket(PF_INET6, SOCK_DGRAM, 0); 45 fd = socket(PF_INET6, SOCK_DGRAM, 0);
47 if (fd >= 0) 46 if (fd >= 0)
48 return fd; 47 return fd;
49 errno = s_errno; 48 bb_perror_msg_and_die("cannot create control socket");
50 bb_perror_msg("cannot create control socket");
51 return -1;
52} 49}
53 50
54static int do_chflags(char *dev, uint32_t flags, uint32_t mask) 51/* Exits on error */
52static void do_chflags(char *dev, uint32_t flags, uint32_t mask)
55{ 53{
56 struct ifreq ifr; 54 struct ifreq ifr;
57 int fd; 55 int fd;
58 int err;
59 56
60 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 57 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
61 fd = get_ctl_fd(); 58 fd = get_ctl_fd();
62 if (fd < 0) 59 if (ioctl(fd, SIOCGIFFLAGS, &ifr)) {
63 return -1; 60 bb_perror_msg_and_die("SIOCGIFFLAGS");
64 err = ioctl(fd, SIOCGIFFLAGS, &ifr);
65 if (err) {
66 bb_perror_msg("SIOCGIFFLAGS");
67 close(fd);
68 return -1;
69 } 61 }
70 if ((ifr.ifr_flags^flags)&mask) { 62 if ((ifr.ifr_flags ^ flags) & mask) {
71 ifr.ifr_flags &= ~mask; 63 ifr.ifr_flags &= ~mask;
72 ifr.ifr_flags |= mask&flags; 64 ifr.ifr_flags |= mask & flags;
73 err = ioctl(fd, SIOCSIFFLAGS, &ifr); 65 if (ioctl(fd, SIOCSIFFLAGS, &ifr))
74 if (err) 66 bb_perror_msg_and_die("SIOCSIFFLAGS");
75 bb_perror_msg("SIOCSIFFLAGS");
76 } 67 }
77 close(fd); 68 close(fd);
78 return err;
79} 69}
80 70
81static int do_changename(char *dev, char *newdev) 71/* Exits on error */
72static void do_changename(char *dev, char *newdev)
82{ 73{
83 struct ifreq ifr; 74 struct ifreq ifr;
84 int fd; 75 int fd;
@@ -87,62 +78,46 @@ static int do_changename(char *dev, char *newdev)
87 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 78 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
88 strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname)); 79 strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname));
89 fd = get_ctl_fd(); 80 fd = get_ctl_fd();
90 if (fd < 0)
91 return -1;
92 err = ioctl(fd, SIOCSIFNAME, &ifr); 81 err = ioctl(fd, SIOCSIFNAME, &ifr);
93 if (err) { 82 if (err) {
94 bb_perror_msg("SIOCSIFNAME"); 83 bb_perror_msg_and_die("SIOCSIFNAME");
95 close(fd);
96 return -1;
97 } 84 }
98 close(fd); 85 close(fd);
99 return err;
100} 86}
101 87
102static int set_qlen(char *dev, int qlen) 88/* Exits on error */
89static void set_qlen(char *dev, int qlen)
103{ 90{
104 struct ifreq ifr; 91 struct ifreq ifr;
105 int s; 92 int s;
106 93
107 s = get_ctl_fd(); 94 s = get_ctl_fd();
108 if (s < 0)
109 return -1;
110
111 memset(&ifr, 0, sizeof(ifr)); 95 memset(&ifr, 0, sizeof(ifr));
112 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 96 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
113 ifr.ifr_qlen = qlen; 97 ifr.ifr_qlen = qlen;
114 if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { 98 if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
115 bb_perror_msg("SIOCSIFXQLEN"); 99 bb_perror_msg_and_die("SIOCSIFXQLEN");
116 close(s);
117 return -1;
118 } 100 }
119 close(s); 101 close(s);
120
121 return 0;
122} 102}
123 103
124static int set_mtu(char *dev, int mtu) 104/* Exits on error */
105static void set_mtu(char *dev, int mtu)
125{ 106{
126 struct ifreq ifr; 107 struct ifreq ifr;
127 int s; 108 int s;
128 109
129 s = get_ctl_fd(); 110 s = get_ctl_fd();
130 if (s < 0)
131 return -1;
132
133 memset(&ifr, 0, sizeof(ifr)); 111 memset(&ifr, 0, sizeof(ifr));
134 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 112 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
135 ifr.ifr_mtu = mtu; 113 ifr.ifr_mtu = mtu;
136 if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { 114 if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
137 bb_perror_msg("SIOCSIFMTU"); 115 bb_perror_msg_and_die("SIOCSIFMTU");
138 close(s);
139 return -1;
140 } 116 }
141 close(s); 117 close(s);
142
143 return 0;
144} 118}
145 119
120/* Exits on error */
146static int get_address(char *dev, int *htype) 121static int get_address(char *dev, int *htype)
147{ 122{
148 struct ifreq ifr; 123 struct ifreq ifr;
@@ -152,16 +127,13 @@ static int get_address(char *dev, int *htype)
152 127
153 s = socket(PF_PACKET, SOCK_DGRAM, 0); 128 s = socket(PF_PACKET, SOCK_DGRAM, 0);
154 if (s < 0) { 129 if (s < 0) {
155 bb_perror_msg("socket(PF_PACKET)"); 130 bb_perror_msg_and_die("socket(PF_PACKET)");
156 return -1;
157 } 131 }
158 132
159 memset(&ifr, 0, sizeof(ifr)); 133 memset(&ifr, 0, sizeof(ifr));
160 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 134 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
161 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 135 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
162 bb_perror_msg("SIOCGIFINDEX"); 136 bb_perror_msg_and_die("SIOCGIFINDEX");
163 close(s);
164 return -1;
165 } 137 }
166 138
167 memset(&me, 0, sizeof(me)); 139 memset(&me, 0, sizeof(me));
@@ -169,23 +141,20 @@ static int get_address(char *dev, int *htype)
169 me.sll_ifindex = ifr.ifr_ifindex; 141 me.sll_ifindex = ifr.ifr_ifindex;
170 me.sll_protocol = htons(ETH_P_LOOP); 142 me.sll_protocol = htons(ETH_P_LOOP);
171 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 143 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
172 bb_perror_msg("bind"); 144 bb_perror_msg_and_die("bind");
173 close(s);
174 return -1;
175 } 145 }
176 146
177 alen = sizeof(me); 147 alen = sizeof(me);
178 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 148 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
179 bb_perror_msg("getsockname"); 149 bb_perror_msg_and_die("getsockname");
180 close(s);
181 return -1;
182 } 150 }
183 close(s); 151 close(s);
184 *htype = me.sll_hatype; 152 *htype = me.sll_hatype;
185 return me.sll_halen; 153 return me.sll_halen;
186} 154}
187 155
188static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) 156/* Exits on error */
157static void parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr)
189{ 158{
190 int alen; 159 int alen;
191 160
@@ -194,31 +163,26 @@ static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifr
194 ifr->ifr_hwaddr.sa_family = hatype; 163 ifr->ifr_hwaddr.sa_family = hatype;
195 alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla); 164 alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla);
196 if (alen < 0) 165 if (alen < 0)
197 return -1; 166 exit(1);
198 if (alen != halen) { 167 if (alen != halen) {
199 bb_error_msg("wrong address (%s) length: expected %d bytes", lla, halen); 168 bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen);
200 return -1;
201 } 169 }
202 return 0;
203} 170}
204 171
205static int set_address(struct ifreq *ifr, int brd) 172/* Exits on error */
173static void set_address(struct ifreq *ifr, int brd)
206{ 174{
207 int s; 175 int s;
208 176
209 s = get_ctl_fd(); 177 s = get_ctl_fd();
210 if (s < 0) 178 if (ioctl(s, brd ? SIOCSIFHWBROADCAST :SIOCSIFHWADDR, ifr) < 0) {
211 return -1; 179 bb_perror_msg_and_die(brd ? "SIOCSIFHWBROADCAST" : "SIOCSIFHWADDR");
212 if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) {
213 bb_perror_msg(brd ? "SIOCSIFHWBROADCAST" : "SIOCSIFHWADDR");
214 close(s);
215 return -1;
216 } 180 }
217 close(s); 181 close(s);
218 return 0;
219} 182}
220 183
221 184
185/* Return value becomes exitcode. It's okay to not return at all */
222static int do_set(int argc, char **argv) 186static int do_set(int argc, char **argv)
223{ 187{
224 char *dev = NULL; 188 char *dev = NULL;
@@ -256,7 +220,7 @@ static int do_set(int argc, char **argv)
256 } else if (strcmp(*argv, "off") == 0) { 220 } else if (strcmp(*argv, "off") == 0) {
257 flags &= ~IFF_MULTICAST; 221 flags &= ~IFF_MULTICAST;
258 } else 222 } else
259 return on_off("multicast"); 223 on_off("multicast");
260 } else if (strcmp(*argv, "arp") == 0) { 224 } else if (strcmp(*argv, "arp") == 0) {
261 NEXT_ARG(); 225 NEXT_ARG();
262 mask |= IFF_NOARP; 226 mask |= IFF_NOARP;
@@ -265,7 +229,7 @@ static int do_set(int argc, char **argv)
265 } else if (strcmp(*argv, "off") == 0) { 229 } else if (strcmp(*argv, "off") == 0) {
266 flags |= IFF_NOARP; 230 flags |= IFF_NOARP;
267 } else 231 } else
268 return on_off("noarp"); 232 on_off("noarp");
269 } else if (strcmp(*argv, "addr") == 0) { 233 } else if (strcmp(*argv, "addr") == 0) {
270 NEXT_ARG(); 234 NEXT_ARG();
271 newaddr = *argv; 235 newaddr = *argv;
@@ -277,53 +241,44 @@ static int do_set(int argc, char **argv)
277 duparg2("dev", *argv); 241 duparg2("dev", *argv);
278 dev = *argv; 242 dev = *argv;
279 } 243 }
280 argc--; argv++; 244 argc--;
245 argv++;
281 } 246 }
282 247
283 if (!dev) { 248 if (!dev) {
284 bb_error_msg(bb_msg_requires_arg, "\"dev\""); 249 bb_error_msg_and_die(bb_msg_requires_arg, "\"dev\"");
285 exit(-1);
286 } 250 }
287 251
288 if (newaddr || newbrd) { 252 if (newaddr || newbrd) {
289 halen = get_address(dev, &htype); 253 halen = get_address(dev, &htype);
290 if (halen < 0)
291 return -1;
292 if (newaddr) { 254 if (newaddr) {
293 if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) 255 parse_address(dev, htype, halen, newaddr, &ifr0);
294 return -1;
295 } 256 }
296 if (newbrd) { 257 if (newbrd) {
297 if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) 258 parse_address(dev, htype, halen, newbrd, &ifr1);
298 return -1;
299 } 259 }
300 } 260 }
301 261
302 if (newname && strcmp(dev, newname)) { 262 if (newname && strcmp(dev, newname)) {
303 if (do_changename(dev, newname) < 0) 263 do_changename(dev, newname);
304 return -1;
305 dev = newname; 264 dev = newname;
306 } 265 }
307 if (qlen != -1) { 266 if (qlen != -1) {
308 if (set_qlen(dev, qlen) < 0) 267 set_qlen(dev, qlen);
309 return -1;
310 } 268 }
311 if (mtu != -1) { 269 if (mtu != -1) {
312 if (set_mtu(dev, mtu) < 0) 270 set_mtu(dev, mtu);
313 return -1;
314 } 271 }
315 if (newaddr || newbrd) { 272 if (newaddr || newbrd) {
316 if (newbrd) { 273 if (newbrd) {
317 if (set_address(&ifr1, 1) < 0) 274 set_address(&ifr1, 1);
318 return -1;
319 } 275 }
320 if (newaddr) { 276 if (newaddr) {
321 if (set_address(&ifr0, 0) < 0) 277 set_address(&ifr0, 0);
322 return -1;
323 } 278 }
324 } 279 }
325 if (mask) 280 if (mask)
326 return do_chflags(dev, flags, mask); 281 do_chflags(dev, flags, mask);
327 return 0; 282 return 0;
328} 283}
329 284
@@ -333,18 +288,19 @@ static int ipaddr_list_link(int argc, char **argv)
333 return ipaddr_list_or_flush(argc, argv, 0); 288 return ipaddr_list_or_flush(argc, argv, 0);
334} 289}
335 290
291/* Return value becomes exitcode. It's okay to not return at all */
336int do_iplink(int argc, char **argv) 292int do_iplink(int argc, char **argv)
337{ 293{
338 if (argc > 0) { 294 if (argc <= 0)
339 if (matches(*argv, "set") == 0)
340 return do_set(argc-1, argv+1);
341 if (matches(*argv, "show") == 0 ||
342 matches(*argv, "lst") == 0 ||
343 matches(*argv, "list") == 0)
344 return ipaddr_list_link(argc-1, argv+1);
345 } else
346 return ipaddr_list_link(0, NULL); 295 return ipaddr_list_link(0, NULL);
347 296
348 bb_error_msg("command \"%s\" is unknown", *argv); 297 if (matches(*argv, "set") == 0)
349 exit(-1); 298 return do_set(argc-1, argv+1);
299
300 if (matches(*argv, "show") == 0 ||
301 matches(*argv, "lst") == 0 ||
302 matches(*argv, "list") == 0)
303 return ipaddr_list_link(argc-1, argv+1);
304
305 bb_error_msg_and_die("command \"%s\" is unknown", *argv);
350} 306}
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 27d37ac79..bb0bfaed1 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -24,8 +24,7 @@
24#endif 24#endif
25 25
26 26
27static struct 27typedef struct filter_t {
28{
29 int tb; 28 int tb;
30 int flushed; 29 int flushed;
31 char *flushb; 30 char *flushb;
@@ -45,12 +44,14 @@ static struct
45 inet_prefix mdst; 44 inet_prefix mdst;
46 inet_prefix rsrc; 45 inet_prefix rsrc;
47 inet_prefix msrc; 46 inet_prefix msrc;
48} filter; 47} filter_t;
48
49#define filter (*(filter_t*)&bb_common_bufsiz1)
49 50
50static int flush_update(void) 51static int flush_update(void)
51{ 52{
52 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 53 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
53 perror("Failed to send flush request\n"); 54 bb_perror_msg("failed to send flush request");
54 return -1; 55 return -1;
55 } 56 }
56 filter.flushp = 0; 57 filter.flushp = 0;
@@ -273,7 +274,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
273 } 274 }
274 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { 275 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
275 if (r->rtm_flags & RTM_F_CLONED) { 276 if (r->rtm_flags & RTM_F_CLONED) {
276 fprintf(fp, "%s cache ", _SL_); 277 fprintf(fp, "%c cache ", _SL_);
277 } 278 }
278 if (ci->rta_expires) { 279 if (ci->rta_expires) {
279 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); 280 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
@@ -289,11 +290,12 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
289 if (tb[RTA_IIF] && filter.iifmask != -1) { 290 if (tb[RTA_IIF] && filter.iifmask != -1) {
290 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); 291 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
291 } 292 }
292 fprintf(fp, "\n"); 293 fputc('\n', fp);
293 fflush(fp); 294 fflush(fp);
294 return 0; 295 return 0;
295} 296}
296 297
298/* Return value becomes exitcode. It's okay to not return at all */
297static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 299static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
298{ 300{
299 struct rtnl_handle rth; 301 struct rtnl_handle rth;
@@ -302,10 +304,10 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
302 struct rtmsg r; 304 struct rtmsg r;
303 char buf[1024]; 305 char buf[1024];
304 } req; 306 } req;
305 char mxbuf[256]; 307 char mxbuf[256];
306 struct rtattr * mxrta = (void*)mxbuf; 308 struct rtattr * mxrta = (void*)mxbuf;
307 unsigned mxlock = 0; 309 unsigned mxlock = 0;
308 char *d = NULL; 310 char *d = NULL;
309 int gw_ok = 0; 311 int gw_ok = 0;
310 int dst_ok = 0; 312 int dst_ok = 0;
311 int proto_ok = 0; 313 int proto_ok = 0;
@@ -384,8 +386,9 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
384 if (strcmp(*argv, "to") == 0) { 386 if (strcmp(*argv, "to") == 0) {
385 NEXT_ARG(); 387 NEXT_ARG();
386 } 388 }
387 if ((**argv < '0' || **argv > '9') && 389 if ((**argv < '0' || **argv > '9')
388 rtnl_rtntype_a2n(&type, *argv) == 0) { 390 && rtnl_rtntype_a2n(&type, *argv) == 0
391 ) {
389 NEXT_ARG(); 392 NEXT_ARG();
390 req.r.rtm_type = type; 393 req.r.rtm_type = type;
391 type_ok = 1; 394 type_ok = 1;
@@ -408,7 +411,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
408 } 411 }
409 412
410 if (rtnl_open(&rth, 0) < 0) { 413 if (rtnl_open(&rth, 0) < 0) {
411 exit(1); 414 return 1;
412 } 415 }
413 416
414 if (d) { 417 if (d) {
@@ -419,8 +422,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
419 if (d) { 422 if (d) {
420 idx = ll_name_to_index(d); 423 idx = ll_name_to_index(d);
421 if (idx == 0) { 424 if (idx == 0) {
422 bb_error_msg("cannot find device \"%s\"", d); 425 bb_error_msg_and_die("cannot find device \"%s\"", d);
423 return -1;
424 } 426 }
425 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 427 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
426 } 428 }
@@ -438,7 +440,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
438 } 440 }
439 441
440 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { 442 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
441 exit(2); 443 return 2;
442 } 444 }
443 445
444 return 0; 446 return 0;
@@ -467,21 +469,21 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
467 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 469 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
468} 470}
469 471
470static int iproute_flush_cache(void) 472static void iproute_flush_cache(void)
471{ 473{
472 static const char fn[] = "/proc/sys/net/ipv4/route/flush"; 474 static const char fn[] = "/proc/sys/net/ipv4/route/flush";
473 int flush_fd = open(fn, O_WRONLY); 475 int flush_fd = open(fn, O_WRONLY);
476
474 if (flush_fd < 0) { 477 if (flush_fd < 0) {
475 bb_perror_msg("cannot open '%s'", fn); 478 bb_perror_msg("cannot open '%s'", fn);
476 return -1; 479 return;
477 } 480 }
478 481
479 if (write(flush_fd, "-1", 2) < 2) { 482 if (write(flush_fd, "-1", 2) < 2) {
480 bb_perror_msg("cannot flush routing cache"); 483 bb_perror_msg("cannot flush routing cache");
481 return -1; 484 return;
482 } 485 }
483 close(flush_fd); 486 close(flush_fd);
484 return 0;
485} 487}
486 488
487static void iproute_reset_filter(void) 489static void iproute_reset_filter(void)
@@ -491,6 +493,7 @@ static void iproute_reset_filter(void)
491 filter.msrc.bitlen = -1; 493 filter.msrc.bitlen = -1;
492} 494}
493 495
496/* Return value becomes exitcode. It's okay to not return at all */
494static int iproute_list_or_flush(int argc, char **argv, int flush) 497static int iproute_list_or_flush(int argc, char **argv, int flush)
495{ 498{
496 int do_ipv6 = preferred_family; 499 int do_ipv6 = preferred_family;
@@ -501,10 +504,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
501 iproute_reset_filter(); 504 iproute_reset_filter();
502 filter.tb = RT_TABLE_MAIN; 505 filter.tb = RT_TABLE_MAIN;
503 506
504 if (flush && argc <= 0) { 507 if (flush && argc <= 0)
505 bb_error_msg(bb_msg_requires_arg, "\"ip route flush\""); 508 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
506 return -1;
507 }
508 509
509 while (argc > 0) { 510 while (argc > 0) {
510 if (matches(*argv, "protocol") == 0) { 511 if (matches(*argv, "protocol") == 0) {
@@ -572,7 +573,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
572 filter.rdst = filter.mdst; 573 filter.rdst = filter.mdst;
573 } 574 }
574 } 575 }
575 argc--; argv++; 576 argc--;
577 argv++;
576 } 578 }
577 579
578 if (do_ipv6 == AF_UNSPEC && filter.tb) { 580 if (do_ipv6 == AF_UNSPEC && filter.tb) {
@@ -580,7 +582,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
580 } 582 }
581 583
582 if (rtnl_open(&rth, 0) < 0) { 584 if (rtnl_open(&rth, 0) < 0) {
583 exit(1); 585 return 1;
584 } 586 }
585 587
586 ll_init_map(&rth); 588 ll_init_map(&rth);
@@ -589,15 +591,16 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
589 int idx; 591 int idx;
590 592
591 if (id) { 593 if (id) {
592 if ((idx = ll_name_to_index(id)) == 0) { 594 idx = ll_name_to_index(id);
593 bb_error_msg("cannot find device \"%s\"", id); 595 if (idx == 0) {
594 return -1; 596 bb_error_msg_and_die("cannot find device \"%s\"", id);
595 } 597 }
596 filter.iif = idx; 598 filter.iif = idx;
597 filter.iifmask = -1; 599 filter.iifmask = -1;
598 } 600 }
599 if (od) { 601 if (od) {
600 if ((idx = ll_name_to_index(od)) == 0) { 602 idx = ll_name_to_index(od);
603 if (idx == 0) {
601 bb_error_msg("cannot find device \"%s\"", od); 604 bb_error_msg("cannot find device \"%s\"", od);
602 } 605 }
603 filter.oif = idx; 606 filter.oif = idx;
@@ -622,20 +625,17 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
622 625
623 for (;;) { 626 for (;;) {
624 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 627 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
625 perror("Cannot send dump request"); 628 bb_perror_msg_and_die("cannot send dump request");
626 return -1;
627 } 629 }
628 filter.flushed = 0; 630 filter.flushed = 0;
629 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { 631 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
630 bb_error_msg("flush terminated"); 632 bb_error_msg_and_die("flush terminated");
631 return -1;
632 } 633 }
633 if (filter.flushed == 0) { 634 if (filter.flushed == 0) {
634 fflush(stdout);
635 return 0; 635 return 0;
636 } 636 }
637 if (flush_update() < 0) 637 if (flush_update())
638 exit(1); 638 return 1;
639 } 639 }
640 } 640 }
641 641
@@ -653,10 +653,11 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
653 bb_error_msg_and_die("dump terminated"); 653 bb_error_msg_and_die("dump terminated");
654 } 654 }
655 655
656 exit(0); 656 return 0;
657} 657}
658 658
659 659
660/* Return value becomes exitcode. It's okay to not return at all */
660static int iproute_get(int argc, char **argv) 661static int iproute_get(int argc, char **argv)
661{ 662{
662 struct rtnl_handle rth; 663 struct rtnl_handle rth;
@@ -734,7 +735,8 @@ static int iproute_get(int argc, char **argv)
734 } 735 }
735 req.r.rtm_dst_len = addr.bitlen; 736 req.r.rtm_dst_len = addr.bitlen;
736 } 737 }
737 argc--; argv++; 738 argc--;
739 argv++;
738 } 740 }
739 } 741 }
740 742
@@ -743,7 +745,7 @@ static int iproute_get(int argc, char **argv)
743 } 745 }
744 746
745 if (rtnl_open(&rth, 0) < 0) 747 if (rtnl_open(&rth, 0) < 0)
746 exit(1); 748 return 1;
747 749
748 ll_init_map(&rth); 750 ll_init_map(&rth);
749 751
@@ -751,16 +753,16 @@ static int iproute_get(int argc, char **argv)
751 int idx; 753 int idx;
752 754
753 if (idev) { 755 if (idev) {
754 if ((idx = ll_name_to_index(idev)) == 0) { 756 idx = ll_name_to_index(idev);
755 bb_error_msg("cannot find device \"%s\"", idev); 757 if (idx == 0) {
756 return -1; 758 bb_error_msg_and_die("cannot find device \"%s\"", idev);
757 } 759 }
758 addattr32(&req.n, sizeof(req), RTA_IIF, idx); 760 addattr32(&req.n, sizeof(req), RTA_IIF, idx);
759 } 761 }
760 if (odev) { 762 if (odev) {
761 if ((idx = ll_name_to_index(odev)) == 0) { 763 idx = ll_name_to_index(odev);
762 bb_error_msg("cannot find device \"%s\"", odev); 764 if (idx == 0) {
763 return -1; 765 bb_error_msg_and_die("cannot find device \"%s\"", odev);
764 } 766 }
765 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 767 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
766 } 768 }
@@ -771,7 +773,7 @@ static int iproute_get(int argc, char **argv)
771 } 773 }
772 774
773 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 775 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
774 exit(2); 776 return 2;
775 } 777 }
776 778
777 if (connected && !from_ok) { 779 if (connected && !from_ok) {
@@ -784,13 +786,11 @@ static int iproute_get(int argc, char **argv)
784 } 786 }
785 787
786 if (req.n.nlmsg_type != RTM_NEWROUTE) { 788 if (req.n.nlmsg_type != RTM_NEWROUTE) {
787 bb_error_msg("not a route?"); 789 bb_error_msg_and_die("not a route?");
788 return -1;
789 } 790 }
790 len -= NLMSG_LENGTH(sizeof(*r)); 791 len -= NLMSG_LENGTH(sizeof(*r));
791 if (len < 0) { 792 if (len < 0) {
792 bb_error_msg("wrong len %d", len); 793 bb_error_msg_and_die("wrong len %d", len);
793 return -1;
794 } 794 }
795 795
796 memset(tb, 0, sizeof(tb)); 796 memset(tb, 0, sizeof(tb));
@@ -800,8 +800,7 @@ static int iproute_get(int argc, char **argv)
800 tb[RTA_PREFSRC]->rta_type = RTA_SRC; 800 tb[RTA_PREFSRC]->rta_type = RTA_SRC;
801 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); 801 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
802 } else if (!tb[RTA_SRC]) { 802 } else if (!tb[RTA_SRC]) {
803 bb_error_msg("failed to connect the route"); 803 bb_error_msg_and_die("failed to connect the route");
804 return -1;
805 } 804 }
806 if (!odev && tb[RTA_OIF]) { 805 if (!odev && tb[RTA_OIF]) {
807 tb[RTA_OIF]->rta_type = 0; 806 tb[RTA_OIF]->rta_type = 0;
@@ -816,17 +815,19 @@ static int iproute_get(int argc, char **argv)
816 req.n.nlmsg_type = RTM_GETROUTE; 815 req.n.nlmsg_type = RTM_GETROUTE;
817 816
818 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 817 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
819 exit(2); 818 return 2;
820 } 819 }
821 } 820 }
822 821
823 if (print_route(NULL, &req.n, (void*)stdout) < 0) { 822 if (print_route(NULL, &req.n, (void*)stdout) < 0) {
823// how is this useful?
824 bb_error_msg_and_die("an error :-)"); 824 bb_error_msg_and_die("an error :-)");
825 } 825 }
826 826
827 exit(0); 827 return 0;
828} 828}
829 829
830/* Return value becomes exitcode. It's okay to not return at all */
830int do_iproute(int argc, char **argv) 831int do_iproute(int argc, char **argv)
831{ 832{
832 static const char * const ip_route_commands[] = { 833 static const char * const ip_route_commands[] = {
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 4b3130307..d4cf2826c 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -155,11 +155,12 @@ static int print_rule(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
155 } else if (r->rtm_type != RTN_UNICAST) 155 } else if (r->rtm_type != RTN_UNICAST)
156 fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); 156 fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
157 157
158 fprintf(fp, "\n"); 158 fputc('\n', fp);
159 fflush(fp); 159 fflush(fp);
160 return 0; 160 return 0;
161} 161}
162 162
163/* Return value becomes exitcode. It's okay to not return at all */
163static int iprule_list(int argc, char **argv) 164static int iprule_list(int argc, char **argv)
164{ 165{
165 struct rtnl_handle rth; 166 struct rtnl_handle rth;
@@ -178,19 +179,18 @@ static int iprule_list(int argc, char **argv)
178 return 1; 179 return 1;
179 180
180 if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) { 181 if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) {
181 bb_perror_msg("Cannot send dump request"); 182 bb_perror_msg_and_die("cannot send dump request");
182 return 1;
183 } 183 }
184 184
185 if (rtnl_dump_filter(&rth, print_rule, stdout, NULL, NULL) < 0) { 185 if (rtnl_dump_filter(&rth, print_rule, stdout, NULL, NULL) < 0) {
186 bb_error_msg("Dump terminated"); 186 bb_error_msg_and_die("dump terminated");
187 return 1;
188 } 187 }
189 188
190 return 0; 189 return 0;
191} 190}
192 191
193 192
193/* Return value becomes exitcode. It's okay to not return at all */
194static int iprule_modify(int cmd, int argc, char **argv) 194static int iprule_modify(int cmd, int argc, char **argv)
195{ 195{
196 int table_ok = 0; 196 int table_ok = 0;
@@ -282,7 +282,8 @@ static int iprule_modify(int cmd, int argc, char **argv)
282 if (matches(*argv, "help") == 0) 282 if (matches(*argv, "help") == 0)
283 bb_show_usage(); 283 bb_show_usage();
284 if (rtnl_rtntype_a2n(&type, *argv)) 284 if (rtnl_rtntype_a2n(&type, *argv))
285 invarg("Failed to parse rule type", *argv); 285// bogus-looking error message "invalid argument 'cannot parse rule type' to '<*argv>'"
286 invarg("cannot parse rule type", *argv);
286 req.r.rtm_type = type; 287 req.r.rtm_type = type;
287 } 288 }
288 argc--; 289 argc--;
@@ -304,6 +305,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
304 return 0; 305 return 0;
305} 306}
306 307
308/* Return value becomes exitcode. It's okay to not return at all */
307int do_iprule(int argc, char **argv) 309int do_iprule(int argc, char **argv)
308{ 310{
309 static const char * const ip_rule_commands[] = 311 static const char * const ip_rule_commands[] =
@@ -331,4 +333,3 @@ int do_iprule(int argc, char **argv)
331 } 333 }
332 return iprule_modify(cmd, argc-1, argv+1); 334 return iprule_modify(cmd, argc-1, argv+1);
333} 335}
334
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index e2e75fce0..52a50993d 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -18,9 +18,6 @@
18#include <sys/socket.h> 18#include <sys/socket.h>
19#include <sys/ioctl.h> 19#include <sys/ioctl.h>
20 20
21#include <string.h>
22#include <unistd.h>
23
24#include <netinet/ip.h> 21#include <netinet/ip.h>
25 22
26#include <net/if.h> 23#include <net/if.h>
@@ -37,6 +34,7 @@
37#include "ip_common.h" 34#include "ip_common.h"
38 35
39 36
37/* Dies on error */
40static int do_ioctl_get_ifindex(char *dev) 38static int do_ioctl_get_ifindex(char *dev)
41{ 39{
42 struct ifreq ifr; 40 struct ifreq ifr;
@@ -45,8 +43,7 @@ static int do_ioctl_get_ifindex(char *dev)
45 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 43 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
46 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 44 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
47 if (ioctl(fd, SIOCGIFINDEX, &ifr)) { 45 if (ioctl(fd, SIOCGIFINDEX, &ifr)) {
48 bb_perror_msg("ioctl"); 46 bb_perror_msg_and_die("SIOCGIFINDEX");
49 return 0;
50 } 47 }
51 close(fd); 48 close(fd);
52 return ifr.ifr_ifindex; 49 return ifr.ifr_ifindex;
@@ -60,31 +57,28 @@ static int do_ioctl_get_iftype(char *dev)
60 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 57 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
61 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 58 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
62 if (ioctl(fd, SIOCGIFHWADDR, &ifr)) { 59 if (ioctl(fd, SIOCGIFHWADDR, &ifr)) {
63 bb_perror_msg("ioctl"); 60 bb_perror_msg("SIOCGIFHWADDR");
64 return -1; 61 return -1;
65 } 62 }
66 close(fd); 63 close(fd);
67 return ifr.ifr_addr.sa_family; 64 return ifr.ifr_addr.sa_family;
68} 65}
69 66
70
71static char *do_ioctl_get_ifname(int idx) 67static char *do_ioctl_get_ifname(int idx)
72{ 68{
73 static struct ifreq ifr; 69 struct ifreq ifr;
74 int fd; 70 int fd;
75 71
76 ifr.ifr_ifindex = idx; 72 ifr.ifr_ifindex = idx;
77 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 73 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
78 if (ioctl(fd, SIOCGIFNAME, &ifr)) { 74 if (ioctl(fd, SIOCGIFNAME, &ifr)) {
79 bb_perror_msg("ioctl"); 75 bb_perror_msg("SIOCGIFNAME");
80 return NULL; 76 return NULL;
81 } 77 }
82 close(fd); 78 close(fd);
83 return ifr.ifr_name; 79 return xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name));
84} 80}
85 81
86
87
88static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p) 82static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
89{ 83{
90 struct ifreq ifr; 84 struct ifreq ifr;
@@ -96,17 +90,17 @@ static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
96 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 90 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
97 err = ioctl(fd, SIOCGETTUNNEL, &ifr); 91 err = ioctl(fd, SIOCGETTUNNEL, &ifr);
98 if (err) { 92 if (err) {
99 bb_perror_msg("ioctl"); 93 bb_perror_msg("SIOCGETTUNNEL");
100 } 94 }
101 close(fd); 95 close(fd);
102 return err; 96 return err;
103} 97}
104 98
99/* Dies on error, otherwise returns 0 */
105static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p) 100static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p)
106{ 101{
107 struct ifreq ifr; 102 struct ifreq ifr;
108 int fd; 103 int fd;
109 int err;
110 104
111 if (cmd == SIOCCHGTUNNEL && p->name[0]) { 105 if (cmd == SIOCCHGTUNNEL && p->name[0]) {
112 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name)); 106 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
@@ -115,19 +109,18 @@ static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p)
115 } 109 }
116 ifr.ifr_ifru.ifru_data = (void*)p; 110 ifr.ifr_ifru.ifru_data = (void*)p;
117 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 111 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
118 err = ioctl(fd, cmd, &ifr); 112 if (ioctl(fd, cmd, &ifr)) {
119 if (err) { 113 bb_perror_msg_and_die("ioctl");
120 bb_perror_msg("ioctl");
121 } 114 }
122 close(fd); 115 close(fd);
123 return err; 116 return 0;
124} 117}
125 118
119/* Dies on error, otherwise returns 0 */
126static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p) 120static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
127{ 121{
128 struct ifreq ifr; 122 struct ifreq ifr;
129 int fd; 123 int fd;
130 int err;
131 124
132 if (p->name[0]) { 125 if (p->name[0]) {
133 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name)); 126 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
@@ -136,15 +129,15 @@ static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
136 } 129 }
137 ifr.ifr_ifru.ifru_data = (void*)p; 130 ifr.ifr_ifru.ifru_data = (void*)p;
138 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 131 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
139 err = ioctl(fd, SIOCDELTUNNEL, &ifr); 132 if (ioctl(fd, SIOCDELTUNNEL, &ifr)) {
140 if (err) { 133 bb_perror_msg_and_die("SIOCDELTUNNEL");
141 bb_perror_msg("ioctl");
142 } 134 }
143 close(fd); 135 close(fd);
144 return err; 136 return 0;
145} 137}
146 138
147static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 139/* Dies on error */
140static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
148{ 141{
149 int count = 0; 142 int count = 0;
150 char medium[IFNAMSIZ]; 143 char medium[IFNAMSIZ];
@@ -164,27 +157,23 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
164 if (strcmp(*argv, "ipip") == 0 || 157 if (strcmp(*argv, "ipip") == 0 ||
165 strcmp(*argv, "ip/ip") == 0) { 158 strcmp(*argv, "ip/ip") == 0) {
166 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { 159 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
167 bb_error_msg("you managed to ask for more than one tunnel mode"); 160 bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
168 exit(-1);
169 } 161 }
170 p->iph.protocol = IPPROTO_IPIP; 162 p->iph.protocol = IPPROTO_IPIP;
171 } else if (strcmp(*argv, "gre") == 0 || 163 } else if (strcmp(*argv, "gre") == 0 ||
172 strcmp(*argv, "gre/ip") == 0) { 164 strcmp(*argv, "gre/ip") == 0) {
173 if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { 165 if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) {
174 bb_error_msg("you managed to ask for more than one tunnel mode"); 166 bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
175 exit(-1);
176 } 167 }
177 p->iph.protocol = IPPROTO_GRE; 168 p->iph.protocol = IPPROTO_GRE;
178 } else if (strcmp(*argv, "sit") == 0 || 169 } else if (strcmp(*argv, "sit") == 0 ||
179 strcmp(*argv, "ipv6/ip") == 0) { 170 strcmp(*argv, "ipv6/ip") == 0) {
180 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { 171 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
181 bb_error_msg("you managed to ask for more than one tunnel mode"); 172 bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
182 exit(-1);
183 } 173 }
184 p->iph.protocol = IPPROTO_IPV6; 174 p->iph.protocol = IPPROTO_IPV6;
185 } else { 175 } else {
186 bb_error_msg("cannot guess tunnel mode"); 176 bb_error_msg_and_die("cannot guess tunnel mode");
187 exit(-1);
188 } 177 }
189 } else if (strcmp(*argv, "key") == 0) { 178 } else if (strcmp(*argv, "key") == 0) {
190 unsigned uval; 179 unsigned uval;
@@ -195,8 +184,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
195 p->i_key = p->o_key = get_addr32(*argv); 184 p->i_key = p->o_key = get_addr32(*argv);
196 else { 185 else {
197 if (get_unsigned(&uval, *argv, 0)<0) { 186 if (get_unsigned(&uval, *argv, 0)<0) {
198 bb_error_msg("invalid value of \"key\""); 187 bb_error_msg_and_die("invalid value of \"key\"");
199 exit(-1);
200 } 188 }
201 p->i_key = p->o_key = htonl(uval); 189 p->i_key = p->o_key = htonl(uval);
202 } 190 }
@@ -208,8 +196,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
208 p->o_key = get_addr32(*argv); 196 p->o_key = get_addr32(*argv);
209 else { 197 else {
210 if (get_unsigned(&uval, *argv, 0)<0) { 198 if (get_unsigned(&uval, *argv, 0)<0) {
211 bb_error_msg("invalid value of \"ikey\""); 199 bb_error_msg_and_die("invalid value of \"ikey\"");
212 exit(-1);
213 } 200 }
214 p->i_key = htonl(uval); 201 p->i_key = htonl(uval);
215 } 202 }
@@ -221,8 +208,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
221 p->o_key = get_addr32(*argv); 208 p->o_key = get_addr32(*argv);
222 else { 209 else {
223 if (get_unsigned(&uval, *argv, 0)<0) { 210 if (get_unsigned(&uval, *argv, 0)<0) {
224 bb_error_msg("invalid value of \"okey\""); 211 bb_error_msg_and_die("invalid value of \"okey\"");
225 exit(-1);
226 } 212 }
227 p->o_key = htonl(uval); 213 p->o_key = htonl(uval);
228 } 214 }
@@ -286,15 +272,15 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
286 struct ip_tunnel_parm old_p; 272 struct ip_tunnel_parm old_p;
287 memset(&old_p, 0, sizeof(old_p)); 273 memset(&old_p, 0, sizeof(old_p));
288 if (do_get_ioctl(*argv, &old_p)) 274 if (do_get_ioctl(*argv, &old_p))
289 return -1; 275 exit(1);
290 *p = old_p; 276 *p = old_p;
291 } 277 }
292 } 278 }
293 count++; 279 count++;
294 argc--; argv++; 280 argc--;
281 argv++;
295 } 282 }
296 283
297
298 if (p->iph.protocol == 0) { 284 if (p->iph.protocol == 0) {
299 if (memcmp(p->name, "gre", 3) == 0) 285 if (memcmp(p->name, "gre", 3) == 0)
300 p->iph.protocol = IPPROTO_GRE; 286 p->iph.protocol = IPPROTO_GRE;
@@ -306,15 +292,12 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
306 292
307 if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { 293 if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
308 if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { 294 if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) {
309 bb_error_msg("keys are not allowed with ipip and sit"); 295 bb_error_msg_and_die("keys are not allowed with ipip and sit");
310 return -1;
311 } 296 }
312 } 297 }
313 298
314 if (medium[0]) { 299 if (medium[0]) {
315 p->link = do_ioctl_get_ifindex(medium); 300 p->link = do_ioctl_get_ifindex(medium);
316 if (p->link == 0)
317 return -1;
318 } 301 }
319 302
320 if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) { 303 if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) {
@@ -326,23 +309,20 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
326 p->o_flags |= GRE_KEY; 309 p->o_flags |= GRE_KEY;
327 } 310 }
328 if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) { 311 if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) {
329 bb_error_msg("broadcast tunnel requires a source address"); 312 bb_error_msg_and_die("broadcast tunnel requires a source address");
330 return -1;
331 } 313 }
332 return 0;
333} 314}
334 315
335 316
317/* Return value becomes exitcode. It's okay to not return at all */
336static int do_add(int cmd, int argc, char **argv) 318static int do_add(int cmd, int argc, char **argv)
337{ 319{
338 struct ip_tunnel_parm p; 320 struct ip_tunnel_parm p;
339 321
340 if (parse_args(argc, argv, cmd, &p) < 0) 322 parse_args(argc, argv, cmd, &p);
341 return -1;
342 323
343 if (p.iph.ttl && p.iph.frag_off == 0) { 324 if (p.iph.ttl && p.iph.frag_off == 0) {
344 bb_error_msg("ttl != 0 and noptmudisc are incompatible"); 325 bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible");
345 return -1;
346 } 326 }
347 327
348 switch (p.iph.protocol) { 328 switch (p.iph.protocol) {
@@ -353,18 +333,16 @@ static int do_add(int cmd, int argc, char **argv)
353 case IPPROTO_IPV6: 333 case IPPROTO_IPV6:
354 return do_add_ioctl(cmd, "sit0", &p); 334 return do_add_ioctl(cmd, "sit0", &p);
355 default: 335 default:
356 bb_error_msg("cannot determine tunnel mode (ipip, gre or sit)"); 336 bb_error_msg_and_die("cannot determine tunnel mode (ipip, gre or sit)");
357 return -1;
358 } 337 }
359 return -1;
360} 338}
361 339
340/* Return value becomes exitcode. It's okay to not return at all */
362static int do_del(int argc, char **argv) 341static int do_del(int argc, char **argv)
363{ 342{
364 struct ip_tunnel_parm p; 343 struct ip_tunnel_parm p;
365 344
366 if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0) 345 parse_args(argc, argv, SIOCDELTUNNEL, &p);
367 return -1;
368 346
369 switch (p.iph.protocol) { 347 switch (p.iph.protocol) {
370 case IPPROTO_IPIP: 348 case IPPROTO_IPIP:
@@ -376,7 +354,6 @@ static int do_del(int argc, char **argv)
376 default: 354 default:
377 return do_del_ioctl(p.name, &p); 355 return do_del_ioctl(p.name, &p);
378 } 356 }
379 return -1;
380} 357}
381 358
382static void print_tunnel(struct ip_tunnel_parm *p) 359static void print_tunnel(struct ip_tunnel_parm *p)
@@ -399,8 +376,10 @@ static void print_tunnel(struct ip_tunnel_parm *p)
399 p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any"); 376 p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any");
400 if (p->link) { 377 if (p->link) {
401 char *n = do_ioctl_get_ifname(p->link); 378 char *n = do_ioctl_get_ifname(p->link);
402 if (n) 379 if (n) {
403 printf(" dev %s ", n); 380 printf(" dev %s ", n);
381 free(n);
382 }
404 } 383 }
405 if (p->iph.ttl) 384 if (p->iph.ttl)
406 printf(" ttl %d ", p->iph.ttl); 385 printf(" ttl %d ", p->iph.ttl);
@@ -428,16 +407,16 @@ static void print_tunnel(struct ip_tunnel_parm *p)
428 } 407 }
429 408
430 if (p->i_flags & GRE_SEQ) 409 if (p->i_flags & GRE_SEQ)
431 printf("%s Drop packets out of sequence.\n", _SL_); 410 printf("%c Drop packets out of sequence.\n", _SL_);
432 if (p->i_flags & GRE_CSUM) 411 if (p->i_flags & GRE_CSUM)
433 printf("%s Checksum in received packet is required.", _SL_); 412 printf("%c Checksum in received packet is required.", _SL_);
434 if (p->o_flags & GRE_SEQ) 413 if (p->o_flags & GRE_SEQ)
435 printf("%s Sequence packets on output.", _SL_); 414 printf("%c Sequence packets on output.", _SL_);
436 if (p->o_flags & GRE_CSUM) 415 if (p->o_flags & GRE_CSUM)
437 printf("%s Checksum output packets.", _SL_); 416 printf("%c Checksum output packets.", _SL_);
438} 417}
439 418
440static int do_tunnels_list(struct ip_tunnel_parm *p) 419static void do_tunnels_list(struct ip_tunnel_parm *p)
441{ 420{
442 char name[IFNAMSIZ]; 421 char name[IFNAMSIZ];
443 unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, 422 unsigned long rx_bytes, rx_packets, rx_errs, rx_drops,
@@ -450,8 +429,8 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
450 FILE *fp = fopen("/proc/net/dev", "r"); 429 FILE *fp = fopen("/proc/net/dev", "r");
451 430
452 if (fp == NULL) { 431 if (fp == NULL) {
453 perror("fopen"); 432 bb_perror_msg("fopen");
454 return -1; 433 return;
455 } 434 }
456 435
457 fgets(buf, sizeof(buf), fp); 436 fgets(buf, sizeof(buf), fp);
@@ -465,7 +444,7 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
465 if (ptr == NULL || 444 if (ptr == NULL ||
466 (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { 445 (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
467 bb_error_msg("wrong format of /proc/net/dev. Sorry"); 446 bb_error_msg("wrong format of /proc/net/dev. Sorry");
468 return -1; 447 return;
469 } 448 }
470 if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", 449 if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
471 &rx_bytes, &rx_packets, &rx_errs, &rx_drops, 450 &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
@@ -477,7 +456,7 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
477 continue; 456 continue;
478 type = do_ioctl_get_iftype(name); 457 type = do_ioctl_get_iftype(name);
479 if (type == -1) { 458 if (type == -1) {
480 bb_error_msg("failed to get type of [%s]", name); 459 bb_error_msg("cannot get type of [%s]", name);
481 continue; 460 continue;
482 } 461 }
483 if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT) 462 if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT)
@@ -494,16 +473,15 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
494 print_tunnel(&p1); 473 print_tunnel(&p1);
495 puts(""); 474 puts("");
496 } 475 }
497 return 0;
498} 476}
499 477
478/* Return value becomes exitcode. It's okay to not return at all */
500static int do_show(int argc, char **argv) 479static int do_show(int argc, char **argv)
501{ 480{
502 int err; 481 int err;
503 struct ip_tunnel_parm p; 482 struct ip_tunnel_parm p;
504 483
505 if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0) 484 parse_args(argc, argv, SIOCGETTUNNEL, &p);
506 return -1;
507 485
508 switch (p.iph.protocol) { 486 switch (p.iph.protocol) {
509 case IPPROTO_IPIP: 487 case IPPROTO_IPIP:
@@ -527,6 +505,7 @@ static int do_show(int argc, char **argv)
527 return 0; 505 return 0;
528} 506}
529 507
508/* Return value becomes exitcode. It's okay to not return at all */
530int do_iptunnel(int argc, char **argv) 509int do_iptunnel(int argc, char **argv)
531{ 510{
532 if (argc > 0) { 511 if (argc > 0) {
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c
index f429763eb..a8fcd7f88 100644
--- a/networking/libiproute/ll_map.c
+++ b/networking/libiproute/ll_map.c
@@ -54,7 +54,7 @@ int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
54 54
55 h = ifi->ifi_index&0xF; 55 h = ifi->ifi_index&0xF;
56 56
57 for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next) 57 for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
58 if (im->index == ifi->ifi_index) 58 if (im->index == ifi->ifi_index)
59 break; 59 break;
60 60
@@ -87,7 +87,7 @@ const char *ll_idx_n2a(int idx, char *buf)
87 87
88 if (idx == 0) 88 if (idx == 0)
89 return "*"; 89 return "*";
90 for (im = idxmap[idx&0xF]; im; im = im->next) 90 for (im = idxmap[idx & 0xF]; im; im = im->next)
91 if (im->index == idx) 91 if (im->index == idx)
92 return im->name; 92 return im->name;
93 snprintf(buf, 16, "if%d", idx); 93 snprintf(buf, 16, "if%d", idx);
@@ -108,7 +108,7 @@ int ll_index_to_type(int idx)
108 108
109 if (idx == 0) 109 if (idx == 0)
110 return -1; 110 return -1;
111 for (im = idxmap[idx&0xF]; im; im = im->next) 111 for (im = idxmap[idx & 0xF]; im; im = im->next)
112 if (im->index == idx) 112 if (im->index == idx)
113 return im->type; 113 return im->type;
114 return -1; 114 return -1;
@@ -121,16 +121,18 @@ unsigned ll_index_to_flags(int idx)
121 if (idx == 0) 121 if (idx == 0)
122 return 0; 122 return 0;
123 123
124 for (im = idxmap[idx&0xF]; im; im = im->next) 124 for (im = idxmap[idx & 0xF]; im; im = im->next)
125 if (im->index == idx) 125 if (im->index == idx)
126 return im->flags; 126 return im->flags;
127 return 0; 127 return 0;
128} 128}
129 129
130// TODO: caching is not warranted - no users which repeatedly call it
130int ll_name_to_index(char *name) 131int ll_name_to_index(char *name)
131{ 132{
132 static char ncache[16]; 133 static char ncache[16];
133 static int icache; 134 static int icache;
135
134 struct idxmap *im; 136 struct idxmap *im;
135 int sock_fd; 137 int sock_fd;
136 int i; 138 int i;
@@ -139,7 +141,7 @@ int ll_name_to_index(char *name)
139 return 0; 141 return 0;
140 if (icache && strcmp(name, ncache) == 0) 142 if (icache && strcmp(name, ncache) == 0)
141 return icache; 143 return icache;
142 for (i=0; i<16; i++) { 144 for (i = 0; i < 16; i++) {
143 for (im = idxmap[i]; im; im = im->next) { 145 for (im = idxmap[i]; im; im = im->next) {
144 if (strcmp(im->name, name) == 0) { 146 if (strcmp(im->name, name) == 0) {
145 icache = im->index; 147 icache = im->index;
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c
index 591c8933a..601e45bb4 100644
--- a/networking/libiproute/utils.c
+++ b/networking/libiproute/utils.c
@@ -13,9 +13,6 @@
13 13
14#include "libbb.h" 14#include "libbb.h"
15 15
16#include <string.h>
17#include <unistd.h>
18
19#include "utils.h" 16#include "utils.h"
20#include "inet_common.h" 17#include "inet_common.h"
21 18
@@ -197,7 +194,7 @@ int get_prefix_1(inet_prefix * dst, char *arg, int family)
197 dst->bitlen = plen; 194 dst->bitlen = plen;
198 } 195 }
199 } 196 }
200 done: 197 done:
201 if (slash) 198 if (slash)
202 *slash = '/'; 199 *slash = '/';
203 return err; 200 return err;
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h
index 556541f79..27afb32ac 100644
--- a/networking/libiproute/utils.h
+++ b/networking/libiproute/utils.h
@@ -9,13 +9,12 @@
9#include "rtm_map.h" 9#include "rtm_map.h"
10 10
11extern int preferred_family; 11extern int preferred_family;
12extern int show_stats; 12extern smallint show_stats; /* UNUSED */
13extern int show_details; 13extern smallint show_details; /* UNUSED */
14extern int show_raw; 14extern smallint show_raw; /* UNUSED */
15extern int resolve_hosts; 15extern smallint resolve_hosts; /* UNUSED */
16extern int oneline; 16extern smallint oneline;
17//FIXME! Appears in two .h files! 17extern char _SL_;
18extern const char * _SL_;
19 18
20#ifndef IPPROTO_ESP 19#ifndef IPPROTO_ESP
21#define IPPROTO_ESP 50 20#define IPPROTO_ESP 50
@@ -80,7 +79,7 @@ void invarg(const char *, const char *) ATTRIBUTE_NORETURN;
80void duparg(const char *, const char *) ATTRIBUTE_NORETURN; 79void duparg(const char *, const char *) ATTRIBUTE_NORETURN;
81void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; 80void duparg2(const char *, const char *) ATTRIBUTE_NORETURN;
82int matches(const char *arg, const char *pattern); 81int matches(const char *arg, const char *pattern);
83extern int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); 82int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits);
84 83
85const char *dnet_ntop(int af, const void *addr, char *str, size_t len); 84const char *dnet_ntop(int af, const void *addr, char *str, size_t len);
86int dnet_pton(int af, const char *src, void *addr); 85int dnet_pton(int af, const char *src, void *addr);