diff options
Diffstat (limited to 'ping.c')
-rw-r--r-- | ping.c | 618 |
1 files changed, 324 insertions, 294 deletions
@@ -1,5 +1,6 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $ | 3 | * $Id: ping.c,v 1.11 2000/02/08 19:58:47 erik Exp $ |
3 | * Mini ping implementation for busybox | 4 | * Mini ping implementation for busybox |
4 | * | 5 | * |
5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> | 6 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> |
@@ -53,7 +54,7 @@ | |||
53 | #define MAXPACKET 65468 | 54 | #define MAXPACKET 65468 |
54 | #define MAX_DUP_CHK (8 * 128) | 55 | #define MAX_DUP_CHK (8 * 128) |
55 | #define MAXWAIT 10 | 56 | #define MAXWAIT 10 |
56 | #define PINGINTERVAL 1 /* second */ | 57 | #define PINGINTERVAL 1 /* second */ |
57 | 58 | ||
58 | #define O_QUIET (1 << 0) | 59 | #define O_QUIET (1 << 0) |
59 | 60 | ||
@@ -66,118 +67,124 @@ | |||
66 | /* common routines */ | 67 | /* common routines */ |
67 | static int in_cksum(unsigned short *buf, int sz) | 68 | static int in_cksum(unsigned short *buf, int sz) |
68 | { | 69 | { |
69 | int nleft = sz; | 70 | int nleft = sz; |
70 | int sum = 0; | 71 | int sum = 0; |
71 | unsigned short *w = buf; | 72 | unsigned short *w = buf; |
72 | unsigned short ans = 0; | 73 | unsigned short ans = 0; |
73 | 74 | ||
74 | while (nleft > 1) { | 75 | while (nleft > 1) { |
75 | sum += *w++; | 76 | sum += *w++; |
76 | nleft -= 2; | 77 | nleft -= 2; |
77 | } | 78 | } |
78 | 79 | ||
79 | if (nleft == 1) { | 80 | if (nleft == 1) { |
80 | *(unsigned char *)(&ans) = *(unsigned char *)w; | 81 | *(unsigned char *) (&ans) = *(unsigned char *) w; |
81 | sum += ans; | 82 | sum += ans; |
82 | } | 83 | } |
83 | 84 | ||
84 | sum = (sum >> 16) + (sum & 0xFFFF); | 85 | sum = (sum >> 16) + (sum & 0xFFFF); |
85 | sum += (sum >> 16); | 86 | sum += (sum >> 16); |
86 | ans = ~sum; | 87 | ans = ~sum; |
87 | return(ans); | 88 | return (ans); |
88 | } | 89 | } |
89 | 90 | ||
90 | /* simple version */ | 91 | /* simple version */ |
91 | #ifdef BB_SIMPLE_PING | 92 | #ifdef BB_SIMPLE_PING |
92 | static const char* ping_usage = "ping host\n\n"; | 93 | static const char *ping_usage = "ping host\n\n"; |
93 | 94 | ||
94 | static char* hostname = NULL; | 95 | static char *hostname = NULL; |
95 | 96 | ||
96 | static void noresp(int ign) | 97 | static void noresp(int ign) |
97 | { | 98 | { |
98 | printf("No response from %s\n", hostname); | 99 | printf("No response from %s\n", hostname); |
99 | exit(0); | 100 | exit(0); |
100 | } | 101 | } |
101 | 102 | ||
102 | static int ping(const char *host) | 103 | static int ping(const char *host) |
103 | { | 104 | { |
104 | struct hostent *h; | 105 | struct hostent *h; |
105 | struct sockaddr_in pingaddr; | 106 | struct sockaddr_in pingaddr; |
106 | struct icmp *pkt; | 107 | struct icmp *pkt; |
107 | int pingsock, c; | 108 | int pingsock, c; |
108 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; | 109 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; |
109 | 110 | ||
110 | if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ | 111 | if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ |
111 | perror("ping"); | 112 | perror("ping"); |
112 | exit(1); | 113 | exit(1); |
113 | } | 114 | } |
114 | 115 | ||
115 | /* drop root privs if running setuid */ | 116 | /* drop root privs if running setuid */ |
116 | setuid(getuid()); | 117 | setuid(getuid()); |
117 | 118 | ||
118 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); | 119 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); |
119 | pingaddr.sin_family = AF_INET; | 120 | |
120 | if (!(h = gethostbyname(host))) { | 121 | pingaddr.sin_family = AF_INET; |
121 | fprintf(stderr, "ping: unknown host %s\n", host); | 122 | if (!(h = gethostbyname(host))) { |
122 | exit(1); | 123 | fprintf(stderr, "ping: unknown host %s\n", host); |
123 | } | 124 | exit(1); |
124 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); | 125 | } |
125 | hostname = h->h_name; | 126 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); |
126 | 127 | hostname = h->h_name; | |
127 | pkt = (struct icmp *)packet; | 128 | |
128 | memset(pkt, 0, sizeof(packet)); | 129 | pkt = (struct icmp *) packet; |
129 | pkt->icmp_type = ICMP_ECHO; | 130 | memset(pkt, 0, sizeof(packet)); |
130 | pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet)); | 131 | pkt->icmp_type = ICMP_ECHO; |
131 | 132 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); | |
132 | c = sendto(pingsock, packet, sizeof(packet), 0, | 133 | |
133 | (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in)); | 134 | c = sendto(pingsock, packet, sizeof(packet), 0, |
134 | 135 | (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); | |
135 | if (c < 0 || c != sizeof(packet)) { | 136 | |
136 | if (c < 0) perror("ping"); | 137 | if (c < 0 || c != sizeof(packet)) { |
137 | fprintf(stderr, "ping: write incomplete\n"); | 138 | if (c < 0) |
138 | exit(1); | 139 | perror("ping"); |
139 | } | 140 | fprintf(stderr, "ping: write incomplete\n"); |
140 | 141 | exit(1); | |
141 | signal(SIGALRM, noresp); | 142 | } |
142 | alarm(5); /* give the host 5000ms to respond */ | 143 | |
143 | /* listen for replies */ | 144 | signal(SIGALRM, noresp); |
144 | while (1) { | 145 | alarm(5); /* give the host 5000ms to respond */ |
145 | struct sockaddr_in from; | 146 | /* listen for replies */ |
146 | size_t fromlen = sizeof(from); | 147 | while (1) { |
147 | 148 | struct sockaddr_in from; | |
148 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, | 149 | size_t fromlen = sizeof(from); |
149 | (struct sockaddr *)&from, &fromlen)) < 0) { | 150 | |
150 | if (errno == EINTR) continue; | 151 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, |
151 | perror("ping"); | 152 | (struct sockaddr *) &from, &fromlen)) < 0) { |
152 | continue; | 153 | if (errno == EINTR) |
154 | continue; | ||
155 | perror("ping"); | ||
156 | continue; | ||
157 | } | ||
158 | if (c >= 76) { /* ip + icmp */ | ||
159 | struct iphdr *iphdr = (struct iphdr *) packet; | ||
160 | |||
161 | pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */ | ||
162 | if (pkt->icmp_type == ICMP_ECHOREPLY) | ||
163 | break; | ||
164 | } | ||
153 | } | 165 | } |
154 | if (c >= 76) { /* ip + icmp */ | 166 | printf("%s is alive!\n", hostname); |
155 | struct iphdr *iphdr = (struct iphdr *)packet; | 167 | return (TRUE); |
156 | pkt = (struct icmp *)(packet + (iphdr->ihl << 2)); /* skip ip hdr */ | ||
157 | if (pkt->icmp_type == ICMP_ECHOREPLY) break; | ||
158 | } | ||
159 | } | ||
160 | printf("%s is alive!\n", hostname); | ||
161 | return(TRUE); | ||
162 | } | 168 | } |
163 | 169 | ||
164 | extern int ping_main(int argc, char **argv) | 170 | extern int ping_main(int argc, char **argv) |
165 | { | 171 | { |
166 | argc--; | 172 | argc--; |
167 | argv++; | 173 | argv++; |
168 | if (argc < 1) usage(ping_usage); | 174 | if (argc < 1) |
169 | ping(*argv); | 175 | usage(ping_usage); |
170 | exit(TRUE); | 176 | ping(*argv); |
177 | exit(TRUE); | ||
171 | } | 178 | } |
172 | 179 | ||
173 | #else | 180 | #else |
174 | /* full(er) version */ | 181 | /* full(er) version */ |
175 | static const char* ping_usage = "ping [OPTION]... host\n\n" | 182 | static const char *ping_usage = "ping [OPTION]... host\n\n" |
176 | "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" | 183 | "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" |
177 | "Options:\n" | 184 | "Options:\n" |
178 | "\t-q\t\tQuiet mode, only displays output at start" | 185 | "\t-q\t\tQuiet mode, only displays output at start" |
179 | "\t\t\tand when finished.\n" | 186 | |
180 | "\t-c COUNT\tSend only COUNT pings.\n"; | 187 | "\t\t\tand when finished.\n" "\t-c COUNT\tSend only COUNT pings.\n"; |
181 | 188 | ||
182 | static char *hostname = NULL; | 189 | static char *hostname = NULL; |
183 | static struct sockaddr_in pingaddr; | 190 | static struct sockaddr_in pingaddr; |
@@ -196,224 +203,247 @@ static void ping(char *); | |||
196 | 203 | ||
197 | /**************************************************************************/ | 204 | /**************************************************************************/ |
198 | 205 | ||
199 | static void pingstats(int ign) { | 206 | static void pingstats(int ign) |
200 | signal(SIGINT, SIG_IGN); | 207 | { |
201 | 208 | signal(SIGINT, SIG_IGN); | |
202 | printf("\n--- %s ping statistics ---\n", hostname); | 209 | |
203 | printf("%ld packets transmitted, ", ntransmitted); | 210 | printf("\n--- %s ping statistics ---\n", hostname); |
204 | printf("%ld packets received, ", nreceived); | 211 | printf("%ld packets transmitted, ", ntransmitted); |
205 | if (nrepeats) | 212 | printf("%ld packets received, ", nreceived); |
206 | printf("%ld duplicates, ", nrepeats); | 213 | if (nrepeats) |
207 | if (ntransmitted) | 214 | printf("%ld duplicates, ", nrepeats); |
208 | printf("%ld%% packet loss\n", | 215 | if (ntransmitted) |
209 | (ntransmitted - nreceived)*100/ntransmitted); | 216 | printf("%ld%% packet loss\n", |
210 | if (nreceived) | 217 | (ntransmitted - nreceived) * 100 / ntransmitted); |
211 | printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n", | 218 | if (nreceived) |
212 | tmin/10, tmin%10, | 219 | printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n", |
213 | (tsum/(nreceived+nrepeats))/10, | 220 | tmin / 10, tmin % 10, |
214 | (tsum/(nreceived+nrepeats))%10, | 221 | (tsum / (nreceived + nrepeats)) / 10, |
215 | tmax/10, tmax%10); | 222 | (tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10); |
216 | exit(0); | 223 | exit(0); |
217 | } | 224 | } |
218 | 225 | ||
219 | static void sendping(int ign) | 226 | static void sendping(int ign) |
220 | { | 227 | { |
221 | struct icmp *pkt; | 228 | struct icmp *pkt; |
222 | int i; | 229 | int i; |
223 | char packet[DEFDATALEN + 8]; | 230 | char packet[DEFDATALEN + 8]; |
224 | 231 | ||
225 | pkt = (struct icmp *)packet; | 232 | pkt = (struct icmp *) packet; |
226 | 233 | ||
227 | pkt->icmp_type = ICMP_ECHO; | 234 | pkt->icmp_type = ICMP_ECHO; |
228 | pkt->icmp_code = 0; | 235 | pkt->icmp_code = 0; |
229 | pkt->icmp_cksum = 0; | 236 | pkt->icmp_cksum = 0; |
230 | pkt->icmp_seq = ntransmitted++; | 237 | pkt->icmp_seq = ntransmitted++; |
231 | pkt->icmp_id = myid; | 238 | pkt->icmp_id = myid; |
232 | CLR(pkt->icmp_seq % MAX_DUP_CHK); | 239 | CLR(pkt->icmp_seq % MAX_DUP_CHK); |
233 | 240 | ||
234 | gettimeofday((struct timeval *)&packet[8], NULL); | 241 | gettimeofday((struct timeval *) &packet[8], NULL); |
235 | pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet)); | 242 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); |
236 | 243 | ||
237 | i = sendto(pingsock, packet, sizeof(packet), 0, | 244 | i = sendto(pingsock, packet, sizeof(packet), 0, |
238 | (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in)); | 245 | (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); |
239 | 246 | ||
240 | if (i < 0 || i != sizeof(packet)) { | 247 | if (i < 0 || i != sizeof(packet)) { |
241 | if (i < 0) perror("ping"); | 248 | if (i < 0) |
242 | fprintf(stderr, "ping wrote %d chars; %d expected\n", i, sizeof(packet)); | 249 | perror("ping"); |
243 | exit(1); | 250 | fprintf(stderr, "ping wrote %d chars; %d expected\n", i, |
244 | } | 251 | sizeof(packet)); |
245 | 252 | exit(1); | |
246 | signal(SIGALRM, sendping); | 253 | } |
247 | if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ | 254 | |
248 | alarm(PINGINTERVAL); | 255 | signal(SIGALRM, sendping); |
249 | } else { /* done, wait for the last ping to come back */ | 256 | if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ |
250 | /* todo, don't necessarily need to wait so long... */ | 257 | alarm(PINGINTERVAL); |
251 | signal(SIGALRM, pingstats); | 258 | } else { /* done, wait for the last ping to come back */ |
252 | alarm(MAXWAIT); | 259 | /* todo, don't necessarily need to wait so long... */ |
253 | } | 260 | signal(SIGALRM, pingstats); |
261 | alarm(MAXWAIT); | ||
262 | } | ||
254 | } | 263 | } |
255 | 264 | ||
256 | static void unpack(char *buf, int sz, struct sockaddr_in *from) | 265 | static void unpack(char *buf, int sz, struct sockaddr_in *from) |
257 | { | 266 | { |
258 | struct icmp *icmppkt; | 267 | struct icmp *icmppkt; |
259 | struct iphdr *iphdr; | 268 | struct iphdr *iphdr; |
260 | struct timeval tv, *tp; | 269 | struct timeval tv, *tp; |
261 | int hlen, dupflag; | 270 | int hlen, dupflag; |
262 | unsigned long triptime; | 271 | unsigned long triptime; |
263 | 272 | ||
264 | gettimeofday(&tv, NULL); | 273 | gettimeofday(&tv, NULL); |
265 | 274 | ||
266 | /* check IP header */ | 275 | /* check IP header */ |
267 | iphdr = (struct iphdr *)buf; | 276 | iphdr = (struct iphdr *) buf; |
268 | hlen = iphdr->ihl << 2; | 277 | hlen = iphdr->ihl << 2; |
269 | /* discard if too short */ | 278 | /* discard if too short */ |
270 | if (sz < (DEFDATALEN + ICMP_MINLEN)) return; | 279 | if (sz < (DEFDATALEN + ICMP_MINLEN)) |
271 | 280 | return; | |
272 | sz -= hlen; | 281 | |
273 | icmppkt = (struct icmp *)(buf + hlen); | 282 | sz -= hlen; |
274 | 283 | icmppkt = (struct icmp *) (buf + hlen); | |
275 | if (icmppkt->icmp_type == ICMP_ECHOREPLY) { | 284 | |
276 | if (icmppkt->icmp_id != myid) return; /* not our ping */ | 285 | if (icmppkt->icmp_type == ICMP_ECHOREPLY) { |
277 | ++nreceived; | 286 | if (icmppkt->icmp_id != myid) |
278 | tp = (struct timeval *)icmppkt->icmp_data; | 287 | return; /* not our ping */ |
279 | 288 | ++nreceived; | |
280 | if ((tv.tv_usec -= tp->tv_usec) < 0) { | 289 | tp = (struct timeval *) icmppkt->icmp_data; |
281 | --tv.tv_sec; | 290 | |
282 | tv.tv_usec += 1000000; | 291 | if ((tv.tv_usec -= tp->tv_usec) < 0) { |
283 | } | 292 | --tv.tv_sec; |
284 | tv.tv_sec -= tp->tv_sec; | 293 | tv.tv_usec += 1000000; |
285 | 294 | } | |
286 | triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); | 295 | tv.tv_sec -= tp->tv_sec; |
287 | tsum += triptime; | 296 | |
288 | if (triptime < tmin) tmin = triptime; | 297 | triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); |
289 | if (triptime > tmax) tmax = triptime; | 298 | tsum += triptime; |
290 | 299 | if (triptime < tmin) | |
291 | if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) { | 300 | tmin = triptime; |
292 | ++nrepeats; | 301 | if (triptime > tmax) |
293 | --nreceived; | 302 | tmax = triptime; |
294 | dupflag = 1; | 303 | |
304 | if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) { | ||
305 | ++nrepeats; | ||
306 | --nreceived; | ||
307 | dupflag = 1; | ||
308 | } else { | ||
309 | SET(icmppkt->icmp_seq % MAX_DUP_CHK); | ||
310 | dupflag = 0; | ||
311 | } | ||
312 | |||
313 | if (options & O_QUIET) | ||
314 | return; | ||
315 | |||
316 | printf("%d bytes from %s: icmp_seq=%u", sz, | ||
317 | inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr), | ||
318 | icmppkt->icmp_seq); | ||
319 | printf(" ttl=%d", iphdr->ttl); | ||
320 | printf(" time=%lu.%lu ms", triptime / 10, triptime % 10); | ||
321 | if (dupflag) | ||
322 | printf(" (DUP!)"); | ||
323 | printf("\n"); | ||
295 | } else { | 324 | } else { |
296 | SET(icmppkt->icmp_seq % MAX_DUP_CHK); | 325 | fprintf(stderr, |
297 | dupflag = 0; | 326 | "Warning: unknown ICMP packet received (not echo-reply)\n"); |
298 | } | 327 | } |
299 | |||
300 | if (options & O_QUIET) return; | ||
301 | |||
302 | printf("%d bytes from %s: icmp_seq=%u", sz, | ||
303 | inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr), | ||
304 | icmppkt->icmp_seq); | ||
305 | printf(" ttl=%d", iphdr->ttl); | ||
306 | printf(" time=%lu.%lu ms", triptime/10, triptime%10); | ||
307 | if (dupflag) printf(" (DUP!)"); | ||
308 | printf("\n"); | ||
309 | } else { | ||
310 | fprintf(stderr, "Warning: unknown ICMP packet received (not echo-reply)\n"); | ||
311 | } | ||
312 | } | 328 | } |
313 | 329 | ||
314 | static void ping(char *host) | 330 | static void ping(char *host) |
315 | { | 331 | { |
316 | struct protoent *proto; | 332 | struct protoent *proto; |
317 | struct hostent *h; | 333 | struct hostent *h; |
318 | char buf[MAXHOSTNAMELEN]; | 334 | char buf[MAXHOSTNAMELEN]; |
319 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; | 335 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; |
320 | int sockopt; | 336 | int sockopt; |
321 | 337 | ||
322 | proto = getprotobyname("icmp"); | 338 | proto = getprotobyname("icmp"); |
323 | /* if getprotobyname failed, just silently force | 339 | /* if getprotobyname failed, just silently force |
324 | * proto->p_proto to have the correct value for "icmp" */ | 340 | * proto->p_proto to have the correct value for "icmp" */ |
325 | if ((pingsock = socket(AF_INET, SOCK_RAW, | 341 | if ((pingsock = socket(AF_INET, SOCK_RAW, |
326 | (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ | 342 | (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ |
327 | if (errno == EPERM) { | 343 | if (errno == EPERM) { |
328 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); | 344 | fprintf(stderr, "ping: permission denied. (are you root?)\n"); |
329 | } else { | 345 | } else { |
330 | perror("ping"); | 346 | perror("ping"); |
347 | } | ||
348 | exit(1); | ||
331 | } | 349 | } |
332 | exit(1); | 350 | |
333 | } | 351 | /* drop root privs if running setuid */ |
334 | 352 | setuid(getuid()); | |
335 | /* drop root privs if running setuid */ | 353 | |
336 | setuid(getuid()); | 354 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); |
337 | 355 | ||
338 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); | 356 | pingaddr.sin_family = AF_INET; |
339 | pingaddr.sin_family = AF_INET; | 357 | if (!(h = gethostbyname(host))) { |
340 | if (!(h = gethostbyname(host))) { | 358 | fprintf(stderr, "ping: unknown host %s\n", host); |
341 | fprintf(stderr, "ping: unknown host %s\n", host); | 359 | exit(1); |
342 | exit(1); | 360 | } |
343 | } | 361 | |
344 | 362 | if (h->h_addrtype != AF_INET) { | |
345 | if (h->h_addrtype != AF_INET) { | 363 | fprintf(stderr, |
346 | fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n"); | 364 | "ping: unknown address type; only AF_INET is currently supported.\n"); |
347 | exit(1); | 365 | exit(1); |
348 | } | ||
349 | |||
350 | pingaddr.sin_family = AF_INET; /* h->h_addrtype */ | ||
351 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); | ||
352 | strncpy(buf, h->h_name, sizeof(buf)-1); | ||
353 | hostname = buf; | ||
354 | |||
355 | /* enable broadcast pings */ | ||
356 | sockopt = 1; | ||
357 | setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt, sizeof(sockopt)); | ||
358 | |||
359 | /* set recv buf for broadcast pings */ | ||
360 | sockopt = 48 * 1024; | ||
361 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt)); | ||
362 | |||
363 | printf("PING %s (%s): %d data bytes\n", | ||
364 | hostname, inet_ntoa(*(struct in_addr *)&pingaddr.sin_addr.s_addr), | ||
365 | DEFDATALEN); | ||
366 | |||
367 | signal(SIGINT, pingstats); | ||
368 | |||
369 | /* start the ping's going ... */ | ||
370 | sendping(0); | ||
371 | |||
372 | /* listen for replies */ | ||
373 | while (1) { | ||
374 | struct sockaddr_in from; | ||
375 | size_t fromlen = sizeof(from); | ||
376 | int c; | ||
377 | |||
378 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, | ||
379 | (struct sockaddr *)&from, &fromlen)) < 0) { | ||
380 | if (errno == EINTR) continue; | ||
381 | perror("ping"); | ||
382 | continue; | ||
383 | } | 366 | } |
384 | unpack(packet, c, &from); | 367 | |
385 | if (pingcount > 0 && nreceived >= pingcount) break; | 368 | pingaddr.sin_family = AF_INET; /* h->h_addrtype */ |
386 | } | 369 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); |
387 | pingstats(0); | 370 | strncpy(buf, h->h_name, sizeof(buf) - 1); |
371 | hostname = buf; | ||
372 | |||
373 | /* enable broadcast pings */ | ||
374 | sockopt = 1; | ||
375 | setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *) &sockopt, | ||
376 | sizeof(sockopt)); | ||
377 | |||
378 | /* set recv buf for broadcast pings */ | ||
379 | sockopt = 48 * 1024; | ||
380 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt, | ||
381 | sizeof(sockopt)); | ||
382 | |||
383 | printf("PING %s (%s): %d data bytes\n", | ||
384 | hostname, | ||
385 | inet_ntoa(*(struct in_addr *) &pingaddr.sin_addr.s_addr), | ||
386 | DEFDATALEN); | ||
387 | |||
388 | signal(SIGINT, pingstats); | ||
389 | |||
390 | /* start the ping's going ... */ | ||
391 | sendping(0); | ||
392 | |||
393 | /* listen for replies */ | ||
394 | while (1) { | ||
395 | struct sockaddr_in from; | ||
396 | size_t fromlen = sizeof(from); | ||
397 | int c; | ||
398 | |||
399 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, | ||
400 | (struct sockaddr *) &from, &fromlen)) < 0) { | ||
401 | if (errno == EINTR) | ||
402 | continue; | ||
403 | perror("ping"); | ||
404 | continue; | ||
405 | } | ||
406 | unpack(packet, c, &from); | ||
407 | if (pingcount > 0 && nreceived >= pingcount) | ||
408 | break; | ||
409 | } | ||
410 | pingstats(0); | ||
388 | } | 411 | } |
389 | 412 | ||
390 | extern int ping_main(int argc, char **argv) | 413 | extern int ping_main(int argc, char **argv) |
391 | { | 414 | { |
392 | char *thisarg; | 415 | char *thisarg; |
393 | 416 | ||
394 | argc--; | 417 | argc--; |
395 | argv++; | 418 | argv++; |
396 | options = 0; | 419 | options = 0; |
397 | /* Parse any options */ | 420 | /* Parse any options */ |
398 | while (argc > 1) { | 421 | while (argc > 1) { |
399 | if (**argv != '-') usage(ping_usage); | 422 | if (**argv != '-') |
400 | thisarg = *argv; thisarg++; | 423 | usage(ping_usage); |
401 | switch (*thisarg) { | 424 | thisarg = *argv; |
402 | case 'q': options |= O_QUIET; break; | 425 | thisarg++; |
403 | case 'c': | 426 | switch (*thisarg) { |
404 | argc--; argv++; | 427 | case 'q': |
405 | pingcount = atoi(*argv); | 428 | options |= O_QUIET; |
406 | break; | 429 | break; |
407 | default: | 430 | case 'c': |
408 | usage(ping_usage); | 431 | argc--; |
409 | } | 432 | argv++; |
410 | argc--; argv++; | 433 | pingcount = atoi(*argv); |
411 | } | 434 | break; |
412 | if (argc < 1) usage(ping_usage); | 435 | default: |
413 | 436 | usage(ping_usage); | |
414 | myid = getpid() & 0xFFFF; | 437 | } |
415 | ping(*argv); | 438 | argc--; |
416 | exit(TRUE); | 439 | argv++; |
440 | } | ||
441 | if (argc < 1) | ||
442 | usage(ping_usage); | ||
443 | |||
444 | myid = getpid() & 0xFFFF; | ||
445 | ping(*argv); | ||
446 | exit(TRUE); | ||
417 | } | 447 | } |
418 | #endif | 448 | #endif |
419 | 449 | ||