diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-19 12:53:35 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-10-19 12:53:35 +0100 |
commit | 8afe8ee83a274925340473fa4d0a984bdcbee740 (patch) | |
tree | b78ed448cb6a55ba7d0ef8141a9f68b55b8acf11 /networking | |
parent | caab029609633220c417dc0aaa9025fd4b7a169c (diff) | |
parent | 3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c (diff) | |
download | busybox-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.src | 13 | ||||
-rw-r--r-- | networking/brctl.c | 8 | ||||
-rw-r--r-- | networking/inetd.c | 4 | ||||
-rw-r--r-- | networking/ip.c | 19 | ||||
-rw-r--r-- | networking/libiproute/Kbuild.src | 8 | ||||
-rw-r--r-- | networking/libiproute/ip_common.h | 2 | ||||
-rw-r--r-- | networking/libiproute/ip_parse_common_args.c | 2 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 28 | ||||
-rw-r--r-- | networking/libiproute/iplink.c | 27 | ||||
-rw-r--r-- | networking/libiproute/ipneigh.c | 353 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 72 | ||||
-rw-r--r-- | networking/libiproute/iprule.c | 31 | ||||
-rw-r--r-- | networking/libiproute/iptunnel.c | 34 | ||||
-rw-r--r-- | networking/libiproute/utils.c | 48 | ||||
-rw-r--r-- | networking/libiproute/utils.h | 12 | ||||
-rw-r--r-- | networking/nbd-client.c | 5 | ||||
-rw-r--r-- | networking/slattach.c | 6 | ||||
-rw-r--r-- | networking/tc.c | 12 | ||||
-rw-r--r-- | networking/telnet.c | 4 |
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 | ||
557 | config 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 | |||
557 | config FEATURE_IP_SHORT_FORMS | 564 | config 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 | ||
615 | config IPNEIGH | ||
616 | bool | ||
617 | default y | ||
618 | depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_NEIGH | ||
619 | |||
607 | config IPCALC | 620 | config 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) |
331 | enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; | 331 | enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; |
332 | struct 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 | ||
95 | static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) | 103 | static 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 | ||
152 | int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
153 | int ipneigh_main(int argc UNUSED_PARAM, char **argv) | ||
154 | { | ||
155 | return ip_do(do_ipneigh, argv); | ||
156 | } | ||
157 | #endif | ||
143 | 158 | ||
144 | 159 | ||
145 | int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 160 | int 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 | |||
68 | lib-$(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); | |||
24 | int FAST_FUNC do_ipaddr(char **argv); | 24 | int FAST_FUNC do_ipaddr(char **argv); |
25 | int FAST_FUNC do_iproute(char **argv); | 25 | int FAST_FUNC do_iproute(char **argv); |
26 | int FAST_FUNC do_iprule(char **argv); | 26 | int FAST_FUNC do_iprule(char **argv); |
27 | //int FAST_FUNC do_ipneigh(char **argv); | 27 | int FAST_FUNC do_ipneigh(char **argv); |
28 | int FAST_FUNC do_iptunnel(char **argv); | 28 | int FAST_FUNC do_iptunnel(char **argv); |
29 | int FAST_FUNC do_iplink(char **argv); | 29 | int 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; | ||
17 | enum { xshow_stats = 3 }; | ||
18 | |||
19 | static 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 | |||
29 | struct 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; | ||
41 | typedef struct filter_t filter_t; | ||
42 | |||
43 | #define G_filter (*(filter_t*)&bb_common_bufsiz1) | ||
44 | |||
45 | static 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 | |||
55 | static 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 | |||
88 | static 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 | |||
213 | static 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 */ | ||
221 | static 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 */ | ||
335 | int 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 | ||
58 | static 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 | |||
80 | static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | 58 | static 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 | ||
405 | static void print_tunnel(struct ip_tunnel_parm *p) | 405 | static 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 | ||
16 | unsigned 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 | |||
16 | unsigned get_unsigned(char *arg, const char *errmsg) | 38 | unsigned 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 | ||
31 | uint32_t get_u32(char *arg, const char *errmsg) | 53 | uint32_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 | ||
46 | uint16_t get_u16(char *arg, const char *errmsg) | 68 | uint16_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 | ||
61 | int get_addr_1(inet_prefix *addr, char *name, int family) | 83 | int get_addr_1(inet_prefix *addr, char *name, int family) |
@@ -208,12 +230,12 @@ uint32_t get_addr32(char *name) | |||
208 | 230 | ||
209 | void incomplete_command(void) | 231 | void 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 | ||
214 | void invarg(const char *arg, const char *opt) | 236 | void 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 | ||
219 | void duparg(const char *key, const char *arg) | 241 | void 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 | ||
257 | const char *rt_addr_n2a(int af, | 279 | const 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 |
270 | const char *format_host(int af, int len, void *addr, char *buf, int buflen) | 293 | const 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); | |||
66 | extern uint32_t get_u32(char *arg, const char *errmsg); | 66 | extern uint32_t get_u32(char *arg, const char *errmsg); |
67 | extern uint16_t get_u16(char *arg, const char *errmsg); | 67 | extern uint16_t get_u16(char *arg, const char *errmsg); |
68 | 68 | ||
69 | extern const char *rt_addr_n2a(int af, void *addr, char *buf, int buflen); | 69 | extern const char *rt_addr_n2a(int af, void *addr); |
70 | #ifdef RESOLVE_HOSTNAMES | 70 | #ifdef RESOLVE_HOSTNAMES |
71 | extern const char *format_host(int af, int len, void *addr, char *buf, int buflen); | 71 | extern 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 | ||
77 | void invarg(const char *, const char *) NORETURN; | 77 | void invarg_1_to_2(const char *, const char *) NORETURN; |
78 | void duparg(const char *, const char *) NORETURN; | 78 | void duparg(const char *, const char *) NORETURN; |
79 | void duparg2(const char *, const char *) NORETURN; | 79 | void duparg2(const char *, const char *) NORETURN; |
80 | int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); | 80 | int 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); | |||
85 | const char *ipx_ntop(int af, const void *addr, char *str, size_t len); | 85 | const char *ipx_ntop(int af, const void *addr, char *str, size_t len); |
86 | int ipx_pton(int af, const char *src, void *addr); | 86 | int ipx_pton(int af, const char *src, void *addr); |
87 | 87 | ||
88 | unsigned get_hz(void); | ||
89 | |||
88 | POP_SAVED_FUNCTION_VISIBILITY | 90 | POP_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 | ||
32 | struct globals { | 32 | struct 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 | ||