diff options
author | Rob Landley <rob@landley.net> | 2006-03-30 21:50:57 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-03-30 21:50:57 +0000 |
commit | 8ea5205726e2ebcd2b12737f47b5cd1a9c1c8289 (patch) | |
tree | 7fd85ad55669b913b1ef1c0537b286f91126fd69 | |
parent | 1f6dc6d35803dd1cf28653a0b521a26084ef3d43 (diff) | |
download | busybox-w32-8ea5205726e2ebcd2b12737f47b5cd1a9c1c8289.tar.gz busybox-w32-8ea5205726e2ebcd2b12737f47b5cd1a9c1c8289.tar.bz2 busybox-w32-8ea5205726e2ebcd2b12737f47b5cd1a9c1c8289.zip |
Shrink patch from Bernhard Fischer.
-rw-r--r-- | networking/arping.c | 150 |
1 files changed, 69 insertions, 81 deletions
diff --git a/networking/arping.c b/networking/arping.c index b30cb535e..90a03a58e 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -1,10 +1,8 @@ | |||
1 | /* vi:set ts=4:*/ | ||
1 | /* | 2 | /* |
2 | * arping.c - Ping hosts by ARP requests/replies | 3 | * arping.c - Ping hosts by ARP requests/replies |
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or | 5 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | 6 | * |
9 | * Author: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 7 | * Author: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
10 | * Busybox port: Nick Fedchik <nick@fedchik.org.ua> | 8 | * Busybox port: Nick Fedchik <nick@fedchik.org.ua> |
@@ -26,29 +24,32 @@ | |||
26 | 24 | ||
27 | #include "busybox.h" | 25 | #include "busybox.h" |
28 | 26 | ||
29 | #define APPLET_NAME "arping" | ||
30 | |||
31 | static struct in_addr src; | 27 | static struct in_addr src; |
32 | static struct in_addr dst; | 28 | static struct in_addr dst; |
33 | static struct sockaddr_ll me; | 29 | static struct sockaddr_ll me; |
34 | static struct sockaddr_ll he; | 30 | static struct sockaddr_ll he; |
35 | static struct timeval last; | 31 | static struct timeval last; |
36 | static int dad; | 32 | struct cfg_s { |
37 | static int unsolicited; | 33 | int dad:1; |
38 | static int advert; | 34 | int unsolicited:1; |
39 | static int quiet; | 35 | int advert:1; |
40 | static int quit_on_reply = 0; | 36 | int quiet:1; |
37 | int quit_on_reply:1; | ||
38 | int unicasting:1; | ||
39 | int broadcast_only:1; | ||
40 | }; | ||
41 | static struct cfg_s cfg; | ||
42 | |||
43 | static int s; | ||
41 | static int count = -1; | 44 | static int count = -1; |
42 | static int timeout; | 45 | static int timeout; |
43 | static int unicasting; | ||
44 | static int s; | ||
45 | static int broadcast_only; | ||
46 | static int sent; | 46 | static int sent; |
47 | static int brd_sent; | 47 | static int brd_sent; |
48 | static int received; | 48 | static int received; |
49 | static int brd_recv; | 49 | static int brd_recv; |
50 | static int req_recv; | 50 | static int req_recv; |
51 | 51 | ||
52 | |||
52 | #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ | 53 | #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ |
53 | ((tv1).tv_usec-(tv2).tv_usec)/1000 ) | 54 | ((tv1).tv_usec-(tv2).tv_usec)/1000 ) |
54 | #if 0 | 55 | #if 0 |
@@ -69,7 +70,7 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
69 | { | 70 | { |
70 | int err; | 71 | int err; |
71 | struct timeval now; | 72 | struct timeval now; |
72 | unsigned char buf[256]; | 73 | RESERVE_CONFIG_UBUFFER(buf, 256); |
73 | struct arphdr *ah = (struct arphdr *) buf; | 74 | struct arphdr *ah = (struct arphdr *) buf; |
74 | unsigned char *p = (unsigned char *) (ah + 1); | 75 | unsigned char *p = (unsigned char *) (ah + 1); |
75 | 76 | ||
@@ -78,7 +79,7 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
78 | ah->ar_pro = htons(ETH_P_IP); | 79 | ah->ar_pro = htons(ETH_P_IP); |
79 | ah->ar_hln = ME->sll_halen; | 80 | ah->ar_hln = ME->sll_halen; |
80 | ah->ar_pln = 4; | 81 | ah->ar_pln = 4; |
81 | ah->ar_op = advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); | 82 | ah->ar_op = cfg.advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); |
82 | 83 | ||
83 | memcpy(p, &ME->sll_addr, ah->ar_hln); | 84 | memcpy(p, &ME->sll_addr, ah->ar_hln); |
84 | p += ME->sll_halen; | 85 | p += ME->sll_halen; |
@@ -86,7 +87,7 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
86 | memcpy(p, src_addr, 4); | 87 | memcpy(p, src_addr, 4); |
87 | p += 4; | 88 | p += 4; |
88 | 89 | ||
89 | if (advert) | 90 | if (cfg.advert) |
90 | memcpy(p, &ME->sll_addr, ah->ar_hln); | 91 | memcpy(p, &ME->sll_addr, ah->ar_hln); |
91 | else | 92 | else |
92 | memcpy(p, &HE->sll_addr, ah->ar_hln); | 93 | memcpy(p, &HE->sll_addr, ah->ar_hln); |
@@ -100,15 +101,16 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
100 | if (err == p - buf) { | 101 | if (err == p - buf) { |
101 | last = now; | 102 | last = now; |
102 | sent++; | 103 | sent++; |
103 | if (!unicasting) | 104 | if (!cfg.unicasting) |
104 | brd_sent++; | 105 | brd_sent++; |
105 | } | 106 | } |
107 | RELEASE_CONFIG_BUFFER(buf); | ||
106 | return err; | 108 | return err; |
107 | } | 109 | } |
108 | 110 | ||
109 | static void finish(void) | 111 | static void finish(void) |
110 | { | 112 | { |
111 | if (!quiet) { | 113 | if (!cfg.quiet) { |
112 | printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent); | 114 | printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent); |
113 | printf("Received %d repl%s", received, (received > 1) ? "ies" : "y"); | 115 | printf("Received %d repl%s", received, (received > 1) ? "ies" : "y"); |
114 | if (brd_recv || req_recv) { | 116 | if (brd_recv || req_recv) { |
@@ -122,9 +124,9 @@ static void finish(void) | |||
122 | putchar('\n'); | 124 | putchar('\n'); |
123 | fflush(stdout); | 125 | fflush(stdout); |
124 | } | 126 | } |
125 | if (dad) | 127 | if (cfg.dad) |
126 | exit(!!received); | 128 | exit(!!received); |
127 | if (unsolicited) | 129 | if (cfg.unsolicited) |
128 | exit(0); | 130 | exit(0); |
129 | exit(!received); | 131 | exit(!received); |
130 | } | 132 | } |
@@ -145,7 +147,7 @@ static void catcher(void) | |||
145 | 147 | ||
146 | if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) { | 148 | if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) { |
147 | send_pack(s, &src, &dst, &me, &he); | 149 | send_pack(s, &src, &dst, &me, &he); |
148 | if (count == 0 && unsolicited) | 150 | if (count == 0 && cfg.unsolicited) |
149 | finish(); | 151 | finish(); |
150 | } | 152 | } |
151 | alarm(1); | 153 | alarm(1); |
@@ -153,13 +155,10 @@ static void catcher(void) | |||
153 | 155 | ||
154 | static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | 156 | static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) |
155 | { | 157 | { |
156 | struct timeval tv; | ||
157 | struct arphdr *ah = (struct arphdr *) buf; | 158 | struct arphdr *ah = (struct arphdr *) buf; |
158 | unsigned char *p = (unsigned char *) (ah + 1); | 159 | unsigned char *p = (unsigned char *) (ah + 1); |
159 | struct in_addr src_ip, dst_ip; | 160 | struct in_addr src_ip, dst_ip; |
160 | 161 | ||
161 | gettimeofday(&tv, NULL); | ||
162 | |||
163 | /* Filter out wild packets */ | 162 | /* Filter out wild packets */ |
164 | if (FROM->sll_pkttype != PACKET_HOST && | 163 | if (FROM->sll_pkttype != PACKET_HOST && |
165 | FROM->sll_pkttype != PACKET_BROADCAST && | 164 | FROM->sll_pkttype != PACKET_BROADCAST && |
@@ -187,7 +186,7 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
187 | return 0; | 186 | return 0; |
188 | memcpy(&src_ip, p + ah->ar_hln, 4); | 187 | memcpy(&src_ip, p + ah->ar_hln, 4); |
189 | memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); | 188 | memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); |
190 | if (!dad) { | 189 | if (!cfg.dad) { |
191 | if (src_ip.s_addr != dst.s_addr) | 190 | if (src_ip.s_addr != dst.s_addr) |
192 | return 0; | 191 | return 0; |
193 | if (src.s_addr != dst_ip.s_addr) | 192 | if (src.s_addr != dst_ip.s_addr) |
@@ -215,8 +214,11 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
215 | if (src.s_addr && src.s_addr != dst_ip.s_addr) | 214 | if (src.s_addr && src.s_addr != dst_ip.s_addr) |
216 | return 0; | 215 | return 0; |
217 | } | 216 | } |
218 | if (!quiet) { | 217 | if (!cfg.quiet) { |
219 | int s_printed = 0; | 218 | int s_printed = 0; |
219 | struct timeval tv; | ||
220 | |||
221 | gettimeofday(&tv, NULL); | ||
220 | 222 | ||
221 | printf("%s ", | 223 | printf("%s ", |
222 | FROM->sll_pkttype == PACKET_HOST ? "Unicast" : "Broadcast"); | 224 | FROM->sll_pkttype == PACKET_HOST ? "Unicast" : "Broadcast"); |
@@ -234,6 +236,7 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
234 | printf("[%s]", | 236 | printf("[%s]", |
235 | ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); | 237 | ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); |
236 | } | 238 | } |
239 | |||
237 | if (last.tv_sec) { | 240 | if (last.tv_sec) { |
238 | long usecs = (tv.tv_sec - last.tv_sec) * 1000000 + | 241 | long usecs = (tv.tv_sec - last.tv_sec) * 1000000 + |
239 | tv.tv_usec - last.tv_usec; | 242 | tv.tv_usec - last.tv_usec; |
@@ -251,48 +254,46 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
251 | brd_recv++; | 254 | brd_recv++; |
252 | if (ah->ar_op == htons(ARPOP_REQUEST)) | 255 | if (ah->ar_op == htons(ARPOP_REQUEST)) |
253 | req_recv++; | 256 | req_recv++; |
254 | if (quit_on_reply) | 257 | if (cfg.quit_on_reply) |
255 | finish(); | 258 | finish(); |
256 | if (!broadcast_only) { | 259 | if (!cfg.broadcast_only) { |
257 | memcpy(he.sll_addr, p, me.sll_halen); | 260 | memcpy(he.sll_addr, p, me.sll_halen); |
258 | unicasting = 1; | 261 | cfg.unicasting = 1; |
259 | } | 262 | } |
260 | return 1; | 263 | return 1; |
261 | } | 264 | } |
262 | 265 | ||
263 | int arping_main(int argc, char **argv) | 266 | int arping_main(int argc, char **argv) |
264 | { | 267 | { |
265 | int socket_errno; | ||
266 | int ch; | 268 | int ch; |
267 | uid_t uid = getuid(); | ||
268 | char *device = "eth0"; | 269 | char *device = "eth0"; |
269 | int ifindex = 0; | 270 | int ifindex; |
270 | char *source = NULL; | 271 | char *source = NULL; |
271 | char *target; | 272 | char *target; |
272 | 273 | ||
273 | s = socket(PF_PACKET, SOCK_DGRAM, 0); | 274 | s = socket(PF_PACKET, SOCK_DGRAM, 0); |
274 | socket_errno = errno; | 275 | ifindex = errno; |
275 | 276 | ||
276 | setuid(uid); | 277 | setuid(getuid()); |
277 | 278 | ||
278 | while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:")) != EOF) { | 279 | while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:")) != EOF) { |
279 | switch (ch) { | 280 | switch (ch) { |
280 | case 'b': | 281 | case 'b': |
281 | broadcast_only = 1; | 282 | cfg.broadcast_only = 1; |
282 | break; | 283 | break; |
283 | case 'D': | 284 | case 'D': |
284 | dad++; | 285 | cfg.dad = 1; |
285 | quit_on_reply = 1; | 286 | cfg.quit_on_reply = 1; |
286 | break; | 287 | break; |
287 | case 'U': | 288 | case 'U': |
288 | unsolicited++; | 289 | cfg.unsolicited = 1; |
289 | break; | 290 | break; |
290 | case 'A': | 291 | case 'A': |
291 | advert++; | 292 | cfg.advert = 1; |
292 | unsolicited++; | 293 | cfg.unsolicited = 1; |
293 | break; | 294 | break; |
294 | case 'q': | 295 | case 'q': |
295 | quiet++; | 296 | cfg.quiet = 1; |
296 | break; | 297 | break; |
297 | case 'c': | 298 | case 'c': |
298 | count = atoi(optarg); | 299 | count = atoi(optarg); |
@@ -304,14 +305,13 @@ int arping_main(int argc, char **argv) | |||
304 | if (optarg == NULL) | 305 | if (optarg == NULL) |
305 | bb_show_usage(); | 306 | bb_show_usage(); |
306 | if (bb_strlen(optarg) > IF_NAMESIZE) { | 307 | if (bb_strlen(optarg) > IF_NAMESIZE) { |
307 | bb_error_msg("Interface name `%s' must be less than %d", optarg, | 308 | bb_error_msg_and_die("Interface name `%s' must be less than %d", |
308 | IF_NAMESIZE); | 309 | optarg, IF_NAMESIZE); |
309 | exit(2); | ||
310 | } | 310 | } |
311 | device = optarg; | 311 | device = optarg; |
312 | break; | 312 | break; |
313 | case 'f': | 313 | case 'f': |
314 | quit_on_reply = 1; | 314 | cfg.quit_on_reply = 1; |
315 | break; | 315 | break; |
316 | case 's': | 316 | case 's': |
317 | source = optarg; | 317 | source = optarg; |
@@ -329,11 +329,11 @@ int arping_main(int argc, char **argv) | |||
329 | bb_show_usage(); | 329 | bb_show_usage(); |
330 | 330 | ||
331 | target = *argv; | 331 | target = *argv; |
332 | 332 | bb_default_error_retval = 2; | |
333 | 333 | ||
334 | if (s < 0) { | 334 | if (s < 0) { |
335 | bb_error_msg("socket"); | 335 | bb_perror_msg("socket"); |
336 | exit(socket_errno); | 336 | exit(ifindex); |
337 | } | 337 | } |
338 | 338 | ||
339 | { | 339 | { |
@@ -342,22 +342,19 @@ int arping_main(int argc, char **argv) | |||
342 | memset(&ifr, 0, sizeof(ifr)); | 342 | memset(&ifr, 0, sizeof(ifr)); |
343 | strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); | 343 | strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); |
344 | if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { | 344 | if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { |
345 | bb_error_msg("Interface %s not found", device); | 345 | bb_error_msg_and_die("Interface %s not found", device); |
346 | exit(2); | ||
347 | } | 346 | } |
348 | ifindex = ifr.ifr_ifindex; | 347 | ifindex = ifr.ifr_ifindex; |
349 | 348 | ||
350 | if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) { | 349 | if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) { |
351 | bb_error_msg("SIOCGIFFLAGS"); | 350 | bb_error_msg_and_die("SIOCGIFFLAGS"); |
352 | exit(2); | ||
353 | } | 351 | } |
354 | if (!(ifr.ifr_flags & IFF_UP)) { | 352 | if (!(ifr.ifr_flags & IFF_UP)) { |
355 | bb_error_msg("Interface %s is down", device); | 353 | bb_error_msg_and_die("Interface %s is down", device); |
356 | exit(2); | ||
357 | } | 354 | } |
358 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { | 355 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { |
359 | bb_error_msg("Interface %s is not ARPable", device); | 356 | bb_error_msg("Interface %s is not ARPable", device); |
360 | exit(dad ? 0 : 2); | 357 | exit(cfg.dad ? 0 : 2); |
361 | } | 358 | } |
362 | } | 359 | } |
363 | 360 | ||
@@ -366,27 +363,24 @@ int arping_main(int argc, char **argv) | |||
366 | 363 | ||
367 | hp = gethostbyname2(target, AF_INET); | 364 | hp = gethostbyname2(target, AF_INET); |
368 | if (!hp) { | 365 | if (!hp) { |
369 | bb_error_msg("invalid or unknown target %s", target); | 366 | bb_error_msg_and_die("invalid or unknown target %s", target); |
370 | exit(2); | ||
371 | } | 367 | } |
372 | memcpy(&dst, hp->h_addr, 4); | 368 | memcpy(&dst, hp->h_addr, 4); |
373 | } | 369 | } |
374 | 370 | ||
375 | if (source && !inet_aton(source, &src)) { | 371 | if (source && !inet_aton(source, &src)) { |
376 | bb_error_msg("invalid source address %s", source); | 372 | bb_error_msg_and_die("invalid source address %s", source); |
377 | exit(2); | ||
378 | } | 373 | } |
379 | 374 | ||
380 | if (!dad && unsolicited && src.s_addr == 0) | 375 | if (!cfg.dad && cfg.unsolicited && src.s_addr == 0) |
381 | src = dst; | 376 | src = dst; |
382 | 377 | ||
383 | if (!dad || src.s_addr) { | 378 | if (!cfg.dad || src.s_addr) { |
384 | struct sockaddr_in saddr; | 379 | struct sockaddr_in saddr; |
385 | int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); | 380 | int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); |
386 | 381 | ||
387 | if (probe_fd < 0) { | 382 | if (probe_fd < 0) { |
388 | bb_error_msg("socket"); | 383 | bb_error_msg_and_die("socket"); |
389 | exit(2); | ||
390 | } | 384 | } |
391 | if (device) { | 385 | if (device) { |
392 | if (setsockopt | 386 | if (setsockopt |
@@ -399,10 +393,9 @@ int arping_main(int argc, char **argv) | |||
399 | if (src.s_addr) { | 393 | if (src.s_addr) { |
400 | saddr.sin_addr = src; | 394 | saddr.sin_addr = src; |
401 | if (bind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { | 395 | if (bind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { |
402 | bb_error_msg("bind"); | 396 | bb_error_msg_and_die("bind"); |
403 | exit(2); | ||
404 | } | 397 | } |
405 | } else if (!dad) { | 398 | } else if (!cfg.dad) { |
406 | int on = 1; | 399 | int on = 1; |
407 | socklen_t alen = sizeof(saddr); | 400 | socklen_t alen = sizeof(saddr); |
408 | 401 | ||
@@ -412,16 +405,14 @@ int arping_main(int argc, char **argv) | |||
412 | if (setsockopt | 405 | if (setsockopt |
413 | (probe_fd, SOL_SOCKET, SO_DONTROUTE, (char *) &on, | 406 | (probe_fd, SOL_SOCKET, SO_DONTROUTE, (char *) &on, |
414 | sizeof(on)) == -1) | 407 | sizeof(on)) == -1) |
415 | perror("WARNING: setsockopt(SO_DONTROUTE)"); | 408 | bb_perror_msg("WARNING: setsockopt(SO_DONTROUTE)"); |
416 | if (connect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) | 409 | if (connect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) |
417 | == -1) { | 410 | == -1) { |
418 | bb_error_msg("connect"); | 411 | bb_error_msg_and_die("connect"); |
419 | exit(2); | ||
420 | } | 412 | } |
421 | if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == | 413 | if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == |
422 | -1) { | 414 | -1) { |
423 | bb_error_msg("getsockname"); | 415 | bb_error_msg_and_die("getsockname"); |
424 | exit(2); | ||
425 | } | 416 | } |
426 | src = saddr.sin_addr; | 417 | src = saddr.sin_addr; |
427 | } | 418 | } |
@@ -432,34 +423,31 @@ int arping_main(int argc, char **argv) | |||
432 | me.sll_ifindex = ifindex; | 423 | me.sll_ifindex = ifindex; |
433 | me.sll_protocol = htons(ETH_P_ARP); | 424 | me.sll_protocol = htons(ETH_P_ARP); |
434 | if (bind(s, (struct sockaddr *) &me, sizeof(me)) == -1) { | 425 | if (bind(s, (struct sockaddr *) &me, sizeof(me)) == -1) { |
435 | bb_error_msg("bind"); | 426 | bb_error_msg_and_die("bind"); |
436 | exit(2); | ||
437 | } | 427 | } |
438 | 428 | ||
439 | { | 429 | { |
440 | socklen_t alen = sizeof(me); | 430 | socklen_t alen = sizeof(me); |
441 | 431 | ||
442 | if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) { | 432 | if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) { |
443 | bb_error_msg("getsockname"); | 433 | bb_error_msg_and_die("getsockname"); |
444 | exit(2); | ||
445 | } | 434 | } |
446 | } | 435 | } |
447 | if (me.sll_halen == 0) { | 436 | if (me.sll_halen == 0) { |
448 | bb_error_msg("Interface \"%s\" is not ARPable (no ll address)", device); | 437 | bb_error_msg("Interface \"%s\" is not ARPable (no ll address)", device); |
449 | exit(dad ? 0 : 2); | 438 | exit(cfg.dad ? 0 : 2); |
450 | } | 439 | } |
451 | he = me; | 440 | he = me; |
452 | memset(he.sll_addr, -1, he.sll_halen); | 441 | memset(he.sll_addr, -1, he.sll_halen); |
453 | 442 | ||
454 | if (!quiet) { | 443 | if (!cfg.quiet) { |
455 | printf("ARPING to %s", inet_ntoa(dst)); | 444 | printf("ARPING to %s", inet_ntoa(dst)); |
456 | printf(" from %s via %s\n", inet_ntoa(src), | 445 | printf(" from %s via %s\n", inet_ntoa(src), |
457 | device ? device : "unknown"); | 446 | device ? device : "unknown"); |
458 | } | 447 | } |
459 | 448 | ||
460 | if (!src.s_addr && !dad) { | 449 | if (!src.s_addr && !cfg.dad) { |
461 | bb_error_msg("no src address in the non-DAD mode"); | 450 | bb_error_msg_and_die("no src address in the non-DAD mode"); |
462 | exit(2); | ||
463 | } | 451 | } |
464 | 452 | ||
465 | { | 453 | { |