diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-11 14:35:05 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-11 14:35:46 +0100 |
commit | d3162773d5c722cc1f5c5b1ea5171c8d3c208135 (patch) | |
tree | d2415fb7c76cc23e425967744e1a330be93cbf76 | |
parent | e015d0659fd3039c321b179190834c7e5909522a (diff) | |
download | busybox-w32-d3162773d5c722cc1f5c5b1ea5171c8d3c208135.tar.gz busybox-w32-d3162773d5c722cc1f5c5b1ea5171c8d3c208135.tar.bz2 busybox-w32-d3162773d5c722cc1f5c5b1ea5171c8d3c208135.zip |
arping: move packet buffer, sigset and struct ifreq to malloced "globals"
This way, we can zero them all in one go.
We do malloc() anyway, thus nothing is lost by mallocing "globals"
function old new delta
arping_main 1683 1686 +3
finish 100 86 -14
catcher 350 310 -40
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 3/-54) Total: -51 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/arping.c | 75 |
1 files changed, 34 insertions, 41 deletions
diff --git a/networking/arping.c b/networking/arping.c index 97e9e680a..a16f04b9f 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -79,8 +79,11 @@ struct globals { | |||
79 | unsigned received; | 79 | unsigned received; |
80 | unsigned brd_recv; | 80 | unsigned brd_recv; |
81 | unsigned req_recv; | 81 | unsigned req_recv; |
82 | |||
83 | struct ifreq ifr; | ||
84 | sigset_t sset; | ||
85 | unsigned char packet[4096]; | ||
82 | } FIX_ALIASING; | 86 | } FIX_ALIASING; |
83 | #define G (*(struct globals*)bb_common_bufsiz1) | ||
84 | #define src (G.src ) | 87 | #define src (G.src ) |
85 | #define dst (G.dst ) | 88 | #define dst (G.dst ) |
86 | #define me (G.me ) | 89 | #define me (G.me ) |
@@ -95,8 +98,11 @@ struct globals { | |||
95 | #define received (G.received ) | 98 | #define received (G.received ) |
96 | #define brd_recv (G.brd_recv ) | 99 | #define brd_recv (G.brd_recv ) |
97 | #define req_recv (G.req_recv ) | 100 | #define req_recv (G.req_recv ) |
101 | //#define G (*(struct globals*)bb_common_bufsiz1) | ||
102 | #define G (*ptr_to_globals) | ||
98 | #define INIT_G() do { \ | 103 | #define INIT_G() do { \ |
99 | setup_common_bufsiz(); \ | 104 | /*setup_common_bufsiz();*/ \ |
105 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | ||
100 | count = -1; \ | 106 | count = -1; \ |
101 | } while (0) | 107 | } while (0) |
102 | 108 | ||
@@ -183,15 +189,10 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
183 | struct arphdr *ah = (struct arphdr *) buf; | 189 | struct arphdr *ah = (struct arphdr *) buf; |
184 | unsigned char *p = (unsigned char *) (ah + 1); | 190 | unsigned char *p = (unsigned char *) (ah + 1); |
185 | struct in_addr src_ip, dst_ip; | 191 | struct in_addr src_ip, dst_ip; |
192 | |||
186 | /* moves below assume in_addr is 4 bytes big, ensure that */ | 193 | /* moves below assume in_addr is 4 bytes big, ensure that */ |
187 | struct BUG_in_addr_must_be_4 { | 194 | BUILD_BUG_ON(sizeof(struct in_addr) != 4); |
188 | char BUG_in_addr_must_be_4[ | 195 | BUILD_BUG_ON(sizeof(src_ip.s_addr) != 4); |
189 | sizeof(struct in_addr) == 4 ? 1 : -1 | ||
190 | ]; | ||
191 | char BUG_s_addr_must_be_4[ | ||
192 | sizeof(src_ip.s_addr) == 4 ? 1 : -1 | ||
193 | ]; | ||
194 | }; | ||
195 | 196 | ||
196 | /* Filter out wild packets */ | 197 | /* Filter out wild packets */ |
197 | if (FROM->sll_pkttype != PACKET_HOST | 198 | if (FROM->sll_pkttype != PACKET_HOST |
@@ -212,8 +213,10 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
212 | if (ah->ar_pro != htons(ETH_P_IP) | 213 | if (ah->ar_pro != htons(ETH_P_IP) |
213 | || (ah->ar_pln != 4) | 214 | || (ah->ar_pln != 4) |
214 | || (ah->ar_hln != me.sll_halen) | 215 | || (ah->ar_hln != me.sll_halen) |
215 | || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))) | 216 | || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln))) |
217 | ) { | ||
216 | return; | 218 | return; |
219 | } | ||
217 | 220 | ||
218 | move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); | 221 | move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); |
219 | move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln); | 222 | move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln); |
@@ -292,7 +295,6 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
292 | const char *device = "eth0"; | 295 | const char *device = "eth0"; |
293 | char *source = NULL; | 296 | char *source = NULL; |
294 | char *target; | 297 | char *target; |
295 | unsigned char *packet; | ||
296 | char *err_str; | 298 | char *err_str; |
297 | 299 | ||
298 | INIT_G(); | 300 | INIT_G(); |
@@ -316,27 +318,21 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
316 | err_str = xasprintf("interface %s %%s", device); | 318 | err_str = xasprintf("interface %s %%s", device); |
317 | xfunc_error_retval = 2; | 319 | xfunc_error_retval = 2; |
318 | 320 | ||
319 | { | 321 | /*memset(&G.ifr, 0, sizeof(G.ifr)); - zeroed by INIT_G */ |
320 | struct ifreq ifr; | 322 | strncpy_IFNAMSIZ(G.ifr.ifr_name, device); |
321 | 323 | ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &G.ifr, err_str, "not found"); | |
322 | memset(&ifr, 0, sizeof(ifr)); | 324 | me.sll_ifindex = G.ifr.ifr_ifindex; |
323 | strncpy_IFNAMSIZ(ifr.ifr_name, device); | ||
324 | /* We use ifr.ifr_name in error msg so that problem | ||
325 | * with truncated name will be visible */ | ||
326 | ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &ifr, err_str, "not found"); | ||
327 | me.sll_ifindex = ifr.ifr_ifindex; | ||
328 | 325 | ||
329 | xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr); | 326 | xioctl(sock_fd, SIOCGIFFLAGS, (char *) &G.ifr); |
330 | 327 | ||
331 | if (!(ifr.ifr_flags & IFF_UP)) { | 328 | if (!(G.ifr.ifr_flags & IFF_UP)) { |
332 | bb_error_msg_and_die(err_str, "is down"); | 329 | bb_error_msg_and_die(err_str, "is down"); |
333 | } | 330 | } |
334 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { | 331 | if (G.ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { |
335 | bb_error_msg(err_str, "is not ARPable"); | 332 | bb_error_msg(err_str, "is not ARPable"); |
336 | BUILD_BUG_ON(DAD != 2); | 333 | BUILD_BUG_ON(DAD != 2); |
337 | /* exit 0 if DAD, else exit 2 */ | 334 | /* exit 0 if DAD, else exit 2 */ |
338 | return (~option_mask32 & DAD); | 335 | return (~option_mask32 & DAD); |
339 | } | ||
340 | } | 336 | } |
341 | 337 | ||
342 | /* if (!inet_aton(target, &dst)) - not needed */ { | 338 | /* if (!inet_aton(target, &dst)) - not needed */ { |
@@ -413,8 +409,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
413 | printf(" from %s %s\n", inet_ntoa(src), device); | 409 | printf(" from %s %s\n", inet_ntoa(src), device); |
414 | } | 410 | } |
415 | 411 | ||
416 | packet = xmalloc(4096); | 412 | /*sigemptyset(&G.sset); - zeroed by INIT_G */ |
417 | 413 | sigaddset(&G.sset, SIGALRM); | |
414 | sigaddset(&G.sset, SIGINT); | ||
418 | signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); | 415 | signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish); |
419 | signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); | 416 | signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher); |
420 | 417 | ||
@@ -422,28 +419,24 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
422 | catcher(); | 419 | catcher(); |
423 | 420 | ||
424 | while (1) { | 421 | while (1) { |
425 | sigset_t sset; | ||
426 | struct sockaddr_ll from; | 422 | struct sockaddr_ll from; |
427 | socklen_t alen = sizeof(from); | 423 | socklen_t alen = sizeof(from); |
428 | int cc; | 424 | int cc; |
429 | 425 | ||
430 | sigemptyset(&sset); | ||
431 | sigaddset(&sset, SIGALRM); | ||
432 | sigaddset(&sset, SIGINT); | ||
433 | /* Unblock SIGALRM so that the previously called alarm() | 426 | /* Unblock SIGALRM so that the previously called alarm() |
434 | * can prevent recvfrom from blocking forever in case the | 427 | * can prevent recvfrom from blocking forever in case the |
435 | * inherited procmask is blocking SIGALRM. | 428 | * inherited procmask is blocking SIGALRM. |
436 | */ | 429 | */ |
437 | sigprocmask(SIG_UNBLOCK, &sset, NULL); | 430 | sigprocmask(SIG_UNBLOCK, &G.sset, NULL); |
438 | 431 | ||
439 | cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen); | 432 | cc = recvfrom(sock_fd, G.packet, sizeof(G.packet), 0, (struct sockaddr *) &from, &alen); |
440 | 433 | ||
441 | /* Don't allow SIGALRMs while we process the reply */ | 434 | /* Don't allow SIGALRMs while we process the reply */ |
442 | sigprocmask(SIG_BLOCK, &sset, NULL); | 435 | sigprocmask(SIG_BLOCK, &G.sset, NULL); |
443 | if (cc < 0) { | 436 | if (cc < 0) { |
444 | bb_perror_msg("recvfrom"); | 437 | bb_perror_msg("recvfrom"); |
445 | continue; | 438 | continue; |
446 | } | 439 | } |
447 | recv_pack(packet, cc, &from); | 440 | recv_pack(G.packet, cc, &from); |
448 | } | 441 | } |
449 | } | 442 | } |