Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 94734 Details for
Bug 144526
arpping misses a signal for timeout causing latest /etc/init.d/net.* scripts to hang
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
arping diff -u
arping.diff (text/plain), 9.43 KB, created by
erik quanstrom
on 2006-08-20 17:23:05 UTC
(
hide
)
Description:
arping diff -u
Filename:
MIME Type:
Creator:
erik quanstrom
Created:
2006-08-20 17:23:05 UTC
Size:
9.43 KB
patch
obsolete
>--- arping.c 2006-08-20 19:14:39.000000000 -0500 >+++ /var/tmp/portage/iputils-021109-r3/work/iputils/arping.c 2006-08-20 19:17:40.000000000 -0500 >@@ -7,9 +7,6 @@ > * 2 of the License, or (at your option) any later version. > * > * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> >- * 2006.08.18 erik quanstrom <quanstro@quanstro.net> >- * use select instead of signals so timeouts will work. >- * > */ > > #include <stdlib.h> >@@ -18,6 +15,7 @@ > #include <linux/sockios.h> > #include <sys/file.h> > #include <sys/time.h> >+#include <sys/signal.h> > #include <sys/ioctl.h> > #include <linux/if.h> > #include <linux/if_arp.h> >@@ -31,12 +29,12 @@ > #include <string.h> > #include <netinet/in.h> > #include <arpa/inet.h> >-#include <stdarg.h> > > #include "SNAPSHOT.h" > > static void usage(void) __attribute__((noreturn)); > >+int quit_on_reply=0; > char *device="eth0"; > int ifindex; > char *source; >@@ -45,10 +43,7 @@ > int dad, unsolicited, advert; > int quiet; > int count=-1; >-int ntosend=-1; >-int ntorecv=-1; > int timeout; >-struct timeval timeouttv; > int unicasting; > int s; > int broadcast_only; >@@ -64,19 +59,6 @@ > #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ > ((tv1).tv_usec-(tv2).tv_usec)/1000 ) > >-#define pkttrace(...) /* fprintf(stderr, __VA_ARGS__) */ >- >-void >-errexit(int err, const char* fmt, ...) >-{ >- va_list ap; >- >- va_start(ap, fmt); >- vfprintf(stderr, fmt, ap); >- va_end(ap); >- exit(err); >-} >- > void usage(void) > { > fprintf(stderr, >@@ -97,6 +79,16 @@ > exit(2); > } > >+void set_signal(int signo, void (*handler)(void)) >+{ >+ struct sigaction sa; >+ >+ memset(&sa, 0, sizeof(sa)); >+ sa.sa_handler = (void (*)(int))handler; >+ sa.sa_flags = SA_RESTART; >+ sigaction(signo, &sa, NULL); >+} >+ > int send_pack(int s, struct in_addr src, struct in_addr dst, > struct sockaddr_ll *ME, struct sockaddr_ll *HE) > { >@@ -130,9 +122,7 @@ > p+=4; > > gettimeofday(&now, NULL); >- pkttrace("sendto->\n"); > err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE)); >- pkttrace("sendto<-\n"); > if (err == p-buf) { > last = now; > sent++; >@@ -145,20 +135,20 @@ > void finish(void) > { > if (!quiet) { >- fflush(stdout); >- fprintf(stderr, "Sent %d probes (%d broadcast(s))\n", sent, brd_sent); >- fprintf(stderr, "Received %d response(s)", received); >+ printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent); >+ printf("Received %d response(s)", received); > if (brd_recv || req_recv) { >- fprintf(stderr, " ("); >+ printf(" ("); > if (req_recv) >- fprintf(stderr, "%d request(s)", req_recv); >+ printf("%d request(s)", req_recv); > if (brd_recv) >- fprintf(stderr, "%s%d broadcast(s)", >+ printf("%s%d broadcast(s)", > req_recv ? ", " : "", > brd_recv); >- fprintf(stderr, ")"); >+ printf(")"); > } >- fprintf(stderr, "\n"); >+ printf("\n"); >+ fflush(stdout); > } > if (dad) > exit(!!received); >@@ -167,13 +157,34 @@ > exit(!received); > } > >+void catcher(void) >+{ >+ struct timeval tv; >+ >+ gettimeofday(&tv, NULL); >+ >+ if (start.tv_sec==0) >+ start = tv; >+ >+ if (count-- == 0 || (timeout && MS_TDIFF(tv,start) > timeout*1000 + 500)) >+ finish(); >+ >+ if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { >+ send_pack(s, src, dst, &me, &he); >+ if (count == 0 && unsolicited) >+ finish(); >+ } >+ alarm(1); >+} >+ > void print_hex(unsigned char *p, int len) > { > int i; >- for (i=0; i<len-1; i++) >- printf("%02X:", p[i]); >- if(len) >+ for (i=0; i<len; i++) { > printf("%02X", p[i]); >+ if (i != len-1) >+ printf(":"); >+ } > } > > int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) >@@ -274,6 +285,8 @@ > brd_recv++; > if (ah->ar_op == htons(ARPOP_REQUEST)) > req_recv++; >+ if (quit_on_reply) >+ finish(); > if(!broadcast_only) { > memcpy(he.sll_addr, p, me.sll_halen); > unicasting=1; >@@ -281,75 +294,26 @@ > return 1; > } > >- >-unsigned char packet[4096]; // too big for stack on some arch. >- >-void >-pktloop(void) >-{ >- struct sockaddr_ll from; >- socklen_t alen = sizeof(from); >- fd_set rset; >- struct timeval tmo; >- int cc, i; >- >- for(;;){ >- if(ntosend-- == 0) >- break; >- send_pack(s, src, dst, &me, &he); >- >- gettimeofday(&tmo, 0); >- if(timeout) >- i = MS_TDIFF(timeouttv, tmo) ; >- else >- i = 1000; >- if(i < 0) >- break; >- if(i > 1000) >- i = 1000; // maximum select 1s. >- tmo.tv_sec = i/1000; >- tmo.tv_usec = (i%1000)*1000; >- >- FD_ZERO(&rset); >- FD_SET(s, &rset); >- pkttrace("select %d ; %d\n", (int)tmo.tv_sec, (int)tmo.tv_usec); >- i = select(s+1, &rset, 0, 0, &tmo); >- pkttrace("<- select\n"); >- if(i == -1){ >- perror("arping: select"); >- exit(1); >- } >- if(i == 0){ >- gettimeofday(&tmo, 0); >- i = MS_TDIFF(timeouttv, tmo); >- if(timeout && i <= 0) >- break; >- continue; >- } >- if ((cc = recvfrom(s, packet, sizeof(packet), 0, >- (struct sockaddr *)&from, &alen)) < 0) { >- perror("arping: recvfrom"); >- continue; >- } >- if(recv_pack(packet, cc, &from)) >- if(--ntorecv == 0) >- break; >- } >-} >- > int > main(int argc, char **argv) > { >- int ch, onereply; >+ int socket_errno; >+ int ch; >+ uid_t uid = getuid(); >+ >+ s = socket(PF_PACKET, SOCK_DGRAM, 0); >+ socket_errno = errno; >+ >+ setuid(uid); > > while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:V")) != EOF) { > switch(ch) { > case 'b': >- broadcast_only = 1; >+ broadcast_only=1; > break; > case 'D': > dad++; >- onereply = 1; >+ quit_on_reply=1; > break; > case 'U': > unsolicited++; >@@ -365,15 +329,13 @@ > count = atoi(optarg); > break; > case 'w': >- gettimeofday(&timeouttv, 0); >- timeouttv.tv_sec += atoi(optarg); >- timeout = 1; >+ timeout = atoi(optarg); > break; > case 'I': > device = optarg; > break; > case 'f': >- onereply = 1; >+ quit_on_reply=1; > break; > case 's': > source = optarg; >@@ -392,26 +354,19 @@ > > if (argc != 1) > usage(); >- target = *argv; > >- if(onereply) >- ntorecv = 1; >- if(timeout) // strange ping compatability. >- ntorecv = count; >- else >- ntosend = count; >+ target = *argv; > >- if (device == 0) { >+ if (device == NULL) { > fprintf(stderr, "arping: device (option -I) is required\n"); > usage(); > } > >- s = socket(PF_PACKET, SOCK_DGRAM, 0); > if (s < 0) { >+ errno = socket_errno; > perror("arping: socket"); > exit(2); > } >- setuid(getuid()); > > if (1) { > struct ifreq ifr; >@@ -424,13 +379,19 @@ > ifindex = ifr.ifr_ifindex; > > if (ioctl(s, SIOCGIFFLAGS, (char*)&ifr)) { >- perror("arping: ioctl(SIOCGIFFLAGS)"); >+ perror("ioctl(SIOCGIFFLAGS)"); > exit(2); > } >- if (!(ifr.ifr_flags&IFF_UP)) >- errexit(2, "Interface \"%s\" is down\n", device); >- if (ifr.ifr_flags&(IFF_NOARP|IFF_LOOPBACK)) >- errexit(dad ? 0 : 2, "Interface \"%s\" is not ARPable\n", device); >+ if (!(ifr.ifr_flags&IFF_UP)) { >+ if (!quiet) >+ printf("Interface \"%s\" is down\n", device); >+ exit(2); >+ } >+ if (ifr.ifr_flags&(IFF_NOARP|IFF_LOOPBACK)) { >+ if (!quiet) >+ printf("Interface \"%s\" is not ARPable\n", device); >+ exit(dad?0:2); >+ } > } > > if (inet_aton(target, &dst) != 1) { >@@ -456,7 +417,7 @@ > int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); > > if (probe_fd < 0) { >- perror("arping: socket"); >+ perror("socket"); > exit(2); > } > if (device) { >@@ -468,7 +429,7 @@ > if (src.s_addr) { > saddr.sin_addr = src; > if (bind(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { >- perror("arping: bind"); >+ perror("bind"); > exit(2); > } > } else if (!dad) { >@@ -481,11 +442,11 @@ > if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, (char*)&on, sizeof(on)) == -1) > perror("WARNING: setsockopt(SO_DONTROUTE)"); > if (connect(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { >- perror("arping: connect"); >+ perror("connect"); > exit(2); > } > if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) { >- perror("arping: getsockname"); >+ perror("getsockname"); > exit(2); > } > src = saddr.sin_addr; >@@ -497,34 +458,60 @@ > me.sll_ifindex = ifindex; > me.sll_protocol = htons(ETH_P_ARP); > if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { >- perror("arping: bind"); >+ perror("bind"); > exit(2); > } > > if (1) { > socklen_t alen = sizeof(me); > if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { >- perror("arping: getsockname"); >+ perror("getsockname"); > exit(2); > } > } >- if (me.sll_halen == 0) >- errexit(dad ? 0 : 2, "Interface \"%s\" is not ARPable (no ll address)\n", device); >+ if (me.sll_halen == 0) { >+ if (!quiet) >+ printf("Interface \"%s\" is not ARPable (no ll address)\n", device); >+ exit(dad?0:2); >+ } > > he = me; > memset(he.sll_addr, -1, he.sll_halen); > > if (!quiet) { >- fprintf(stderr, "ARPING %s ", inet_ntoa(dst)); >- fprintf(stderr, "from %s %s\n", inet_ntoa(src), device ? : ""); >+ printf("ARPING %s ", inet_ntoa(dst)); >+ printf("from %s %s\n", inet_ntoa(src), device ? : ""); > } > >- if (!src.s_addr && !dad) >- errexit(2, "arping: no source address in not-DAD mode\n"); >+ if (!src.s_addr && !dad) { >+ fprintf(stderr, "arping: no source address in not-DAD mode\n"); >+ exit(2); >+ } >+ >+ set_signal(SIGINT, finish); >+ set_signal(SIGALRM, catcher); >+ >+ catcher(); > >- pktloop(); >- finish(); >- return 1; // shut up gcc. >+ while(1) { >+ sigset_t sset, osset; >+ unsigned char packet[4096]; >+ struct sockaddr_ll from; >+ socklen_t alen = sizeof(from); >+ int cc; >+ >+ if ((cc = recvfrom(s, packet, sizeof(packet), 0, >+ (struct sockaddr *)&from, &alen)) < 0) { >+ perror("arping: recvfrom"); >+ continue; >+ } >+ sigemptyset(&sset); >+ sigaddset(&sset, SIGALRM); >+ sigaddset(&sset, SIGINT); >+ sigprocmask(SIG_BLOCK, &sset, &osset); >+ recv_pack(packet, cc, &from); >+ sigprocmask(SIG_SETMASK, &osset, NULL); >+ } > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 144526
:
94696
| 94734