diff options
-rw-r--r-- | networking/arping.c | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/networking/arping.c b/networking/arping.c index f9967d81e..fd2f52cdb 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -11,7 +11,6 @@ | |||
11 | //config: select PLATFORM_LINUX | 11 | //config: select PLATFORM_LINUX |
12 | //config: help | 12 | //config: help |
13 | //config: Ping hosts by ARP packets. | 13 | //config: Ping hosts by ARP packets. |
14 | //config: | ||
15 | 14 | ||
16 | //applet:IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 15 | //applet:IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
17 | 16 | ||
@@ -45,14 +44,23 @@ | |||
45 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | 44 | #define MONOTONIC_US() ((unsigned)monotonic_us()) |
46 | 45 | ||
47 | enum { | 46 | enum { |
48 | DAD = 1, | 47 | UNSOLICITED = 1 << 0, |
49 | UNSOLICITED = 2, | 48 | DAD = 1 << 1, |
50 | ADVERT = 4, | 49 | ADVERT = 1 << 2, |
51 | QUIET = 8, | 50 | QUIET = 1 << 3, |
52 | QUIT_ON_REPLY = 16, | 51 | QUIT_ON_REPLY = 1 << 4, |
53 | BCAST_ONLY = 32, | 52 | BCAST_ONLY = 1 << 5, |
54 | UNICASTING = 64 | 53 | UNICASTING = 1 << 6, |
54 | TIMEOUT = 1 << 7, | ||
55 | }; | 55 | }; |
56 | #define GETOPT32(str_timeout, device, source) \ | ||
57 | getopt32(argv, "^" \ | ||
58 | "UDAqfbc:+w:I:s:" \ | ||
59 | /* Dad also sets quit_on_reply, */ \ | ||
60 | /* Advert also sets unsolicited: */ \ | ||
61 | "\0" "=1:Df:AU", \ | ||
62 | &count, &str_timeout, &device, &source \ | ||
63 | ); | ||
56 | 64 | ||
57 | struct globals { | 65 | struct globals { |
58 | struct in_addr src; | 66 | struct in_addr src; |
@@ -92,21 +100,15 @@ struct globals { | |||
92 | count = -1; \ | 100 | count = -1; \ |
93 | } while (0) | 101 | } while (0) |
94 | 102 | ||
95 | // If GNUisms are not available... | ||
96 | //static void *mempcpy(void *_dst, const void *_src, int n) | ||
97 | //{ | ||
98 | // memcpy(_dst, _src, n); | ||
99 | // return (char*)_dst + n; | ||
100 | //} | ||
101 | |||
102 | static int send_pack(struct in_addr *src_addr, | 103 | static int send_pack(struct in_addr *src_addr, |
103 | struct in_addr *dst_addr, struct sockaddr_ll *ME, | 104 | struct in_addr *dst_addr, |
105 | struct sockaddr_ll *ME, | ||
104 | struct sockaddr_ll *HE) | 106 | struct sockaddr_ll *HE) |
105 | { | 107 | { |
106 | int err; | 108 | int err; |
107 | unsigned char buf[256]; | 109 | unsigned char buf[256]; |
108 | struct arphdr *ah = (struct arphdr *) buf; | 110 | struct arphdr *ah = (struct arphdr *) buf; |
109 | unsigned char *p = (unsigned char *) (ah + 1); | 111 | unsigned char *p; |
110 | 112 | ||
111 | ah->ar_hrd = htons(ARPHRD_ETHER); | 113 | ah->ar_hrd = htons(ARPHRD_ETHER); |
112 | ah->ar_pro = htons(ETH_P_IP); | 114 | ah->ar_pro = htons(ETH_P_IP); |
@@ -114,6 +116,7 @@ static int send_pack(struct in_addr *src_addr, | |||
114 | ah->ar_pln = 4; | 116 | ah->ar_pln = 4; |
115 | ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); | 117 | ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); |
116 | 118 | ||
119 | p = (unsigned char *) (ah + 1); | ||
117 | p = mempcpy(p, &ME->sll_addr, ah->ar_hln); | 120 | p = mempcpy(p, &ME->sll_addr, ah->ar_hln); |
118 | p = mempcpy(p, src_addr, 4); | 121 | p = mempcpy(p, src_addr, 4); |
119 | 122 | ||
@@ -303,16 +306,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
303 | unsigned opt; | 306 | unsigned opt; |
304 | char *str_timeout; | 307 | char *str_timeout; |
305 | 308 | ||
306 | /* Dad also sets quit_on_reply. | 309 | opt = GETOPT32(str_timeout, device, source); |
307 | * Advert also sets unsolicited. | 310 | if (opt & TIMEOUT) |
308 | */ | ||
309 | opt = getopt32(argv, "^" "DUAqfbc:+w:I:s:" "\0" "=1:Df:AU", | ||
310 | &count, &str_timeout, &device, &source | ||
311 | ); | ||
312 | if (opt & 0x80) /* -w: timeout */ | ||
313 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; | 311 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; |
314 | //if (opt & 0x200) /* -s: source */ | ||
315 | option_mask32 &= 0x3f; /* set respective flags */ | ||
316 | } | 312 | } |
317 | 313 | ||
318 | target = argv[optind]; | 314 | target = argv[optind]; |
@@ -336,7 +332,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
336 | } | 332 | } |
337 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { | 333 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { |
338 | bb_error_msg(err_str, "is not ARPable"); | 334 | bb_error_msg(err_str, "is not ARPable"); |
339 | return (option_mask32 & DAD ? 0 : 2); | 335 | BUILD_BUG_ON(DAD != 2); |
336 | /* exit 0 if DAD, else exit 2 */ | ||
337 | return (~option_mask32 & DAD); | ||
340 | } | 338 | } |
341 | } | 339 | } |
342 | 340 | ||
@@ -401,7 +399,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
401 | } | 399 | } |
402 | if (me.sll_halen == 0) { | 400 | if (me.sll_halen == 0) { |
403 | bb_error_msg(err_str, "is not ARPable (no ll address)"); | 401 | bb_error_msg(err_str, "is not ARPable (no ll address)"); |
404 | return (option_mask32 & DAD ? 0 : 2); | 402 | BUILD_BUG_ON(DAD != 2); |
403 | /* exit 0 if DAD, else exit 2 */ | ||
404 | return (~option_mask32 & DAD); | ||
405 | } | 405 | } |
406 | he = me; | 406 | he = me; |
407 | memset(he.sll_addr, -1, he.sll_halen); | 407 | memset(he.sll_addr, -1, he.sll_halen); |