aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-19 12:53:35 +0100
committerRon Yorston <rmy@pobox.com>2015-10-19 12:53:35 +0100
commit8afe8ee83a274925340473fa4d0a984bdcbee740 (patch)
treeb78ed448cb6a55ba7d0ef8141a9f68b55b8acf11 /networking
parentcaab029609633220c417dc0aaa9025fd4b7a169c (diff)
parent3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c (diff)
downloadbusybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.tar.gz
busybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.tar.bz2
busybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src13
-rw-r--r--networking/brctl.c8
-rw-r--r--networking/inetd.c4
-rw-r--r--networking/ip.c19
-rw-r--r--networking/libiproute/Kbuild.src8
-rw-r--r--networking/libiproute/ip_common.h2
-rw-r--r--networking/libiproute/ip_parse_common_args.c2
-rw-r--r--networking/libiproute/ipaddress.c28
-rw-r--r--networking/libiproute/iplink.c27
-rw-r--r--networking/libiproute/ipneigh.c353
-rw-r--r--networking/libiproute/iproute.c72
-rw-r--r--networking/libiproute/iprule.c31
-rw-r--r--networking/libiproute/iptunnel.c34
-rw-r--r--networking/libiproute/utils.c48
-rw-r--r--networking/libiproute/utils.h12
-rw-r--r--networking/nbd-client.c5
-rw-r--r--networking/slattach.c6
-rw-r--r--networking/tc.c12
-rw-r--r--networking/telnet.c4
19 files changed, 529 insertions, 159 deletions
diff --git a/networking/Config.src b/networking/Config.src
index 43ccbf385..8c7417f86 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -554,6 +554,13 @@ config FEATURE_IP_RULE
554 help 554 help
555 Add support for rule commands to "ip". 555 Add support for rule commands to "ip".
556 556
557config FEATURE_IP_NEIGH
558 bool "ip neighbor"
559 default y
560 depends on IP
561 help
562 Add support for neighbor commands to "ip".
563
557config FEATURE_IP_SHORT_FORMS 564config FEATURE_IP_SHORT_FORMS
558 bool "Support short forms of ip commands" 565 bool "Support short forms of ip commands"
559 default y 566 default y
@@ -565,6 +572,7 @@ config FEATURE_IP_SHORT_FORMS
565 ip route -> iproute 572 ip route -> iproute
566 ip tunnel -> iptunnel 573 ip tunnel -> iptunnel
567 ip rule -> iprule 574 ip rule -> iprule
575 ip neigh -> ipneigh
568 576
569 Say N unless you desparately need the short form of the ip 577 Say N unless you desparately need the short form of the ip
570 object commands. 578 object commands.
@@ -604,6 +612,11 @@ config IPRULE
604 default y 612 default y
605 depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_RULE 613 depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_RULE
606 614
615config IPNEIGH
616 bool
617 default y
618 depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_NEIGH
619
607config IPCALC 620config IPCALC
608 bool "ipcalc" 621 bool "ipcalc"
609 default y 622 default y
diff --git a/networking/brctl.c b/networking/brctl.c
index c01a86998..b7320966a 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -128,7 +128,7 @@ static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv,
128# else 128# else
129 if (sscanf(time_str, "%lf", &secs) != 1) 129 if (sscanf(time_str, "%lf", &secs) != 1)
130# endif 130# endif
131 bb_error_msg_and_die(bb_msg_invalid_arg, time_str, "timespec"); 131 bb_error_msg_and_die(bb_msg_invalid_arg_to, time_str, "timespec");
132 tv->tv_sec = secs; 132 tv->tv_sec = secs;
133 tv->tv_usec = 1000000 * (secs - tv->tv_sec); 133 tv->tv_usec = 1000000 * (secs - tv->tv_sec);
134} 134}
@@ -205,7 +205,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
205 205
206 key = index_in_strings(keywords, *argv); 206 key = index_in_strings(keywords, *argv);
207 if (key == -1) /* no match found in keywords array, bail out. */ 207 if (key == -1) /* no match found in keywords array, bail out. */
208 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 208 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
209 argv++; 209 argv++;
210 fd = xsocket(AF_INET, SOCK_STREAM, 0); 210 fd = xsocket(AF_INET, SOCK_STREAM, 0);
211 211
@@ -299,7 +299,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
299 "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */ 299 "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */
300 int onoff = index_in_strings(no_yes, *argv); 300 int onoff = index_in_strings(no_yes, *argv);
301 if (onoff < 0) 301 if (onoff < 0)
302 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 302 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
303 onoff = (unsigned)onoff / 4; 303 onoff = (unsigned)onoff / 4;
304 arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0); 304 arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0);
305 goto fire; 305 goto fire;
@@ -332,7 +332,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
332 332
333 port = if_nametoindex(*argv++); 333 port = if_nametoindex(*argv++);
334 if (!port) 334 if (!port)
335 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); 335 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, "port");
336 memset(ifidx, 0, sizeof ifidx); 336 memset(ifidx, 0, sizeof ifidx);
337 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, 337 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx,
338 MAX_PORTS); 338 MAX_PORTS);
diff --git a/networking/inetd.c b/networking/inetd.c
index dce5a0885..243165a07 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -329,9 +329,6 @@ struct globals {
329} FIX_ALIASING; 329} FIX_ALIASING;
330#define G (*(struct globals*)&bb_common_bufsiz1) 330#define G (*(struct globals*)&bb_common_bufsiz1)
331enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; 331enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) };
332struct BUG_G_too_big {
333 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
334};
335#define rlim_ofile_cur (G.rlim_ofile_cur ) 332#define rlim_ofile_cur (G.rlim_ofile_cur )
336#define rlim_ofile (G.rlim_ofile ) 333#define rlim_ofile (G.rlim_ofile )
337#define serv_list (G.serv_list ) 334#define serv_list (G.serv_list )
@@ -352,6 +349,7 @@ struct BUG_G_too_big {
352#define allsock (G.allsock ) 349#define allsock (G.allsock )
353#define line (G.line ) 350#define line (G.line )
354#define INIT_G() do { \ 351#define INIT_G() do { \
352 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
355 rlim_ofile_cur = OPEN_MAX; \ 353 rlim_ofile_cur = OPEN_MAX; \
356 global_queuelen = 128; \ 354 global_queuelen = 128; \
357 config_filename = "/etc/inetd.conf"; \ 355 config_filename = "/etc/inetd.conf"; \
diff --git a/networking/ip.c b/networking/ip.c
index d35345c36..ddfe74e9c 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -16,6 +16,7 @@
16//usage: IF_FEATURE_IP_ROUTE("route | ") 16//usage: IF_FEATURE_IP_ROUTE("route | ")
17//usage: IF_FEATURE_IP_LINK("link | ") 17//usage: IF_FEATURE_IP_LINK("link | ")
18//usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 18//usage: IF_FEATURE_IP_TUNNEL("tunnel | ")
19//usage: IF_FEATURE_IP_NEIGH("neigh | ")
19//usage: IF_FEATURE_IP_RULE("rule") 20//usage: IF_FEATURE_IP_RULE("rule")
20//usage: "} {COMMAND}" 21//usage: "} {COMMAND}"
21//usage:#define ip_full_usage "\n\n" 22//usage:#define ip_full_usage "\n\n"
@@ -25,6 +26,7 @@
25//usage: IF_FEATURE_IP_ROUTE("route | ") 26//usage: IF_FEATURE_IP_ROUTE("route | ")
26//usage: IF_FEATURE_IP_LINK("link | ") 27//usage: IF_FEATURE_IP_LINK("link | ")
27//usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 28//usage: IF_FEATURE_IP_TUNNEL("tunnel | ")
29//usage: IF_FEATURE_IP_NEIGH("neigh | ")
28//usage: IF_FEATURE_IP_RULE("rule") 30//usage: IF_FEATURE_IP_RULE("rule")
29//usage: "}\n" 31//usage: "}\n"
30//usage: "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }" 32//usage: "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }"
@@ -80,6 +82,11 @@
80//usage: " [mode { ipip | gre | sit }] [remote ADDR] [local ADDR]\n" 82//usage: " [mode { ipip | gre | sit }] [remote ADDR] [local ADDR]\n"
81//usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" 83//usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n"
82//usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" 84//usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]"
85//usage:
86//usage:#define ipneigh_trivial_usage
87//usage: "{ show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]"
88//usage:#define ipneigh_full_usage "\n\n"
89//usage: "ipneigh { show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]"
83 90
84#include "libbb.h" 91#include "libbb.h"
85 92
@@ -90,7 +97,8 @@
90 || ENABLE_FEATURE_IP_ROUTE \ 97 || ENABLE_FEATURE_IP_ROUTE \
91 || ENABLE_FEATURE_IP_LINK \ 98 || ENABLE_FEATURE_IP_LINK \
92 || ENABLE_FEATURE_IP_TUNNEL \ 99 || ENABLE_FEATURE_IP_TUNNEL \
93 || ENABLE_FEATURE_IP_RULE 100 || ENABLE_FEATURE_IP_RULE \
101 || ENABLE_FEATURE_IP_NEIGH
94 102
95static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) 103static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM)
96{ 104{
@@ -140,6 +148,13 @@ int iptunnel_main(int argc UNUSED_PARAM, char **argv)
140 return ip_do(do_iptunnel, argv); 148 return ip_do(do_iptunnel, argv);
141} 149}
142#endif 150#endif
151#if ENABLE_FEATURE_IP_NEIGH
152int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
153int ipneigh_main(int argc UNUSED_PARAM, char **argv)
154{
155 return ip_do(do_ipneigh, argv);
156}
157#endif
143 158
144 159
145int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 160int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -153,6 +168,7 @@ int ip_main(int argc UNUSED_PARAM, char **argv)
153 IF_FEATURE_IP_TUNNEL("tunnel\0") 168 IF_FEATURE_IP_TUNNEL("tunnel\0")
154 IF_FEATURE_IP_TUNNEL("tunl\0") 169 IF_FEATURE_IP_TUNNEL("tunl\0")
155 IF_FEATURE_IP_RULE("rule\0") 170 IF_FEATURE_IP_RULE("rule\0")
171 IF_FEATURE_IP_NEIGH("neigh\0")
156 ; 172 ;
157 static const ip_func_ptr_t ip_func_ptrs[] = { 173 static const ip_func_ptr_t ip_func_ptrs[] = {
158 ip_print_help, 174 ip_print_help,
@@ -163,6 +179,7 @@ int ip_main(int argc UNUSED_PARAM, char **argv)
163 IF_FEATURE_IP_TUNNEL(do_iptunnel,) 179 IF_FEATURE_IP_TUNNEL(do_iptunnel,)
164 IF_FEATURE_IP_TUNNEL(do_iptunnel,) 180 IF_FEATURE_IP_TUNNEL(do_iptunnel,)
165 IF_FEATURE_IP_RULE(do_iprule,) 181 IF_FEATURE_IP_RULE(do_iprule,)
182 IF_FEATURE_IP_NEIGH(do_ipneigh,)
166 }; 183 };
167 ip_func_ptr_t ip_func; 184 ip_func_ptr_t ip_func;
168 int key; 185 int key;
diff --git a/networking/libiproute/Kbuild.src b/networking/libiproute/Kbuild.src
index 7c78f3c6a..c20e2fee8 100644
--- a/networking/libiproute/Kbuild.src
+++ b/networking/libiproute/Kbuild.src
@@ -64,3 +64,11 @@ lib-$(CONFIG_FEATURE_IP_RULE) += \
64 iprule.o \ 64 iprule.o \
65 rt_names.o \ 65 rt_names.o \
66 utils.o 66 utils.o
67
68lib-$(CONFIG_FEATURE_IP_NEIGH) += \
69 ip_parse_common_args.o \
70 ipneigh.o \
71 libnetlink.o \
72 ll_map.o \
73 rt_names.o \
74 utils.o
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h
index 30c7e595b..40171bed9 100644
--- a/networking/libiproute/ip_common.h
+++ b/networking/libiproute/ip_common.h
@@ -24,7 +24,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush);
24int FAST_FUNC do_ipaddr(char **argv); 24int FAST_FUNC do_ipaddr(char **argv);
25int FAST_FUNC do_iproute(char **argv); 25int FAST_FUNC do_iproute(char **argv);
26int FAST_FUNC do_iprule(char **argv); 26int FAST_FUNC do_iprule(char **argv);
27//int FAST_FUNC do_ipneigh(char **argv); 27int FAST_FUNC do_ipneigh(char **argv);
28int FAST_FUNC do_iptunnel(char **argv); 28int FAST_FUNC do_iptunnel(char **argv);
29int FAST_FUNC do_iplink(char **argv); 29int FAST_FUNC do_iplink(char **argv);
30//int FAST_FUNC do_ipmonitor(char **argv); 30//int FAST_FUNC do_ipmonitor(char **argv);
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index 59c759b23..1a298f738 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -67,7 +67,7 @@ char** FAST_FUNC ip_parse_common_args(char **argv)
67 bb_show_usage(); 67 bb_show_usage();
68 arg = index_in_strings(families, *argv); 68 arg = index_in_strings(families, *argv);
69 if (arg < 0) 69 if (arg < 0)
70 invarg(*argv, "protocol family"); 70 invarg_1_to_2(*argv, "family");
71 /* now arg == 0, 1 or 2 */ 71 /* now arg == 0, 1 or 2 */
72 } else { 72 } else {
73 arg -= ARG_IPv4; 73 arg -= ARG_IPv4;
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 8845cab91..5c975d8c5 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -214,8 +214,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
214{ 214{
215 struct ifaddrmsg *ifa = NLMSG_DATA(n); 215 struct ifaddrmsg *ifa = NLMSG_DATA(n);
216 int len = n->nlmsg_len; 216 int len = n->nlmsg_len;
217 struct rtattr * rta_tb[IFA_MAX+1]; 217 struct rtattr *rta_tb[IFA_MAX+1];
218 char abuf[256];
219 218
220 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 219 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
221 return 0; 220 return 0;
@@ -291,9 +290,9 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
291 printf(" family %d ", ifa->ifa_family); 290 printf(" family %d ", ifa->ifa_family);
292 291
293 if (rta_tb[IFA_LOCAL]) { 292 if (rta_tb[IFA_LOCAL]) {
294 fputs(rt_addr_n2a(ifa->ifa_family, 293 fputs(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])),
295 RTA_DATA(rta_tb[IFA_LOCAL]), 294 stdout
296 abuf, sizeof(abuf)), stdout); 295 );
297 296
298 if (rta_tb[IFA_ADDRESS] == NULL 297 if (rta_tb[IFA_ADDRESS] == NULL
299 || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0 298 || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
@@ -301,25 +300,22 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
301 printf("/%d ", ifa->ifa_prefixlen); 300 printf("/%d ", ifa->ifa_prefixlen);
302 } else { 301 } else {
303 printf(" peer %s/%d ", 302 printf(" peer %s/%d ",
304 rt_addr_n2a(ifa->ifa_family, 303 rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_ADDRESS])),
305 RTA_DATA(rta_tb[IFA_ADDRESS]), 304 ifa->ifa_prefixlen
306 abuf, sizeof(abuf)), 305 );
307 ifa->ifa_prefixlen);
308 } 306 }
309 } 307 }
310 308
311 if (rta_tb[IFA_BROADCAST]) { 309 if (rta_tb[IFA_BROADCAST]) {
312 printf("brd %s ", 310 printf("brd %s ",
313 rt_addr_n2a(ifa->ifa_family, 311 rt_addr_n2a(ifa->ifa_family,
314 RTA_DATA(rta_tb[IFA_BROADCAST]), 312 RTA_DATA(rta_tb[IFA_BROADCAST]))
315 abuf, sizeof(abuf))
316 ); 313 );
317 } 314 }
318 if (rta_tb[IFA_ANYCAST]) { 315 if (rta_tb[IFA_ANYCAST]) {
319 printf("any %s ", 316 printf("any %s ",
320 rt_addr_n2a(ifa->ifa_family, 317 rt_addr_n2a(ifa->ifa_family,
321 RTA_DATA(rta_tb[IFA_ANYCAST]), 318 RTA_DATA(rta_tb[IFA_ANYCAST]))
322 abuf, sizeof(abuf))
323 ); 319 );
324 } 320 }
325 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); 321 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope));
@@ -455,7 +451,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
455 G_filter.scopemask = -1; 451 G_filter.scopemask = -1;
456 if (rtnl_rtscope_a2n(&scope, *argv)) { 452 if (rtnl_rtscope_a2n(&scope, *argv)) {
457 if (strcmp(*argv, "all") != 0) { 453 if (strcmp(*argv, "all") != 0) {
458 invarg(*argv, "scope"); 454 invarg_1_to_2(*argv, "scope");
459 } 455 }
460 scope = RT_SCOPE_NOWHERE; 456 scope = RT_SCOPE_NOWHERE;
461 G_filter.scopemask = 0; 457 G_filter.scopemask = 0;
@@ -669,7 +665,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
669 } else if (arg == 5) { /* scope */ 665 } else if (arg == 5) { /* scope */
670 uint32_t scope = 0; 666 uint32_t scope = 0;
671 if (rtnl_rtscope_a2n(&scope, *argv)) { 667 if (rtnl_rtscope_a2n(&scope, *argv)) {
672 invarg(*argv, "scope"); 668 invarg_1_to_2(*argv, "scope");
673 } 669 }
674 req.ifa.ifa_scope = scope; 670 req.ifa.ifa_scope = scope;
675 scoped = 1; 671 scoped = 1;
@@ -751,7 +747,7 @@ int FAST_FUNC do_ipaddr(char **argv)
751 if (*argv) { 747 if (*argv) {
752 cmd = index_in_substrings(commands, *argv); 748 cmd = index_in_substrings(commands, *argv);
753 if (cmd < 0) 749 if (cmd < 0)
754 invarg(*argv, applet_name); 750 invarg_1_to_2(*argv, applet_name);
755 argv++; 751 argv++;
756 if (cmd <= 4) { 752 if (cmd <= 4) {
757 return ipaddr_modify( 753 return ipaddr_modify(
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 5c27c2de3..ae3ef0ceb 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -349,7 +349,7 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size)
349 while (*argv) { 349 while (*argv) {
350 arg = index_in_substrings(keywords, *argv); 350 arg = index_in_substrings(keywords, *argv);
351 if (arg < 0) 351 if (arg < 0)
352 invarg(*argv, "type vlan"); 352 invarg_1_to_2(*argv, "type vlan");
353 353
354 NEXT_ARG(); 354 NEXT_ARG();
355 if (arg == ARG_id) { 355 if (arg == ARG_id) {
@@ -512,7 +512,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
512 if (name_str) { 512 if (name_str) {
513 const size_t name_len = strlen(name_str) + 1; 513 const size_t name_len = strlen(name_str) + 1;
514 if (name_len < 2 || name_len > IFNAMSIZ) 514 if (name_len < 2 || name_len > IFNAMSIZ)
515 invarg(name_str, "name"); 515 invarg_1_to_2(name_str, "name");
516 addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len); 516 addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
517 } 517 }
518 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 518 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
@@ -536,14 +536,14 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
536 if (qlen != -1) 536 if (qlen != -1)
537 duparg("txqueuelen", *argv); 537 duparg("txqueuelen", *argv);
538 if (get_integer(&qlen, *argv, 0)) 538 if (get_integer(&qlen, *argv, 0))
539 invarg("Invalid \"txqueuelen\" value\n", *argv); 539 invarg_1_to_2(*argv, "txqueuelen");
540 addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); 540 addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
541 } else if (strcmp(*argv, "mtu") == 0) { 541 } else if (strcmp(*argv, "mtu") == 0) {
542 NEXT_ARG(); 542 NEXT_ARG();
543 if (mtu != -1) 543 if (mtu != -1)
544 duparg("mtu", *argv); 544 duparg("mtu", *argv);
545 if (get_integer(&mtu, *argv, 0)) 545 if (get_integer(&mtu, *argv, 0))
546 invarg("Invalid \"mtu\" value\n", *argv); 546 invarg_1_to_2(*argv, "mtu");
547 addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); 547 addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
548 } else if (strcmp(*argv, "netns") == 0) { 548 } else if (strcmp(*argv, "netns") == 0) {
549 NEXT_ARG(); 549 NEXT_ARG();
@@ -554,7 +554,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
554 else if (get_integer(&netns, *argv, 0) == 0) 554 else if (get_integer(&netns, *argv, 0) == 0)
555 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); 555 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
556 else 556 else
557 invarg("Invalid \"netns\" value\n", *argv); 557 invarg_1_to_2(*argv, "netns");
558 } else if (strcmp(*argv, "multicast") == 0) { 558 } else if (strcmp(*argv, "multicast") == 0) {
559 NEXT_ARG(); 559 NEXT_ARG();
560 req->i.ifi_change |= IFF_MULTICAST; 560 req->i.ifi_change |= IFF_MULTICAST;
@@ -604,7 +604,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
604 struct rtattr *vflist; 604 struct rtattr *vflist;
605 NEXT_ARG(); 605 NEXT_ARG();
606 if (get_integer(&vf, *argv, 0)) { 606 if (get_integer(&vf, *argv, 0)) {
607 invarg("Invalid \"vf\" value\n", *argv); 607 invarg_1_to_2(*argv, "vf");
608 } 608 }
609 vflist = addattr_nest(&req->n, sizeof(*req), 609 vflist = addattr_nest(&req->n, sizeof(*req),
610 IFLA_VFINFO_LIST); 610 IFLA_VFINFO_LIST);
@@ -617,7 +617,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
617 NEXT_ARG(); 617 NEXT_ARG();
618 ifindex = ll_name_to_index(*argv); 618 ifindex = ll_name_to_index(*argv);
619 if (!ifindex) 619 if (!ifindex)
620 invarg("Device does not exist\n", *argv); 620 invarg_1_to_2(*argv, "master");
621 addattr_l(&req->n, sizeof(*req), IFLA_MASTER, 621 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
622 &ifindex, 4); 622 &ifindex, 4);
623 } else if (matches(*argv, "nomaster") == 0) { 623 } else if (matches(*argv, "nomaster") == 0) {
@@ -644,28 +644,27 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
644 if (*group != -1) 644 if (*group != -1)
645 duparg("group", *argv); 645 duparg("group", *argv);
646 if (rtnl_group_a2n(group, *argv)) 646 if (rtnl_group_a2n(group, *argv))
647 invarg("Invalid \"group\" value\n", *argv); 647 invarg_1_to_2(*argv, "group");
648 } else if (strcmp(*argv, "mode") == 0) { 648 } else if (strcmp(*argv, "mode") == 0) {
649 int mode; 649 int mode;
650 NEXT_ARG(); 650 NEXT_ARG();
651 mode = get_link_mode(*argv); 651 mode = get_link_mode(*argv);
652 if (mode < 0) 652 if (mode < 0)
653 invarg("Invalid link mode\n", *argv); 653 invarg_1_to_2(*argv, "mode");
654 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); 654 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
655 } else if (strcmp(*argv, "state") == 0) { 655 } else if (strcmp(*argv, "state") == 0) {
656 int state; 656 int state;
657 NEXT_ARG(); 657 NEXT_ARG();
658 state = get_operstate(*argv); 658 state = get_operstate(*argv);
659 if (state < 0) 659 if (state < 0)
660 invarg("Invalid operstate\n", *argv); 660 invarg_1_to_2(*argv, "state");
661
662 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); 661 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
663 } else if (matches(*argv, "numtxqueues") == 0) { 662 } else if (matches(*argv, "numtxqueues") == 0) {
664 NEXT_ARG(); 663 NEXT_ARG();
665 if (numtxqueues != -1) 664 if (numtxqueues != -1)
666 duparg("numtxqueues", *argv); 665 duparg("numtxqueues", *argv);
667 if (get_integer(&numtxqueues, *argv, 0)) 666 if (get_integer(&numtxqueues, *argv, 0))
668 invarg("Invalid \"numtxqueues\" value\n", *argv); 667 invarg_1_to_2(*argv, "numtxqueues");
669 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, 668 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
670 &numtxqueues, 4); 669 &numtxqueues, 4);
671 } else if (matches(*argv, "numrxqueues") == 0) { 670 } else if (matches(*argv, "numrxqueues") == 0) {
@@ -673,7 +672,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
673 if (numrxqueues != -1) 672 if (numrxqueues != -1)
674 duparg("numrxqueues", *argv); 673 duparg("numrxqueues", *argv);
675 if (get_integer(&numrxqueues, *argv, 0)) 674 if (get_integer(&numrxqueues, *argv, 0))
676 invarg("Invalid \"numrxqueues\" value\n", *argv); 675 invarg_1_to_2(*argv, "numrxqueues");
677 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, 676 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
678 &numrxqueues, 4); 677 &numrxqueues, 4);
679 } 678 }
@@ -687,7 +686,7 @@ int FAST_FUNC do_iplink(char **argv)
687 if (*argv) { 686 if (*argv) {
688 int key = index_in_substrings(keywords, *argv); 687 int key = index_in_substrings(keywords, *argv);
689 if (key < 0) /* invalid argument */ 688 if (key < 0) /* invalid argument */
690 invarg(*argv, applet_name); 689 invarg_1_to_2(*argv, applet_name);
691 argv++; 690 argv++;
692 if (key <= 1) /* add/delete */ 691 if (key <= 1) /* add/delete */
693 return do_add_or_delete(argv, key ? RTM_DELLINK : RTM_NEWLINK); 692 return do_add_or_delete(argv, key ? RTM_DELLINK : RTM_NEWLINK);
diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c
new file mode 100644
index 000000000..179505c2d
--- /dev/null
+++ b/networking/libiproute/ipneigh.c
@@ -0,0 +1,353 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
4 *
5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
6 *
7 * Ported to Busybox by: Curt Brune <curt@cumulusnetworks.com>
8 */
9
10#include "ip_common.h" /* #include "libbb.h" is inside */
11#include "rt_names.h"
12#include "utils.h"
13#include <linux/neighbour.h>
14#include <net/if_arp.h>
15
16//static int xshow_stats = 3;
17enum { xshow_stats = 3 };
18
19static inline uint32_t rta_getattr_u32(const struct rtattr *rta)
20{
21 return *(uint32_t *)RTA_DATA(rta);
22}
23
24#ifndef RTAX_RTTVAR
25#define RTAX_RTTVAR RTAX_HOPS
26#endif
27
28
29struct filter_t {
30 int family;
31 int index;
32 int state;
33 int unused_only;
34 inet_prefix pfx;
35 int flushed;
36 char *flushb;
37 int flushp;
38 int flushe;
39 struct rtnl_handle *rth;
40} FIX_ALIASING;
41typedef struct filter_t filter_t;
42
43#define G_filter (*(filter_t*)&bb_common_bufsiz1)
44
45static int flush_update(void)
46{
47 if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
48 bb_perror_msg("can't send flush request");
49 return -1;
50 }
51 G_filter.flushp = 0;
52 return 0;
53}
54
55static unsigned nud_state_a2n(char *arg)
56{
57 static const char keywords[] ALIGN1 =
58 /* "ip neigh show/flush" parameters: */
59 "permanent\0" "reachable\0" "noarp\0" "none\0"
60 "stale\0" "incomplete\0" "delay\0" "probe\0"
61 "failed\0"
62 ;
63 static uint8_t nuds[] = {
64 NUD_PERMANENT,NUD_REACHABLE, NUD_NOARP,NUD_NONE,
65 NUD_STALE, NUD_INCOMPLETE,NUD_DELAY,NUD_PROBE,
66 NUD_FAILED
67 };
68 int id;
69
70 BUILD_BUG_ON(
71 (NUD_PERMANENT|NUD_REACHABLE| NUD_NOARP|NUD_NONE|
72 NUD_STALE| NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE|
73 NUD_FAILED) > 0xff
74 );
75
76 id = index_in_substrings(keywords, arg);
77 if (id < 0)
78 bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, "nud state");
79 return nuds[id];
80}
81
82#ifndef NDA_RTA
83#define NDA_RTA(r) \
84 ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
85#endif
86
87
88static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM,
89 struct nlmsghdr *n, void *arg UNUSED_PARAM)
90{
91 struct ndmsg *r = NLMSG_DATA(n);
92 int len = n->nlmsg_len;
93 struct rtattr *tb[NDA_MAX+1];
94
95 if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
96 bb_error_msg_and_die("not RTM_NEWNEIGH: %08x %08x %08x",
97 n->nlmsg_len, n->nlmsg_type,
98 n->nlmsg_flags);
99 }
100 len -= NLMSG_LENGTH(sizeof(*r));
101 if (len < 0) {
102 bb_error_msg_and_die("BUG: wrong nlmsg len %d", len);
103 }
104
105 if (G_filter.flushb && n->nlmsg_type != RTM_NEWNEIGH)
106 return 0;
107
108 if (G_filter.family && G_filter.family != r->ndm_family)
109 return 0;
110 if (G_filter.index && G_filter.index != r->ndm_ifindex)
111 return 0;
112 if (!(G_filter.state&r->ndm_state) &&
113 !(r->ndm_flags & NTF_PROXY) &&
114 (r->ndm_state || !(G_filter.state & 0x100)) &&
115 (r->ndm_family != AF_DECnet))
116 return 0;
117
118 parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
119
120 if (tb[NDA_DST]) {
121 if (G_filter.pfx.family) {
122 inet_prefix dst;
123 memset(&dst, 0, sizeof(dst));
124 dst.family = r->ndm_family;
125 memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
126 if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
127 return 0;
128 }
129 }
130 if (G_filter.unused_only && tb[NDA_CACHEINFO]) {
131 struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
132 if (ci->ndm_refcnt)
133 return 0;
134 }
135
136 if (G_filter.flushb) {
137 struct nlmsghdr *fn;
138 if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
139 if (flush_update())
140 return -1;
141 }
142 fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
143 memcpy(fn, n, n->nlmsg_len);
144 fn->nlmsg_type = RTM_DELNEIGH;
145 fn->nlmsg_flags = NLM_F_REQUEST;
146 fn->nlmsg_seq = ++(G_filter.rth->seq);
147 G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
148 G_filter.flushed++;
149 if (xshow_stats < 2)
150 return 0;
151 }
152
153 if (tb[NDA_DST]) {
154 printf("%s ",
155 format_host(r->ndm_family,
156 RTA_PAYLOAD(tb[NDA_DST]),
157 RTA_DATA(tb[NDA_DST]))
158 );
159 }
160 if (!G_filter.index && r->ndm_ifindex)
161 printf("dev %s ", ll_index_to_name(r->ndm_ifindex));
162 if (tb[NDA_LLADDR]) {
163 SPRINT_BUF(b1);
164 printf("lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
165 RTA_PAYLOAD(tb[NDA_LLADDR]),
166 ARPHRD_ETHER,
167 b1, sizeof(b1)));
168 }
169 if (r->ndm_flags & NTF_ROUTER) {
170 printf(" router");
171 }
172 if (r->ndm_flags & NTF_PROXY) {
173 printf(" proxy");
174 }
175 if (tb[NDA_CACHEINFO] && xshow_stats) {
176 struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
177 int hz = get_hz();
178
179 if (ci->ndm_refcnt)
180 printf(" ref %d", ci->ndm_refcnt);
181 printf(" used %d/%d/%d", ci->ndm_used/hz,
182 ci->ndm_confirmed/hz, ci->ndm_updated/hz);
183 }
184
185 if (tb[NDA_PROBES] && xshow_stats) {
186 uint32_t p = rta_getattr_u32(tb[NDA_PROBES]);
187 printf(" probes %u", p);
188 }
189
190 /*if (r->ndm_state)*/ {
191 int nud = r->ndm_state;
192 char c = ' ';
193#define PRINT_FLAG(f) \
194 if (nud & NUD_##f) { \
195 printf("%c"#f, c); \
196 c = ','; \
197 }
198 PRINT_FLAG(INCOMPLETE);
199 PRINT_FLAG(REACHABLE);
200 PRINT_FLAG(STALE);
201 PRINT_FLAG(DELAY);
202 PRINT_FLAG(PROBE);
203 PRINT_FLAG(FAILED);
204 PRINT_FLAG(NOARP);
205 PRINT_FLAG(PERMANENT);
206#undef PRINT_FLAG
207 }
208 bb_putchar('\n');
209
210 return 0;
211}
212
213static void ipneigh_reset_filter(void)
214{
215 memset(&G_filter, 0, sizeof(G_filter));
216 G_filter.state = ~0;
217}
218
219#define MAX_ROUNDS 10
220/* Return value becomes exitcode. It's okay to not return at all */
221static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush)
222{
223 static const char keywords[] ALIGN1 =
224 /* "ip neigh show/flush" parameters: */
225 "to\0" "dev\0" "nud\0";
226 enum {
227 KW_to, KW_dev, KW_nud,
228 };
229 struct rtnl_handle rth;
230 struct ndmsg ndm = { 0 };
231 char *filter_dev = NULL;
232 int state_given = 0;
233 int arg;
234
235 ipneigh_reset_filter();
236
237 if (flush && !*argv)
238 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip neigh flush\"");
239
240 if (!G_filter.family)
241 G_filter.family = preferred_family;
242
243 G_filter.state = (flush) ?
244 ~(NUD_PERMANENT|NUD_NOARP) : 0xFF & ~NUD_NOARP;
245
246 while (*argv) {
247 arg = index_in_substrings(keywords, *argv);
248 if (arg == KW_dev) {
249 NEXT_ARG();
250 filter_dev = *argv;
251 } else if (arg == KW_nud) {
252 unsigned state;
253 NEXT_ARG();
254 if (!state_given) {
255 state_given = 1;
256 G_filter.state = 0;
257 }
258 if (strcmp(*argv, "all") == 0) {
259 state = ~0;
260 if (flush)
261 state &= ~NUD_NOARP;
262 } else {
263 state = nud_state_a2n(*argv);
264 }
265 if (state == 0)
266 state = 0x100;
267 G_filter.state |= state;
268 } else {
269 if (arg == KW_to) {
270 NEXT_ARG();
271 }
272 get_prefix(&G_filter.pfx, *argv, G_filter.family);
273 if (G_filter.family == AF_UNSPEC)
274 G_filter.family = G_filter.pfx.family;
275 }
276 argv++;
277 }
278
279 xrtnl_open(&rth);
280 ll_init_map(&rth);
281
282 if (filter_dev) {
283 G_filter.index = xll_name_to_index(filter_dev);
284 if (G_filter.index == 0) {
285 bb_error_msg_and_die("can't find device '%s'", filter_dev);
286 }
287 }
288
289 if (flush) {
290 int round = 0;
291 char flushb[4096-512];
292 G_filter.flushb = flushb;
293 G_filter.flushp = 0;
294 G_filter.flushe = sizeof(flushb);
295 G_filter.state &= ~NUD_FAILED;
296 G_filter.rth = &rth;
297
298 while (round < MAX_ROUNDS) {
299 if (xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH) < 0) {
300 bb_perror_msg_and_die("can't send dump request");
301 }
302 G_filter.flushed = 0;
303 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) {
304 bb_perror_msg_and_die("flush terminated");
305 }
306 if (G_filter.flushed == 0) {
307 if (round == 0)
308 puts("Nothing to flush");
309 else
310 printf("*** Flush is complete after %d round(s) ***\n", round);
311 return 0;
312 }
313 round++;
314 if (flush_update() < 0)
315 xfunc_die();
316 printf("\n*** Round %d, deleting %d entries ***\n", round, G_filter.flushed);
317 }
318 bb_error_msg_and_die("*** Flush not complete bailing out after %d rounds", MAX_ROUNDS);
319 }
320
321 ndm.ndm_family = G_filter.family;
322
323 if (rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0) {
324 bb_perror_msg_and_die("can't send dump request");
325 }
326
327 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) {
328 bb_error_msg_and_die("dump terminated");
329 }
330
331 return 0;
332}
333
334/* Return value becomes exitcode. It's okay to not return at all */
335int FAST_FUNC do_ipneigh(char **argv)
336{
337 static const char ip_neigh_commands[] ALIGN1 =
338 /*0-1*/ "show\0" "flush\0";
339 int command_num;
340
341 if (!*argv)
342 return ipneigh_list_or_flush(argv, 0);
343
344 command_num = index_in_substrings(ip_neigh_commands, *argv);
345 switch (command_num) {
346 case 0: /* show */
347 return ipneigh_list_or_flush(argv + 1, 0);
348 case 1: /* flush */
349 return ipneigh_list_or_flush(argv + 1, 1);
350 }
351 invarg_1_to_2(*argv, applet_name);
352 return 1;
353}
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 6ecd5f719..d232ee6fd 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -55,35 +55,12 @@ static int flush_update(void)
55 return 0; 55 return 0;
56} 56}
57 57
58static unsigned get_hz(void)
59{
60 static unsigned hz_internal;
61 FILE *fp;
62
63 if (hz_internal)
64 return hz_internal;
65
66 fp = fopen_for_read("/proc/net/psched");
67 if (fp) {
68 unsigned nom, denom;
69
70 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
71 if (nom == 1000000)
72 hz_internal = denom;
73 fclose(fp);
74 }
75 if (!hz_internal)
76 hz_internal = bb_clk_tck();
77 return hz_internal;
78}
79
80static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, 58static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
81 struct nlmsghdr *n, void *arg UNUSED_PARAM) 59 struct nlmsghdr *n, void *arg UNUSED_PARAM)
82{ 60{
83 struct rtmsg *r = NLMSG_DATA(n); 61 struct rtmsg *r = NLMSG_DATA(n);
84 int len = n->nlmsg_len; 62 int len = n->nlmsg_len;
85 struct rtattr *tb[RTA_MAX+1]; 63 struct rtattr *tb[RTA_MAX+1];
86 char abuf[256];
87 inet_prefix dst; 64 inet_prefix dst;
88 inet_prefix src; 65 inet_prefix src;
89 int host_len = -1; 66 int host_len = -1;
@@ -217,7 +194,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
217 194
218 if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { 195 if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
219 if (flush_update()) 196 if (flush_update())
220 bb_error_msg_and_die("flush"); 197 xfunc_die();
221 } 198 }
222 fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); 199 fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
223 memcpy(fn, n, n->nlmsg_len); 200 memcpy(fn, n, n->nlmsg_len);
@@ -240,17 +217,15 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
240 217
241 if (tb[RTA_DST]) { 218 if (tb[RTA_DST]) {
242 if (r->rtm_dst_len != host_len) { 219 if (r->rtm_dst_len != host_len) {
243 printf("%s/%u ", rt_addr_n2a(r->rtm_family, 220 printf("%s/%u ",
244 RTA_DATA(tb[RTA_DST]), 221 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_DST])),
245 abuf, sizeof(abuf)), 222 r->rtm_dst_len
246 r->rtm_dst_len 223 );
247 );
248 } else { 224 } else {
249 printf("%s ", format_host(r->rtm_family, 225 printf("%s ", format_host(r->rtm_family,
250 RTA_PAYLOAD(tb[RTA_DST]), 226 RTA_PAYLOAD(tb[RTA_DST]),
251 RTA_DATA(tb[RTA_DST]), 227 RTA_DATA(tb[RTA_DST]))
252 abuf, sizeof(abuf)) 228 );
253 );
254 } 229 }
255 } else if (r->rtm_dst_len) { 230 } else if (r->rtm_dst_len) {
256 printf("0/%d ", r->rtm_dst_len); 231 printf("0/%d ", r->rtm_dst_len);
@@ -259,17 +234,15 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
259 } 234 }
260 if (tb[RTA_SRC]) { 235 if (tb[RTA_SRC]) {
261 if (r->rtm_src_len != host_len) { 236 if (r->rtm_src_len != host_len) {
262 printf("from %s/%u ", rt_addr_n2a(r->rtm_family, 237 printf("from %s/%u ",
263 RTA_DATA(tb[RTA_SRC]), 238 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])),
264 abuf, sizeof(abuf)), 239 r->rtm_src_len
265 r->rtm_src_len 240 );
266 );
267 } else { 241 } else {
268 printf("from %s ", format_host(r->rtm_family, 242 printf("from %s ", format_host(r->rtm_family,
269 RTA_PAYLOAD(tb[RTA_SRC]), 243 RTA_PAYLOAD(tb[RTA_SRC]),
270 RTA_DATA(tb[RTA_SRC]), 244 RTA_DATA(tb[RTA_SRC]))
271 abuf, sizeof(abuf)) 245 );
272 );
273 } 246 }
274 } else if (r->rtm_src_len) { 247 } else if (r->rtm_src_len) {
275 printf("from 0/%u ", r->rtm_src_len); 248 printf("from 0/%u ", r->rtm_src_len);
@@ -277,8 +250,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
277 if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) { 250 if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) {
278 printf("via %s ", format_host(r->rtm_family, 251 printf("via %s ", format_host(r->rtm_family,
279 RTA_PAYLOAD(tb[RTA_GATEWAY]), 252 RTA_PAYLOAD(tb[RTA_GATEWAY]),
280 RTA_DATA(tb[RTA_GATEWAY]), 253 RTA_DATA(tb[RTA_GATEWAY]))
281 abuf, sizeof(abuf))); 254 );
282 } 255 }
283 if (tb[RTA_OIF]) { 256 if (tb[RTA_OIF]) {
284 printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); 257 printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
@@ -291,8 +264,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
291 and symbolic name will not be useful. 264 and symbolic name will not be useful.
292 */ 265 */
293 printf(" src %s ", rt_addr_n2a(r->rtm_family, 266 printf(" src %s ", rt_addr_n2a(r->rtm_family,
294 RTA_DATA(tb[RTA_PREFSRC]), 267 RTA_DATA(tb[RTA_PREFSRC])));
295 abuf, sizeof(abuf)));
296 } 268 }
297 if (tb[RTA_PRIORITY]) { 269 if (tb[RTA_PRIORITY]) {
298 printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); 270 printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
@@ -425,7 +397,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
425 uint32_t prot; 397 uint32_t prot;
426 NEXT_ARG(); 398 NEXT_ARG();
427 if (rtnl_rtprot_a2n(&prot, *argv)) 399 if (rtnl_rtprot_a2n(&prot, *argv))
428 invarg(*argv, "protocol"); 400 invarg_1_to_2(*argv, "protocol");
429 req.r.rtm_protocol = prot; 401 req.r.rtm_protocol = prot;
430 ok |= proto_ok; 402 ok |= proto_ok;
431#if ENABLE_FEATURE_IP_RULE 403#if ENABLE_FEATURE_IP_RULE
@@ -433,7 +405,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
433 uint32_t tid; 405 uint32_t tid;
434 NEXT_ARG(); 406 NEXT_ARG();
435 if (rtnl_rttable_a2n(&tid, *argv)) 407 if (rtnl_rttable_a2n(&tid, *argv))
436 invarg(*argv, "table"); 408 invarg_1_to_2(*argv, "table");
437 req.r.rtm_table = tid; 409 req.r.rtm_table = tid;
438#endif 410#endif
439 } else if (arg == ARG_dev || arg == ARG_oif) { 411 } else if (arg == ARG_dev || arg == ARG_oif) {
@@ -619,7 +591,7 @@ static int iproute_list_or_flush(char **argv, int flush)
619 //G_filter.protocolmask = -1; 591 //G_filter.protocolmask = -1;
620 if (rtnl_rtprot_a2n(&prot, *argv)) { 592 if (rtnl_rtprot_a2n(&prot, *argv)) {
621 if (index_in_strings(keywords, *argv) != KW_all) 593 if (index_in_strings(keywords, *argv) != KW_all)
622 invarg(*argv, "protocol"); 594 invarg_1_to_2(*argv, "protocol");
623 prot = 0; 595 prot = 0;
624 //G_filter.protocolmask = 0; 596 //G_filter.protocolmask = 0;
625 } 597 }
@@ -644,10 +616,10 @@ static int iproute_list_or_flush(char **argv, int flush)
644#if ENABLE_FEATURE_IP_RULE 616#if ENABLE_FEATURE_IP_RULE
645 uint32_t tid; 617 uint32_t tid;
646 if (rtnl_rttable_a2n(&tid, *argv)) 618 if (rtnl_rttable_a2n(&tid, *argv))
647 invarg(*argv, "table"); 619 invarg_1_to_2(*argv, "table");
648 G_filter.tb = tid; 620 G_filter.tb = tid;
649#else 621#else
650 invarg(*argv, "table"); 622 invarg_1_to_2(*argv, "table");
651#endif 623#endif
652 } 624 }
653 } else if (arg == KW_cache) { 625 } else if (arg == KW_cache) {
@@ -954,7 +926,7 @@ int FAST_FUNC do_iproute(char **argv)
954 case 11: /* flush */ 926 case 11: /* flush */
955 return iproute_list_or_flush(argv+1, 1); 927 return iproute_list_or_flush(argv+1, 1);
956 default: 928 default:
957 bb_error_msg_and_die("unknown command %s", *argv); 929 invarg_1_to_2(*argv, applet_name);
958 } 930 }
959 931
960 return iproute_modify(cmd, flags, argv+1); 932 return iproute_modify(cmd, flags, argv+1);
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 774a3e220..dba64346f 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -44,7 +44,6 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
44 int len = n->nlmsg_len; 44 int len = n->nlmsg_len;
45 int host_len = -1; 45 int host_len = -1;
46 struct rtattr * tb[RTA_MAX+1]; 46 struct rtattr * tb[RTA_MAX+1];
47 char abuf[256];
48 47
49 if (n->nlmsg_type != RTM_NEWRULE) 48 if (n->nlmsg_type != RTM_NEWRULE)
50 return 0; 49 return 0;
@@ -71,16 +70,14 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
71 printf("from "); 70 printf("from ");
72 if (tb[RTA_SRC]) { 71 if (tb[RTA_SRC]) {
73 if (r->rtm_src_len != host_len) { 72 if (r->rtm_src_len != host_len) {
74 printf("%s/%u", rt_addr_n2a(r->rtm_family, 73 printf("%s/%u",
75 RTA_DATA(tb[RTA_SRC]), 74 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])),
76 abuf, sizeof(abuf)),
77 r->rtm_src_len 75 r->rtm_src_len
78 ); 76 );
79 } else { 77 } else {
80 fputs(format_host(r->rtm_family, 78 fputs(format_host(r->rtm_family,
81 RTA_PAYLOAD(tb[RTA_SRC]), 79 RTA_PAYLOAD(tb[RTA_SRC]),
82 RTA_DATA(tb[RTA_SRC]), 80 RTA_DATA(tb[RTA_SRC])),
83 abuf, sizeof(abuf)),
84 stdout 81 stdout
85 ); 82 );
86 } 83 }
@@ -94,15 +91,13 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
94 if (tb[RTA_DST]) { 91 if (tb[RTA_DST]) {
95 if (r->rtm_dst_len != host_len) { 92 if (r->rtm_dst_len != host_len) {
96 printf("to %s/%u ", rt_addr_n2a(r->rtm_family, 93 printf("to %s/%u ", rt_addr_n2a(r->rtm_family,
97 RTA_DATA(tb[RTA_DST]), 94 RTA_DATA(tb[RTA_DST])),
98 abuf, sizeof(abuf)),
99 r->rtm_dst_len 95 r->rtm_dst_len
100 ); 96 );
101 } else { 97 } else {
102 printf("to %s ", format_host(r->rtm_family, 98 printf("to %s ", format_host(r->rtm_family,
103 RTA_PAYLOAD(tb[RTA_DST]), 99 RTA_PAYLOAD(tb[RTA_DST]),
104 RTA_DATA(tb[RTA_DST]), 100 RTA_DATA(tb[RTA_DST])));
105 abuf, sizeof(abuf)));
106 } 101 }
107 } else if (r->rtm_dst_len) { 102 } else if (r->rtm_dst_len) {
108 printf("to 0/%d ", r->rtm_dst_len); 103 printf("to 0/%d ", r->rtm_dst_len);
@@ -139,8 +134,8 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
139 printf("map-to %s ", 134 printf("map-to %s ",
140 format_host(r->rtm_family, 135 format_host(r->rtm_family,
141 RTA_PAYLOAD(tb[RTA_GATEWAY]), 136 RTA_PAYLOAD(tb[RTA_GATEWAY]),
142 RTA_DATA(tb[RTA_GATEWAY]), 137 RTA_DATA(tb[RTA_GATEWAY]))
143 abuf, sizeof(abuf))); 138 );
144 } else 139 } else
145 printf("masquerade"); 140 printf("masquerade");
146 } else if (r->rtm_type != RTN_UNICAST) 141 } else if (r->rtm_type != RTN_UNICAST)
@@ -214,7 +209,7 @@ static int iprule_modify(int cmd, char **argv)
214 while (*argv) { 209 while (*argv) {
215 key = index_in_substrings(keywords, *argv) + 1; 210 key = index_in_substrings(keywords, *argv) + 1;
216 if (key == 0) /* no match found in keywords array, bail out. */ 211 if (key == 0) /* no match found in keywords array, bail out. */
217 invarg(*argv, applet_name); 212 invarg_1_to_2(*argv, applet_name);
218 if (key == ARG_from) { 213 if (key == ARG_from) {
219 inet_prefix dst; 214 inet_prefix dst;
220 NEXT_ARG(); 215 NEXT_ARG();
@@ -239,7 +234,7 @@ static int iprule_modify(int cmd, char **argv)
239 uint32_t tos; 234 uint32_t tos;
240 NEXT_ARG(); 235 NEXT_ARG();
241 if (rtnl_dsfield_a2n(&tos, *argv)) 236 if (rtnl_dsfield_a2n(&tos, *argv))
242 invarg(*argv, "TOS"); 237 invarg_1_to_2(*argv, "TOS");
243 req.r.rtm_tos = tos; 238 req.r.rtm_tos = tos;
244 } else if (key == ARG_fwmark) { 239 } else if (key == ARG_fwmark) {
245 uint32_t fwmark; 240 uint32_t fwmark;
@@ -250,7 +245,7 @@ static int iprule_modify(int cmd, char **argv)
250 uint32_t realm; 245 uint32_t realm;
251 NEXT_ARG(); 246 NEXT_ARG();
252 if (get_rt_realms(&realm, *argv)) 247 if (get_rt_realms(&realm, *argv))
253 invarg(*argv, "realms"); 248 invarg_1_to_2(*argv, "realms");
254 addattr32(&req.n, sizeof(req), RTA_FLOW, realm); 249 addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
255 } else if (key == ARG_table || 250 } else if (key == ARG_table ||
256 key == ARG_lookup 251 key == ARG_lookup
@@ -258,7 +253,7 @@ static int iprule_modify(int cmd, char **argv)
258 uint32_t tid; 253 uint32_t tid;
259 NEXT_ARG(); 254 NEXT_ARG();
260 if (rtnl_rttable_a2n(&tid, *argv)) 255 if (rtnl_rttable_a2n(&tid, *argv))
261 invarg(*argv, "table ID"); 256 invarg_1_to_2(*argv, "table ID");
262 req.r.rtm_table = tid; 257 req.r.rtm_table = tid;
263 table_ok = 1; 258 table_ok = 1;
264 } else if (key == ARG_dev || 259 } else if (key == ARG_dev ||
@@ -281,7 +276,7 @@ static int iprule_modify(int cmd, char **argv)
281 if (key == ARG_help) 276 if (key == ARG_help)
282 bb_show_usage(); 277 bb_show_usage();
283 if (rtnl_rtntype_a2n(&type, *argv)) 278 if (rtnl_rtntype_a2n(&type, *argv))
284 invarg(*argv, "type"); 279 invarg_1_to_2(*argv, "type");
285 req.r.rtm_type = type; 280 req.r.rtm_type = type;
286 } 281 }
287 argv++; 282 argv++;
@@ -309,7 +304,7 @@ int FAST_FUNC do_iprule(char **argv)
309 if (*argv) { 304 if (*argv) {
310 int cmd = index_in_substrings(ip_rule_commands, *argv); 305 int cmd = index_in_substrings(ip_rule_commands, *argv);
311 if (cmd < 0) 306 if (cmd < 0)
312 invarg(*argv, applet_name); 307 invarg_1_to_2(*argv, applet_name);
313 argv++; 308 argv++;
314 if (cmd < 2) 309 if (cmd < 2)
315 return iprule_modify((cmd == 0) ? RTM_NEWRULE : RTM_DELRULE, argv); 310 return iprule_modify((cmd == 0) ? RTM_NEWRULE : RTM_DELRULE, argv);
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index a65d5e579..eb136e435 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -294,7 +294,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
294 if (key != ARG_inherit) { 294 if (key != ARG_inherit) {
295 uval = get_unsigned(*argv, "TTL"); 295 uval = get_unsigned(*argv, "TTL");
296 if (uval > 255) 296 if (uval > 255)
297 invarg(*argv, "TTL must be <=255"); 297 invarg_1_to_2(*argv, "TTL");
298 p->iph.ttl = uval; 298 p->iph.ttl = uval;
299 } 299 }
300 } else if (key == ARG_tos || 300 } else if (key == ARG_tos ||
@@ -305,7 +305,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
305 key = index_in_strings(keywords, *argv); 305 key = index_in_strings(keywords, *argv);
306 if (key != ARG_inherit) { 306 if (key != ARG_inherit) {
307 if (rtnl_dsfield_a2n(&uval, *argv)) 307 if (rtnl_dsfield_a2n(&uval, *argv))
308 invarg(*argv, "TOS"); 308 invarg_1_to_2(*argv, "TOS");
309 p->iph.tos = uval; 309 p->iph.tos = uval;
310 } else 310 } else
311 p->iph.tos = 1; 311 p->iph.tos = 1;
@@ -404,22 +404,18 @@ static int do_del(char **argv)
404 404
405static void print_tunnel(struct ip_tunnel_parm *p) 405static void print_tunnel(struct ip_tunnel_parm *p)
406{ 406{
407 char s1[256]; 407 char s3[INET_ADDRSTRLEN];
408 char s2[256]; 408 char s4[INET_ADDRSTRLEN];
409 char s3[64];
410 char s4[64];
411
412 format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1));
413 format_host(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2));
414 inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
415 inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
416 409
417 printf("%s: %s/ip remote %s local %s ", 410 printf("%s: %s/ip remote %s local %s ",
418 p->name, 411 p->name,
419 p->iph.protocol == IPPROTO_IPIP ? "ip" : 412 p->iph.protocol == IPPROTO_IPIP ? "ip" :
420 (p->iph.protocol == IPPROTO_GRE ? "gre" : 413 p->iph.protocol == IPPROTO_GRE ? "gre" :
421 (p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : "unknown")), 414 p->iph.protocol == IPPROTO_IPV6 ? "ipv6" :
422 p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any"); 415 "unknown",
416 p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr) : "any",
417 p->iph.saddr ? format_host(AF_INET, 4, &p->iph.saddr) : "any"
418 );
423 if (p->link) { 419 if (p->link) {
424 char *n = do_ioctl_get_ifname(p->link); 420 char *n = do_ioctl_get_ifname(p->link);
425 if (n) { 421 if (n) {
@@ -442,9 +438,11 @@ static void print_tunnel(struct ip_tunnel_parm *p)
442 if (!(p->iph.frag_off & htons(IP_DF))) 438 if (!(p->iph.frag_off & htons(IP_DF)))
443 printf(" nopmtudisc"); 439 printf(" nopmtudisc");
444 440
441 inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
442 inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
445 if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key) 443 if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key)
446 printf(" key %s", s3); 444 printf(" key %s", s3);
447 else if ((p->i_flags | p->o_flags) & GRE_KEY) { 445 else {
448 if (p->i_flags & GRE_KEY) 446 if (p->i_flags & GRE_KEY)
449 printf(" ikey %s ", s3); 447 printf(" ikey %s ", s3);
450 if (p->o_flags & GRE_KEY) 448 if (p->o_flags & GRE_KEY)
@@ -562,7 +560,7 @@ int FAST_FUNC do_iptunnel(char **argv)
562 if (*argv) { 560 if (*argv) {
563 int key = index_in_substrings(keywords, *argv); 561 int key = index_in_substrings(keywords, *argv);
564 if (key < 0) 562 if (key < 0)
565 invarg(*argv, applet_name); 563 invarg_1_to_2(*argv, applet_name);
566 argv++; 564 argv++;
567 if (key == ARG_add) 565 if (key == ARG_add)
568 return do_add(SIOCADDTUNNEL, argv); 566 return do_add(SIOCADDTUNNEL, argv);
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c
index d0fe30605..42025bc66 100644
--- a/networking/libiproute/utils.c
+++ b/networking/libiproute/utils.c
@@ -13,6 +13,28 @@
13#include "utils.h" 13#include "utils.h"
14#include "inet_common.h" 14#include "inet_common.h"
15 15
16unsigned get_hz(void)
17{
18 static unsigned hz_internal;
19 FILE *fp;
20
21 if (hz_internal)
22 return hz_internal;
23
24 fp = fopen_for_read("/proc/net/psched");
25 if (fp) {
26 unsigned nom, denom;
27
28 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
29 if (nom == 1000000)
30 hz_internal = denom;
31 fclose(fp);
32 }
33 if (!hz_internal)
34 hz_internal = bb_clk_tck();
35 return hz_internal;
36}
37
16unsigned get_unsigned(char *arg, const char *errmsg) 38unsigned get_unsigned(char *arg, const char *errmsg)
17{ 39{
18 unsigned long res; 40 unsigned long res;
@@ -25,7 +47,7 @@ unsigned get_unsigned(char *arg, const char *errmsg)
25 return res; 47 return res;
26 } 48 }
27 } 49 }
28 invarg(arg, errmsg); /* does not return */ 50 invarg_1_to_2(arg, errmsg); /* does not return */
29} 51}
30 52
31uint32_t get_u32(char *arg, const char *errmsg) 53uint32_t get_u32(char *arg, const char *errmsg)
@@ -40,7 +62,7 @@ uint32_t get_u32(char *arg, const char *errmsg)
40 return res; 62 return res;
41 } 63 }
42 } 64 }
43 invarg(arg, errmsg); /* does not return */ 65 invarg_1_to_2(arg, errmsg); /* does not return */
44} 66}
45 67
46uint16_t get_u16(char *arg, const char *errmsg) 68uint16_t get_u16(char *arg, const char *errmsg)
@@ -55,7 +77,7 @@ uint16_t get_u16(char *arg, const char *errmsg)
55 return res; 77 return res;
56 } 78 }
57 } 79 }
58 invarg(arg, errmsg); /* does not return */ 80 invarg_1_to_2(arg, errmsg); /* does not return */
59} 81}
60 82
61int get_addr_1(inet_prefix *addr, char *name, int family) 83int get_addr_1(inet_prefix *addr, char *name, int family)
@@ -208,12 +230,12 @@ uint32_t get_addr32(char *name)
208 230
209void incomplete_command(void) 231void incomplete_command(void)
210{ 232{
211 bb_error_msg_and_die("command line is not complete, try option \"help\""); 233 bb_error_msg_and_die("command line is not complete, try \"help\"");
212} 234}
213 235
214void invarg(const char *arg, const char *opt) 236void invarg_1_to_2(const char *arg, const char *opt)
215{ 237{
216 bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt); 238 bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, opt);
217} 239}
218 240
219void duparg(const char *key, const char *arg) 241void duparg(const char *key, const char *arg)
@@ -254,20 +276,21 @@ int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
254 return 0; 276 return 0;
255} 277}
256 278
257const char *rt_addr_n2a(int af, 279const char *rt_addr_n2a(int af, void *addr)
258 void *addr, char *buf, int buflen)
259{ 280{
260 switch (af) { 281 switch (af) {
261 case AF_INET: 282 case AF_INET:
262 case AF_INET6: 283 case AF_INET6:
263 return inet_ntop(af, addr, buf, buflen); 284 return inet_ntop(af, addr,
285 auto_string(xzalloc(INET6_ADDRSTRLEN)), INET6_ADDRSTRLEN
286 );
264 default: 287 default:
265 return "???"; 288 return "???";
266 } 289 }
267} 290}
268 291
269#ifdef RESOLVE_HOSTNAMES 292#ifdef RESOLVE_HOSTNAMES
270const char *format_host(int af, int len, void *addr, char *buf, int buflen) 293const char *format_host(int af, int len, void *addr)
271{ 294{
272 if (resolve_hosts) { 295 if (resolve_hosts) {
273 struct hostent *h_ent; 296 struct hostent *h_ent;
@@ -286,11 +309,10 @@ const char *format_host(int af, int len, void *addr, char *buf, int buflen)
286 if (len > 0) { 309 if (len > 0) {
287 h_ent = gethostbyaddr(addr, len, af); 310 h_ent = gethostbyaddr(addr, len, af);
288 if (h_ent != NULL) { 311 if (h_ent != NULL) {
289 safe_strncpy(buf, h_ent->h_name, buflen); 312 return auto_string(xstrdup(h_ent->h_name));
290 return buf;
291 } 313 }
292 } 314 }
293 } 315 }
294 return rt_addr_n2a(af, addr, buf, buflen); 316 return rt_addr_n2a(af, addr);
295} 317}
296#endif 318#endif
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h
index 5fb4a862c..408d5f65f 100644
--- a/networking/libiproute/utils.h
+++ b/networking/libiproute/utils.h
@@ -66,15 +66,15 @@ extern unsigned get_unsigned(char *arg, const char *errmsg);
66extern uint32_t get_u32(char *arg, const char *errmsg); 66extern uint32_t get_u32(char *arg, const char *errmsg);
67extern uint16_t get_u16(char *arg, const char *errmsg); 67extern uint16_t get_u16(char *arg, const char *errmsg);
68 68
69extern const char *rt_addr_n2a(int af, void *addr, char *buf, int buflen); 69extern const char *rt_addr_n2a(int af, void *addr);
70#ifdef RESOLVE_HOSTNAMES 70#ifdef RESOLVE_HOSTNAMES
71extern const char *format_host(int af, int len, void *addr, char *buf, int buflen); 71extern const char *format_host(int af, int len, void *addr);
72#else 72#else
73#define format_host(af, len, addr, buf, buflen) \ 73#define format_host(af, len, addr) \
74 rt_addr_n2a(af, addr, buf, buflen) 74 rt_addr_n2a(af, addr)
75#endif 75#endif
76 76
77void invarg(const char *, const char *) NORETURN; 77void invarg_1_to_2(const char *, const char *) NORETURN;
78void duparg(const char *, const char *) NORETURN; 78void duparg(const char *, const char *) NORETURN;
79void duparg2(const char *, const char *) NORETURN; 79void duparg2(const char *, const char *) NORETURN;
80int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); 80int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
@@ -85,6 +85,8 @@ int dnet_pton(int af, const char *src, void *addr);
85const char *ipx_ntop(int af, const void *addr, char *str, size_t len); 85const char *ipx_ntop(int af, const void *addr, char *str, size_t len);
86int ipx_pton(int af, const char *src, void *addr); 86int ipx_pton(int af, const char *src, void *addr);
87 87
88unsigned get_hz(void);
89
88POP_SAVED_FUNCTION_VISIBILITY 90POP_SAVED_FUNCTION_VISIBILITY
89 91
90#endif 92#endif
diff --git a/networking/nbd-client.c b/networking/nbd-client.c
index a601430b6..70869d651 100644
--- a/networking/nbd-client.c
+++ b/networking/nbd-client.c
@@ -57,9 +57,8 @@ int nbdclient_main(int argc, char **argv)
57 uint32_t flags; 57 uint32_t flags;
58 char data[124]; 58 char data[124];
59 } nbd_header; 59 } nbd_header;
60 struct bug_check { 60
61 char c[offsetof(struct nbd_header_t, data) == 8+8+8+4 ? 1 : -1]; 61 BUILD_BUG_ON(offsetof(struct nbd_header_t, data) != 8+8+8+4);
62 };
63 62
64 // Parse command line stuff (just a stub now) 63 // Parse command line stuff (just a stub now)
65 if (argc != 4) 64 if (argc != 4)
diff --git a/networking/slattach.c b/networking/slattach.c
index a500da6d0..14e0c1941 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -27,7 +27,7 @@
27//usage: "\n -F Disable RTS/CTS flow control" 27//usage: "\n -F Disable RTS/CTS flow control"
28 28
29#include "libbb.h" 29#include "libbb.h"
30#include "libiproute/utils.h" /* invarg() */ 30#include "libiproute/utils.h" /* invarg_1_to_2() */
31 31
32struct globals { 32struct globals {
33 int handle; 33 int handle;
@@ -175,7 +175,7 @@ int slattach_main(int argc UNUSED_PARAM, char **argv)
175 encap = index_in_strings(proto_names, proto); 175 encap = index_in_strings(proto_names, proto);
176 176
177 if (encap < 0) 177 if (encap < 0)
178 invarg(proto, "protocol"); 178 invarg_1_to_2(proto, "protocol");
179 if (encap > 3) 179 if (encap > 3)
180 encap = 8; 180 encap = 8;
181 181
@@ -183,7 +183,7 @@ int slattach_main(int argc UNUSED_PARAM, char **argv)
183 if (opt & OPT_s_baud) { 183 if (opt & OPT_s_baud) {
184 baud_code = tty_value_to_baud(xatoi(baud_str)); 184 baud_code = tty_value_to_baud(xatoi(baud_str));
185 if (baud_code < 0) 185 if (baud_code < 0)
186 invarg(baud_str, "baud rate"); 186 invarg_1_to_2(baud_str, "baud rate");
187 } 187 }
188 188
189 /* Trap signals in order to restore tty states upon exit */ 189 /* Trap signals in order to restore tty states upon exit */
diff --git a/networking/tc.c b/networking/tc.c
index 6d1fef993..c84c18a67 100644
--- a/networking/tc.c
+++ b/networking/tc.c
@@ -459,14 +459,14 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
459 459
460 obj = index_in_substrings(objects, *argv++); 460 obj = index_in_substrings(objects, *argv++);
461 461
462 if (obj < OBJ_qdisc) 462 if (obj < 0)
463 bb_show_usage(); 463 bb_show_usage();
464 if (!*argv) 464 if (!*argv)
465 cmd = CMD_show; /* list is the default */ 465 cmd = CMD_show; /* list is the default */
466 else { 466 else {
467 cmd = index_in_substrings(commands, *argv); 467 cmd = index_in_substrings(commands, *argv);
468 if (cmd < 0) 468 if (cmd < 0)
469 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 469 invarg_1_to_2(*argv, argv[-1]);
470 argv++; 470 argv++;
471 } 471 }
472 memset(&msg, 0, sizeof(msg)); 472 memset(&msg, 0, sizeof(msg));
@@ -489,7 +489,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
489 NEXT_ARG(); 489 NEXT_ARG();
490 /* We don't care about duparg2("qdisc handle",*argv) for now */ 490 /* We don't care about duparg2("qdisc handle",*argv) for now */
491 if (get_qdisc_handle(&filter_qdisc, *argv)) 491 if (get_qdisc_handle(&filter_qdisc, *argv))
492 invarg(*argv, "qdisc"); 492 invarg_1_to_2(*argv, "qdisc");
493 } else 493 } else
494 if (obj != OBJ_qdisc 494 if (obj != OBJ_qdisc
495 && (arg == ARG_root 495 && (arg == ARG_root
@@ -499,7 +499,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
499 ) { 499 ) {
500 /* nothing */ 500 /* nothing */
501 } else { 501 } else {
502 invarg(*argv, "command"); 502 invarg_1_to_2(*argv, "command");
503 } 503 }
504 NEXT_ARG(); 504 NEXT_ARG();
505 if (arg == ARG_root) { 505 if (arg == ARG_root) {
@@ -513,7 +513,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
513 if (msg.tcm_parent) 513 if (msg.tcm_parent)
514 duparg(*argv, "parent"); 514 duparg(*argv, "parent");
515 if (get_tc_classid(&handle, *argv)) 515 if (get_tc_classid(&handle, *argv))
516 invarg(*argv, "parent"); 516 invarg_1_to_2(*argv, "parent");
517 msg.tcm_parent = handle; 517 msg.tcm_parent = handle;
518 if (obj == OBJ_filter) 518 if (obj == OBJ_filter)
519 filter_parent = handle; 519 filter_parent = handle;
@@ -538,7 +538,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
538 if (filter_proto) 538 if (filter_proto)
539 duparg(*argv, "protocol"); 539 duparg(*argv, "protocol");
540 if (ll_proto_a2n(&tmp, *argv)) 540 if (ll_proto_a2n(&tmp, *argv))
541 invarg(*argv, "protocol"); 541 invarg_1_to_2(*argv, "protocol");
542 filter_proto = tmp; 542 filter_proto = tmp;
543 } 543 }
544 } 544 }
diff --git a/networking/telnet.c b/networking/telnet.c
index 3bb6fb1ba..944cf1bd6 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -110,9 +110,7 @@ struct globals {
110} FIX_ALIASING; 110} FIX_ALIASING;
111#define G (*(struct globals*)&bb_common_bufsiz1) 111#define G (*(struct globals*)&bb_common_bufsiz1)
112#define INIT_G() do { \ 112#define INIT_G() do { \
113 struct G_sizecheck { \ 113 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
114 char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \
115 }; \
116} while (0) 114} while (0)
117 115
118 116