diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 09:15:26 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 09:15:26 +0000 |
commit | fff9b699f19bf4e687b755f3a0faecbe958258a9 (patch) | |
tree | fad71af79fdd3ab44a5285fc883b53341f72cd38 | |
parent | 3831c91c95116b9a9b28f67e998e53a80b3e33bd (diff) | |
download | busybox-w32-fff9b699f19bf4e687b755f3a0faecbe958258a9.tar.gz busybox-w32-fff9b699f19bf4e687b755f3a0faecbe958258a9.tar.bz2 busybox-w32-fff9b699f19bf4e687b755f3a0faecbe958258a9.zip |
arping: fix a bug where there is implicit count of 4G;
eliminate data/bss usage; code shrink
function old new delta
timeout_us 4 - -4
static.start 4 - -4
src 4 - -4
sock 4 - -4
sent 4 - -4
req_recv 4 - -4
received 4 - -4
last 4 - -4
dst 4 - -4
count 4 - -4
brd_sent 4 - -4
brd_recv 4 - -4
catcher 375 365 -10
me 20 - -20
he 20 - -20
arping_main 1941 1874 -67
------------------------------------------------------------------------------
(add/remove: 0/14 grow/shrink: 0/2 up/down: 0/-165) Total: -165 bytes
text data bss dec hex filename
783035 941 9244 793220 c1a84 busybox_old
782907 937 9156 793000 c19a8 busybox_unstripped
-rw-r--r-- | networking/arping.c | 86 |
1 files changed, 54 insertions, 32 deletions
diff --git a/networking/arping.c b/networking/arping.c index 44615d5b1..771c3bccd 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -18,12 +18,6 @@ | |||
18 | /* We don't expect to see 1000+ seconds delay, unsigned is enough */ | 18 | /* We don't expect to see 1000+ seconds delay, unsigned is enough */ |
19 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | 19 | #define MONOTONIC_US() ((unsigned)monotonic_us()) |
20 | 20 | ||
21 | static struct in_addr src; | ||
22 | static struct in_addr dst; | ||
23 | static struct sockaddr_ll me; | ||
24 | static struct sockaddr_ll he; | ||
25 | static unsigned last; | ||
26 | |||
27 | enum { | 21 | enum { |
28 | DAD = 1, | 22 | DAD = 1, |
29 | UNSOLICITED = 2, | 23 | UNSOLICITED = 2, |
@@ -34,14 +28,43 @@ enum { | |||
34 | UNICASTING = 64 | 28 | UNICASTING = 64 |
35 | }; | 29 | }; |
36 | 30 | ||
37 | static int sock; | 31 | struct globals { |
38 | static unsigned count = UINT_MAX; | 32 | struct in_addr src; |
39 | static unsigned timeout_us; | 33 | struct in_addr dst; |
40 | static unsigned sent; | 34 | struct sockaddr_ll me; |
41 | static unsigned brd_sent; | 35 | struct sockaddr_ll he; |
42 | static unsigned received; | 36 | int sock; |
43 | static unsigned brd_recv; | 37 | |
44 | static unsigned req_recv; | 38 | int count; // = -1; |
39 | unsigned last; | ||
40 | unsigned timeout_us; | ||
41 | unsigned start; | ||
42 | |||
43 | unsigned sent; | ||
44 | unsigned brd_sent; | ||
45 | unsigned received; | ||
46 | unsigned brd_recv; | ||
47 | unsigned req_recv; | ||
48 | }; | ||
49 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
50 | #define src (G.src ) | ||
51 | #define dst (G.dst ) | ||
52 | #define me (G.me ) | ||
53 | #define he (G.he ) | ||
54 | #define sock (G.sock ) | ||
55 | #define count (G.count ) | ||
56 | #define last (G.last ) | ||
57 | #define timeout_us (G.timeout_us) | ||
58 | #define start (G.start ) | ||
59 | #define sent (G.sent ) | ||
60 | #define brd_sent (G.brd_sent ) | ||
61 | #define received (G.received ) | ||
62 | #define brd_recv (G.brd_recv ) | ||
63 | #define req_recv (G.req_recv ) | ||
64 | #define INIT_G() \ | ||
65 | do { \ | ||
66 | count = -1; \ | ||
67 | } while (0) | ||
45 | 68 | ||
46 | static int send_pack(struct in_addr *src_addr, | 69 | static int send_pack(struct in_addr *src_addr, |
47 | struct in_addr *dst_addr, struct sockaddr_ll *ME, | 70 | struct in_addr *dst_addr, struct sockaddr_ll *ME, |
@@ -106,8 +129,6 @@ static void finish(void) | |||
106 | 129 | ||
107 | static void catcher(void) | 130 | static void catcher(void) |
108 | { | 131 | { |
109 | static unsigned start; | ||
110 | |||
111 | unsigned now; | 132 | unsigned now; |
112 | 133 | ||
113 | now = MONOTONIC_US(); | 134 | now = MONOTONIC_US(); |
@@ -117,7 +138,9 @@ static void catcher(void) | |||
117 | if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000))) | 138 | if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000))) |
118 | finish(); | 139 | finish(); |
119 | 140 | ||
120 | count--; | 141 | /* count < 0 means "infinite count" */ |
142 | if (count > 0) | ||
143 | count--; | ||
121 | 144 | ||
122 | if (last == 0 || (now - last) > 500000) { | 145 | if (last == 0 || (now - last) > 500000) { |
123 | send_pack(&src, &dst, &me, &he); | 146 | send_pack(&src, &dst, &me, &he); |
@@ -236,6 +259,8 @@ int arping_main(int argc, char **argv) | |||
236 | char *target; | 259 | char *target; |
237 | unsigned char *packet; | 260 | unsigned char *packet; |
238 | 261 | ||
262 | INIT_G(); | ||
263 | |||
239 | sock = xsocket(PF_PACKET, SOCK_DGRAM, 0); | 264 | sock = xsocket(PF_PACKET, SOCK_DGRAM, 0); |
240 | 265 | ||
241 | // Drop suid root privileges | 266 | // Drop suid root privileges |
@@ -252,14 +277,9 @@ int arping_main(int argc, char **argv) | |||
252 | opt = getopt32(argv, "DUAqfbc:w:I:s:", | 277 | opt = getopt32(argv, "DUAqfbc:w:I:s:", |
253 | &str_count, &str_timeout, &device, &source); | 278 | &str_count, &str_timeout, &device, &source); |
254 | if (opt & 0x40) /* -c: count */ | 279 | if (opt & 0x40) /* -c: count */ |
255 | count = xatou(str_count); | 280 | count = xatoi_u(str_count); |
256 | if (opt & 0x80) /* -w: timeout */ | 281 | if (opt & 0x80) /* -w: timeout */ |
257 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000; | 282 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000; |
258 | //if (opt & 0x100) /* -I: interface */ | ||
259 | if (strlen(device) >= IF_NAMESIZE) { | ||
260 | bb_error_msg_and_die("interface name '%s' is too long", | ||
261 | device); | ||
262 | } | ||
263 | //if (opt & 0x200) /* -s: source */ | 283 | //if (opt & 0x200) /* -s: source */ |
264 | option_mask32 &= 0x3f; /* set respective flags */ | 284 | option_mask32 &= 0x3f; /* set respective flags */ |
265 | } | 285 | } |
@@ -272,8 +292,10 @@ int arping_main(int argc, char **argv) | |||
272 | struct ifreq ifr; | 292 | struct ifreq ifr; |
273 | 293 | ||
274 | memset(&ifr, 0, sizeof(ifr)); | 294 | memset(&ifr, 0, sizeof(ifr)); |
275 | strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); | 295 | strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name) - 1); |
276 | ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", device); | 296 | /* We use ifr.ifr_name in error msg so that problem |
297 | * with truncated name will be visible */ | ||
298 | ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", ifr.ifr_name); | ||
277 | ifindex = ifr.ifr_ifindex; | 299 | ifindex = ifr.ifr_ifindex; |
278 | 300 | ||
279 | xioctl(sock, SIOCGIFFLAGS, (char *) &ifr); | 301 | xioctl(sock, SIOCGIFFLAGS, (char *) &ifr); |
@@ -308,7 +330,7 @@ int arping_main(int argc, char **argv) | |||
308 | 330 | ||
309 | if (device) { | 331 | if (device) { |
310 | if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) | 332 | if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) |
311 | bb_error_msg("warning: interface %s is ignored", device); | 333 | bb_perror_msg("cannot bind to device %s", device); |
312 | } | 334 | } |
313 | memset(&saddr, 0, sizeof(saddr)); | 335 | memset(&saddr, 0, sizeof(saddr)); |
314 | saddr.sin_family = AF_INET; | 336 | saddr.sin_family = AF_INET; |
@@ -322,7 +344,7 @@ int arping_main(int argc, char **argv) | |||
322 | saddr.sin_addr = dst; | 344 | saddr.sin_addr = dst; |
323 | 345 | ||
324 | if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) | 346 | if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) |
325 | bb_perror_msg("warning: setsockopt(SO_DONTROUTE)"); | 347 | bb_perror_msg("setsockopt(SO_DONTROUTE)"); |
326 | xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); | 348 | xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); |
327 | if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { | 349 | if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { |
328 | bb_error_msg_and_die("getsockname"); | 350 | bb_error_msg_and_die("getsockname"); |
@@ -345,22 +367,22 @@ int arping_main(int argc, char **argv) | |||
345 | } | 367 | } |
346 | } | 368 | } |
347 | if (me.sll_halen == 0) { | 369 | if (me.sll_halen == 0) { |
348 | bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); | 370 | bb_error_msg("interface %s is not ARPable (no ll address)", device); |
349 | return (option_mask32 & DAD ? 0 : 2); | 371 | return (option_mask32 & DAD ? 0 : 2); |
350 | } | 372 | } |
351 | he = me; | 373 | he = me; |
352 | memset(he.sll_addr, -1, he.sll_halen); | 374 | memset(he.sll_addr, -1, he.sll_halen); |
353 | 375 | ||
376 | if (!src.s_addr && !(option_mask32 & DAD)) { | ||
377 | bb_error_msg_and_die("no src address in the non-DAD mode"); | ||
378 | } | ||
379 | |||
354 | if (!(option_mask32 & QUIET)) { | 380 | if (!(option_mask32 & QUIET)) { |
355 | printf("ARPING to %s from %s via %s\n", | 381 | printf("ARPING to %s from %s via %s\n", |
356 | inet_ntoa(dst), inet_ntoa(src), | 382 | inet_ntoa(dst), inet_ntoa(src), |
357 | device ? device : "unknown"); | 383 | device ? device : "unknown"); |
358 | } | 384 | } |
359 | 385 | ||
360 | if (!src.s_addr && !(option_mask32 & DAD)) { | ||
361 | bb_error_msg_and_die("no src address in the non-DAD mode"); | ||
362 | } | ||
363 | |||
364 | { | 386 | { |
365 | struct sigaction sa; | 387 | struct sigaction sa; |
366 | 388 | ||