summaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-08 23:55:33 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-08 23:55:33 +0000
commit44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3 (patch)
tree4fd57ec4aec7587b1187138f724f2c64e6a1d471 /networking
parentd6c23aeefba32ae1d7290f849cf2290749876462 (diff)
downloadbusybox-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.c41
-rw-r--r--networking/ping6.c92
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
34enum { 22enum {
@@ -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
141int ping_main(int argc, char **argv) 127int 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
46enum { 40enum {
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
128int ping6_main(int argc, char **argv) 120int 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)
246static char *icmp6_type_name(int id) 238static 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);