From 44c2eb23ddddb7d0703f24d1dac99f4501f1b9f3 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 8 Jan 2007 23:55:33 +0000 Subject: [PATCH] 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...) --- networking/ping.c | 41 +++++++-------------- 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 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include -#include -#include -#include -#include - -#include -#include +//#include +//#include #include -#include -#include -#include -#include -#include -#include -#include -#include +//#include +//#include #include "busybox.h" enum { @@ -120,9 +108,8 @@ static void ping(const char *host) c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen); if (c < 0) { - if (errno == EINTR) - continue; - bb_perror_msg("recvfrom"); + if (errno != EINTR) + bb_perror_msg("recvfrom"); continue; } if (c >= 76) { /* ip + icmp */ @@ -135,7 +122,6 @@ static void ping(const char *host) } if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); printf("%s is alive!\n", hostname); - return; } int ping_main(int argc, char **argv) @@ -231,7 +217,7 @@ static void sendping(int junk) if (i < 0) bb_perror_msg_and_die("sendto"); - else if ((size_t)i != sizeof(packet)) + if ((size_t)i != sizeof(packet)) bb_error_msg_and_die("ping wrote %d chars; %d expected", i, (int)sizeof(packet)); @@ -328,7 +314,8 @@ static void unpack(char *buf, int sz, struct sockaddr_in *from) } else if (icmppkt->icmp_type != ICMP_ECHO) bb_error_msg("warning: got ICMP %d (%s)", - icmppkt->icmp_type, icmp_type_name(icmppkt->icmp_type)); + icmppkt->icmp_type, + icmp_type_name(icmppkt->icmp_type)); fflush(stdout); } @@ -380,11 +367,11 @@ static void ping(const char *host) socklen_t fromlen = (socklen_t) sizeof(from); int c; - if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, - (struct sockaddr *) &from, &fromlen)) < 0) { - if (errno == EINTR) - continue; - bb_perror_msg("recvfrom"); + c = recvfrom(pingsock, packet, sizeof(packet), 0, + (struct sockaddr *) &from, &fromlen); + if (c < 0) { + if (errno != EINTR) + bb_perror_msg("recvfrom"); continue; } 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 @@ * The code was modified by Bart Visscher */ -#include -#include -#include -#include -#include - -#include -#include +//#include +//#include #include -#include +//#include #include -#include -#include -#include -#include -#include -#include -#include -#include /* offsetof */ +//#include #include "busybox.h" +/* I see RENUMBERED constants in bits/in.h - !!? + * What a fuck is going on with libc? Is it a glibc joke? */ +#ifdef IPV6_2292HOPLIMIT +#undef IPV6_HOPLIMIT +#define IPV6_HOPLIMIT IPV6_2292HOPLIMIT +#endif + enum { DEFDATALEN = 56, MAXIPLEN = 60, @@ -94,7 +88,7 @@ static void ping(const char *host) c = sendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6)); - if (c < 0 || c != sizeof(packet)) { + if (c < 0) { if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); bb_perror_msg_and_die("sendto"); } @@ -109,9 +103,8 @@ static void ping(const char *host) c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen); if (c < 0) { - if (errno == EINTR) - continue; - bb_perror_msg("recvfrom"); + if (errno != EINTR) + bb_perror_msg("recvfrom"); continue; } if (c >= 8) { /* icmp6_hdr */ @@ -122,7 +115,6 @@ static void ping(const char *host) } if (ENABLE_FEATURE_CLEAN_UP) close(pingsock); printf("%s is alive!\n", h->h_name); - return; } int ping6_main(int argc, char **argv) @@ -218,7 +210,7 @@ static void sendping(int junk) if (i < 0) bb_perror_msg_and_die("sendto"); - else if ((size_t)i != sizeof(packet)) + if ((size_t)i != sizeof(packet)) bb_error_msg_and_die("ping wrote %d chars; %d expected", i, (int)sizeof(packet)); @@ -246,16 +238,16 @@ static void sendping(int junk) static char *icmp6_type_name(int id) { switch (id) { - case ICMP6_DST_UNREACH: return "Destination Unreachable"; - case ICMP6_PACKET_TOO_BIG: return "Packet too big"; - case ICMP6_TIME_EXCEEDED: return "Time Exceeded"; - case ICMP6_PARAM_PROB: return "Parameter Problem"; - case ICMP6_ECHO_REPLY: return "Echo Reply"; - case ICMP6_ECHO_REQUEST: return "Echo Request"; - case MLD_LISTENER_QUERY: return "Listener Query"; - case MLD_LISTENER_REPORT: return "Listener Report"; - case MLD_LISTENER_REDUCTION: return "Listener Reduction"; - default: return "unknown ICMP type"; + case ICMP6_DST_UNREACH: return "Destination Unreachable"; + case ICMP6_PACKET_TOO_BIG: return "Packet too big"; + case ICMP6_TIME_EXCEEDED: return "Time Exceeded"; + case ICMP6_PARAM_PROB: return "Parameter Problem"; + case ICMP6_ECHO_REPLY: return "Echo Reply"; + case ICMP6_ECHO_REQUEST: return "Echo Request"; + case MLD_LISTENER_QUERY: return "Listener Query"; + case MLD_LISTENER_REPORT: return "Listener Report"; + case MLD_LISTENER_REDUCTION: return "Listener Reduction"; + default: return "unknown ICMP type"; } } @@ -309,7 +301,7 @@ static void unpack(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit printf("%d bytes from %s: icmp6_seq=%u", sz, inet_ntop(AF_INET6, &pingaddr.sin6_addr, buf, sizeof(buf)), - icmppkt->icmp6_seq); + ntohs(icmppkt->icmp6_seq)); printf(" ttl=%d time=%lu.%lu ms", hoplimit, triptime / 10, triptime % 10); if (dupflag) @@ -361,14 +353,16 @@ static void ping(const char *host) setsockopt_broadcast(pingsock); /* set recv buf for broadcast pings */ - sockopt = 48 * 1024; + sockopt = 48 * 1024; /* explain why 48k? */ setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt, sizeof(sockopt)); + sockopt = 2; /* iputils-ss020927 does this */ sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, (char *) &sockopt, sizeof(sockopt)); + /* request ttl info to be returned in ancillary data */ sockopt = 1; setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, (char *) &sockopt, sizeof(sockopt)); @@ -377,10 +371,10 @@ static void ping(const char *host) pingaddr.sin6_scope_id = if_index; printf("PING %s (%s): %d data bytes\n", - hostent->h_name, - inet_ntop(AF_INET6, &pingaddr.sin6_addr, + hostent->h_name, + inet_ntop(AF_INET6, &pingaddr.sin6_addr, buf, sizeof(buf)), - datalen); + datalen); signal(SIGINT, pingstats); @@ -397,21 +391,23 @@ static void ping(const char *host) iov.iov_len = sizeof(packet); while (1) { int c; - struct cmsghdr *cmsgptr = NULL; + struct cmsghdr *mp; int hoplimit = -1; msg.msg_controllen = sizeof(control_buf); - if ((c = recvmsg(pingsock, &msg, 0)) < 0) { - if (errno == EINTR) - continue; - bb_perror_msg("recvfrom"); + c = recvmsg(pingsock, &msg, 0); + if (c < 0) { + if (errno != EINTR) + bb_perror_msg("recvfrom"); continue; } - for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; - cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { - if (cmsgptr->cmsg_level == SOL_IPV6 && - cmsgptr->cmsg_type == IPV6_HOPLIMIT ) { - hoplimit = *(int*)CMSG_DATA(cmsgptr); + for (mp = CMSG_FIRSTHDR(&msg); mp; mp = CMSG_NXTHDR(&msg, mp)) { + if (mp->cmsg_level == SOL_IPV6 + && mp->cmsg_type == IPV6_HOPLIMIT + /* don't check len - we trust the kernel: */ + /* && mp->cmsg_len >= CMSG_LEN(sizeof(int)) */ + ) { + hoplimit = *(int*)CMSG_DATA(mp); } } unpack(packet, c, &from, hoplimit); -- 2.25.1