diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-08 23:55:33 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-08 23:55:33 +0000 |
commit | 44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3 (patch) | |
tree | 4fd57ec4aec7587b1187138f724f2c64e6a1d471 /networking | |
parent | d6c23aeefba32ae1d7290f849cf2290749876462 (diff) | |
download | busybox-w32-44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3.tar.gz busybox-w32-44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3.tar.bz2 busybox-w32-44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3.zip |
ping6: fix sequence numbers (missed ntoh) and ttl display.
(apparently some, eh, clever libc guy decided that
*CHANGING* IPV6_HOPLIMIT value in libc header is a nifty idea...)
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ping.c | 41 | ||||
-rw-r--r-- | networking/ping6.c | 92 |
2 files changed, 58 insertions, 75 deletions
diff --git a/networking/ping.c b/networking/ping.c index 8b49df1bd..de97d7e7f 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -12,23 +12,11 @@ | |||
12 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 12 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <sys/param.h> | 15 | //#include <netinet/in.h> |
16 | #include <sys/socket.h> | 16 | //#include <netinet/ip.h> |
17 | #include <sys/file.h> | ||
18 | #include <sys/times.h> | ||
19 | #include <signal.h> | ||
20 | |||
21 | #include <netinet/in.h> | ||
22 | #include <netinet/ip.h> | ||
23 | #include <netinet/ip_icmp.h> | 17 | #include <netinet/ip_icmp.h> |
24 | #include <arpa/inet.h> | 18 | //#include <arpa/inet.h> |
25 | #include <netdb.h> | 19 | //#include <netdb.h> |
26 | #include <stdio.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <errno.h> | ||
29 | #include <unistd.h> | ||
30 | #include <string.h> | ||
31 | #include <stdlib.h> | ||
32 | #include "busybox.h" | 20 | #include "busybox.h" |
33 | 21 | ||
34 | enum { | 22 | enum { |
@@ -120,9 +108,8 @@ static void ping(const char *host) | |||
120 | c = recvfrom(pingsock, packet, sizeof(packet), 0, | 108 | c = recvfrom(pingsock, packet, sizeof(packet), 0, |
121 | (struct sockaddr *) &from, &fromlen); | 109 | (struct sockaddr *) &from, &fromlen); |
122 | if (c < 0) { | 110 | if (c < 0) { |
123 | if (errno == EINTR) | 111 | if (errno != EINTR) |
124 | continue; | 112 | bb_perror_msg("recvfrom"); |
125 | bb_perror_msg("recvfrom"); | ||
126 | continue; | 113 | continue; |
127 | } | 114 | } |
128 | if (c >= 76) { /* ip + icmp */ | 115 | if (c >= 76) { /* ip + icmp */ |
@@ -135,7 +122,6 @@ static void ping(const char *host) | |||
135 | } | 122 | } |
136 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); | 123 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); |
137 | printf("%s is alive!\n", hostname); | 124 | printf("%s is alive!\n", hostname); |
138 | return; | ||
139 | } | 125 | } |
140 | 126 | ||
141 | int ping_main(int argc, char **argv) | 127 | int ping_main(int argc, char **argv) |
@@ -231,7 +217,7 @@ static void sendping(int junk) | |||
231 | 217 | ||
232 | if (i < 0) | 218 | if (i < 0) |
233 | bb_perror_msg_and_die("sendto"); | 219 | bb_perror_msg_and_die("sendto"); |
234 | else if ((size_t)i != sizeof(packet)) | 220 | if ((size_t)i != sizeof(packet)) |
235 | bb_error_msg_and_die("ping wrote %d chars; %d expected", i, | 221 | bb_error_msg_and_die("ping wrote %d chars; %d expected", i, |
236 | (int)sizeof(packet)); | 222 | (int)sizeof(packet)); |
237 | 223 | ||
@@ -328,7 +314,8 @@ static void unpack(char *buf, int sz, struct sockaddr_in *from) | |||
328 | } else | 314 | } else |
329 | if (icmppkt->icmp_type != ICMP_ECHO) | 315 | if (icmppkt->icmp_type != ICMP_ECHO) |
330 | bb_error_msg("warning: got ICMP %d (%s)", | 316 | bb_error_msg("warning: got ICMP %d (%s)", |
331 | icmppkt->icmp_type, icmp_type_name(icmppkt->icmp_type)); | 317 | icmppkt->icmp_type, |
318 | icmp_type_name(icmppkt->icmp_type)); | ||
332 | fflush(stdout); | 319 | fflush(stdout); |
333 | } | 320 | } |
334 | 321 | ||
@@ -380,11 +367,11 @@ static void ping(const char *host) | |||
380 | socklen_t fromlen = (socklen_t) sizeof(from); | 367 | socklen_t fromlen = (socklen_t) sizeof(from); |
381 | int c; | 368 | int c; |
382 | 369 | ||
383 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, | 370 | c = recvfrom(pingsock, packet, sizeof(packet), 0, |
384 | (struct sockaddr *) &from, &fromlen)) < 0) { | 371 | (struct sockaddr *) &from, &fromlen); |
385 | if (errno == EINTR) | 372 | if (c < 0) { |
386 | continue; | 373 | if (errno != EINTR) |
387 | bb_perror_msg("recvfrom"); | 374 | bb_perror_msg("recvfrom"); |
388 | continue; | 375 | continue; |
389 | } | 376 | } |
390 | unpack(packet, c, &from); | 377 | unpack(packet, c, &from); |
diff --git a/networking/ping6.c b/networking/ping6.c index c0b31c752..81e16e2f0 100644 --- a/networking/ping6.c +++ b/networking/ping6.c | |||
@@ -22,27 +22,21 @@ | |||
22 | * The code was modified by Bart Visscher <magick@linux-fan.com> | 22 | * The code was modified by Bart Visscher <magick@linux-fan.com> |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <sys/param.h> | 25 | //#include <netinet/in.h> |
26 | #include <sys/socket.h> | 26 | //#include <netinet/ip6.h> |
27 | #include <sys/file.h> | ||
28 | #include <sys/times.h> | ||
29 | #include <signal.h> | ||
30 | |||
31 | #include <netinet/in.h> | ||
32 | #include <netinet/ip6.h> | ||
33 | #include <netinet/icmp6.h> | 27 | #include <netinet/icmp6.h> |
34 | #include <arpa/inet.h> | 28 | //#include <arpa/inet.h> |
35 | #include <net/if.h> | 29 | #include <net/if.h> |
36 | #include <netdb.h> | 30 | //#include <netdb.h> |
37 | #include <stdio.h> | ||
38 | #include <stdlib.h> | ||
39 | #include <errno.h> | ||
40 | #include <unistd.h> | ||
41 | #include <string.h> | ||
42 | #include <stdlib.h> | ||
43 | #include <stddef.h> /* offsetof */ | ||
44 | #include "busybox.h" | 31 | #include "busybox.h" |
45 | 32 | ||
33 | /* I see RENUMBERED constants in bits/in.h - !!? | ||
34 | * What a fuck is going on with libc? Is it a glibc joke? */ | ||
35 | #ifdef IPV6_2292HOPLIMIT | ||
36 | #undef IPV6_HOPLIMIT | ||
37 | #define IPV6_HOPLIMIT IPV6_2292HOPLIMIT | ||
38 | #endif | ||
39 | |||
46 | enum { | 40 | enum { |
47 | DEFDATALEN = 56, | 41 | DEFDATALEN = 56, |
48 | MAXIPLEN = 60, | 42 | MAXIPLEN = 60, |
@@ -94,7 +88,7 @@ static void ping(const char *host) | |||
94 | c = sendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), 0, | 88 | c = sendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), 0, |
95 | (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6)); | 89 | (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6)); |
96 | 90 | ||
97 | if (c < 0 || c != sizeof(packet)) { | 91 | if (c < 0) { |
98 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); | 92 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); |
99 | bb_perror_msg_and_die("sendto"); | 93 | bb_perror_msg_and_die("sendto"); |
100 | } | 94 | } |
@@ -109,9 +103,8 @@ static void ping(const char *host) | |||
109 | c = recvfrom(pingsock, packet, sizeof(packet), 0, | 103 | c = recvfrom(pingsock, packet, sizeof(packet), 0, |
110 | (struct sockaddr *) &from, &fromlen); | 104 | (struct sockaddr *) &from, &fromlen); |
111 | if (c < 0) { | 105 | if (c < 0) { |
112 | if (errno == EINTR) | 106 | if (errno != EINTR) |
113 | continue; | 107 | bb_perror_msg("recvfrom"); |
114 | bb_perror_msg("recvfrom"); | ||
115 | continue; | 108 | continue; |
116 | } | 109 | } |
117 | if (c >= 8) { /* icmp6_hdr */ | 110 | if (c >= 8) { /* icmp6_hdr */ |
@@ -122,7 +115,6 @@ static void ping(const char *host) | |||
122 | } | 115 | } |
123 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); | 116 | if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); |
124 | printf("%s is alive!\n", h->h_name); | 117 | printf("%s is alive!\n", h->h_name); |
125 | return; | ||
126 | } | 118 | } |
127 | 119 | ||
128 | int ping6_main(int argc, char **argv) | 120 | int ping6_main(int argc, char **argv) |
@@ -218,7 +210,7 @@ static void sendping(int junk) | |||
218 | 210 | ||
219 | if (i < 0) | 211 | if (i < 0) |
220 | bb_perror_msg_and_die("sendto"); | 212 | bb_perror_msg_and_die("sendto"); |
221 | else if ((size_t)i != sizeof(packet)) | 213 | if ((size_t)i != sizeof(packet)) |
222 | bb_error_msg_and_die("ping wrote %d chars; %d expected", i, | 214 | bb_error_msg_and_die("ping wrote %d chars; %d expected", i, |
223 | (int)sizeof(packet)); | 215 | (int)sizeof(packet)); |
224 | 216 | ||
@@ -246,16 +238,16 @@ static void sendping(int junk) | |||
246 | static char *icmp6_type_name(int id) | 238 | static char *icmp6_type_name(int id) |
247 | { | 239 | { |
248 | switch (id) { | 240 | switch (id) { |
249 | case ICMP6_DST_UNREACH: return "Destination Unreachable"; | 241 | case ICMP6_DST_UNREACH: return "Destination Unreachable"; |
250 | case ICMP6_PACKET_TOO_BIG: return "Packet too big"; | 242 | case ICMP6_PACKET_TOO_BIG: return "Packet too big"; |
251 | case ICMP6_TIME_EXCEEDED: return "Time Exceeded"; | 243 | case ICMP6_TIME_EXCEEDED: return "Time Exceeded"; |
252 | case ICMP6_PARAM_PROB: return "Parameter Problem"; | 244 | case ICMP6_PARAM_PROB: return "Parameter Problem"; |
253 | case ICMP6_ECHO_REPLY: return "Echo Reply"; | 245 | case ICMP6_ECHO_REPLY: return "Echo Reply"; |
254 | case ICMP6_ECHO_REQUEST: return "Echo Request"; | 246 | case ICMP6_ECHO_REQUEST: return "Echo Request"; |
255 | case MLD_LISTENER_QUERY: return "Listener Query"; | 247 | case MLD_LISTENER_QUERY: return "Listener Query"; |
256 | case MLD_LISTENER_REPORT: return "Listener Report"; | 248 | case MLD_LISTENER_REPORT: return "Listener Report"; |
257 | case MLD_LISTENER_REDUCTION: return "Listener Reduction"; | 249 | case MLD_LISTENER_REDUCTION: return "Listener Reduction"; |
258 | default: return "unknown ICMP type"; | 250 | default: return "unknown ICMP type"; |
259 | } | 251 | } |
260 | } | 252 | } |
261 | 253 | ||
@@ -309,7 +301,7 @@ static void unpack(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit | |||
309 | printf("%d bytes from %s: icmp6_seq=%u", sz, | 301 | printf("%d bytes from %s: icmp6_seq=%u", sz, |
310 | inet_ntop(AF_INET6, &pingaddr.sin6_addr, | 302 | inet_ntop(AF_INET6, &pingaddr.sin6_addr, |
311 | buf, sizeof(buf)), | 303 | buf, sizeof(buf)), |
312 | icmppkt->icmp6_seq); | 304 | ntohs(icmppkt->icmp6_seq)); |
313 | printf(" ttl=%d time=%lu.%lu ms", hoplimit, | 305 | printf(" ttl=%d time=%lu.%lu ms", hoplimit, |
314 | triptime / 10, triptime % 10); | 306 | triptime / 10, triptime % 10); |
315 | if (dupflag) | 307 | if (dupflag) |
@@ -361,14 +353,16 @@ static void ping(const char *host) | |||
361 | setsockopt_broadcast(pingsock); | 353 | setsockopt_broadcast(pingsock); |
362 | 354 | ||
363 | /* set recv buf for broadcast pings */ | 355 | /* set recv buf for broadcast pings */ |
364 | sockopt = 48 * 1024; | 356 | sockopt = 48 * 1024; /* explain why 48k? */ |
365 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt, | 357 | setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt, |
366 | sizeof(sockopt)); | 358 | sizeof(sockopt)); |
367 | 359 | ||
360 | sockopt = 2; /* iputils-ss020927 does this */ | ||
368 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); | 361 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); |
369 | setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, (char *) &sockopt, | 362 | setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, (char *) &sockopt, |
370 | sizeof(sockopt)); | 363 | sizeof(sockopt)); |
371 | 364 | ||
365 | /* request ttl info to be returned in ancillary data */ | ||
372 | sockopt = 1; | 366 | sockopt = 1; |
373 | setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, (char *) &sockopt, | 367 | setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, (char *) &sockopt, |
374 | sizeof(sockopt)); | 368 | sizeof(sockopt)); |
@@ -377,10 +371,10 @@ static void ping(const char *host) | |||
377 | pingaddr.sin6_scope_id = if_index; | 371 | pingaddr.sin6_scope_id = if_index; |
378 | 372 | ||
379 | printf("PING %s (%s): %d data bytes\n", | 373 | printf("PING %s (%s): %d data bytes\n", |
380 | hostent->h_name, | 374 | hostent->h_name, |
381 | inet_ntop(AF_INET6, &pingaddr.sin6_addr, | 375 | inet_ntop(AF_INET6, &pingaddr.sin6_addr, |
382 | buf, sizeof(buf)), | 376 | buf, sizeof(buf)), |
383 | datalen); | 377 | datalen); |
384 | 378 | ||
385 | signal(SIGINT, pingstats); | 379 | signal(SIGINT, pingstats); |
386 | 380 | ||
@@ -397,21 +391,23 @@ static void ping(const char *host) | |||
397 | iov.iov_len = sizeof(packet); | 391 | iov.iov_len = sizeof(packet); |
398 | while (1) { | 392 | while (1) { |
399 | int c; | 393 | int c; |
400 | struct cmsghdr *cmsgptr = NULL; | 394 | struct cmsghdr *mp; |
401 | int hoplimit = -1; | 395 | int hoplimit = -1; |
402 | msg.msg_controllen = sizeof(control_buf); | 396 | msg.msg_controllen = sizeof(control_buf); |
403 | 397 | ||
404 | if ((c = recvmsg(pingsock, &msg, 0)) < 0) { | 398 | c = recvmsg(pingsock, &msg, 0); |
405 | if (errno == EINTR) | 399 | if (c < 0) { |
406 | continue; | 400 | if (errno != EINTR) |
407 | bb_perror_msg("recvfrom"); | 401 | bb_perror_msg("recvfrom"); |
408 | continue; | 402 | continue; |
409 | } | 403 | } |
410 | for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; | 404 | for (mp = CMSG_FIRSTHDR(&msg); mp; mp = CMSG_NXTHDR(&msg, mp)) { |
411 | cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { | 405 | if (mp->cmsg_level == SOL_IPV6 |
412 | if (cmsgptr->cmsg_level == SOL_IPV6 && | 406 | && mp->cmsg_type == IPV6_HOPLIMIT |
413 | cmsgptr->cmsg_type == IPV6_HOPLIMIT ) { | 407 | /* don't check len - we trust the kernel: */ |
414 | hoplimit = *(int*)CMSG_DATA(cmsgptr); | 408 | /* && mp->cmsg_len >= CMSG_LEN(sizeof(int)) */ |
409 | ) { | ||
410 | hoplimit = *(int*)CMSG_DATA(mp); | ||
415 | } | 411 | } |
416 | } | 412 | } |
417 | unpack(packet, c, &from, hoplimit); | 413 | unpack(packet, c, &from, hoplimit); |