aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-02-11 14:35:05 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-02-11 14:35:46 +0100
commitd3162773d5c722cc1f5c5b1ea5171c8d3c208135 (patch)
treed2415fb7c76cc23e425967744e1a330be93cbf76
parente015d0659fd3039c321b179190834c7e5909522a (diff)
downloadbusybox-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.c75
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}