aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-23 09:15:26 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-23 09:15:26 +0000
commitfff9b699f19bf4e687b755f3a0faecbe958258a9 (patch)
treefad71af79fdd3ab44a5285fc883b53341f72cd38
parent3831c91c95116b9a9b28f67e998e53a80b3e33bd (diff)
downloadbusybox-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.c86
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
21static struct in_addr src;
22static struct in_addr dst;
23static struct sockaddr_ll me;
24static struct sockaddr_ll he;
25static unsigned last;
26
27enum { 21enum {
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
37static int sock; 31struct globals {
38static unsigned count = UINT_MAX; 32 struct in_addr src;
39static unsigned timeout_us; 33 struct in_addr dst;
40static unsigned sent; 34 struct sockaddr_ll me;
41static unsigned brd_sent; 35 struct sockaddr_ll he;
42static unsigned received; 36 int sock;
43static unsigned brd_recv; 37
44static 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
46static int send_pack(struct in_addr *src_addr, 69static 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
107static void catcher(void) 130static 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