X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fping.c;h=3df67f5c39845125339ce54daf05abf9423b4735;hb=a8816dafc4b274b17c58df88cabdbf9e2b47f528;hp=7f74c26fa5c355e8a4bfb42f7582005f79a52cd6;hpb=3c8799b8a45def567705bfd07b8745e99d5f2dd9;p=oweals%2Fbusybox.git diff --git a/networking/ping.c b/networking/ping.c index 7f74c26fa..3df67f5c3 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -29,10 +29,26 @@ #include #include "libbb.h" +#ifdef __BIONIC__ +/* should be in netinet/ip_icmp.h */ +# define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ +# define ICMP_SOURCE_QUENCH 4 /* Source Quench */ +# define ICMP_REDIRECT 5 /* Redirect (change route) */ +# define ICMP_ECHO 8 /* Echo Request */ +# define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ +# define ICMP_PARAMETERPROB 12 /* Parameter Problem */ +# define ICMP_TIMESTAMP 13 /* Timestamp Request */ +# define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ +# define ICMP_INFO_REQUEST 15 /* Information Request */ +# define ICMP_INFO_REPLY 16 /* Information Reply */ +# define ICMP_ADDRESS 17 /* Address Mask Request */ +# define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ +#endif + //config:config PING //config: bool "ping" //config: default y -//config: depends on PLATFORM_LINUX +//config: select PLATFORM_LINUX //config: help //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. @@ -52,8 +68,9 @@ //config: Make the output from the ping applet include statistics, and at the //config: same time provide full support for ICMP packets. -//applet:IF_PING(APPLET(ping, _BB_DIR_BIN, _BB_SUID_MAYBE)) -//applet:IF_PING6(APPLET(ping6, _BB_DIR_BIN, _BB_SUID_MAYBE)) +/* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */ +//applet:IF_PING(APPLET(ping, BB_DIR_BIN, BB_SUID_MAYBE)) +//applet:IF_PING6(APPLET(ping6, BB_DIR_BIN, BB_SUID_MAYBE)) //kbuild:lib-$(CONFIG_PING) += ping.o //kbuild:lib-$(CONFIG_PING6) += ping.o @@ -72,7 +89,6 @@ //usage: "[OPTIONS] HOST" //usage:# define ping_full_usage "\n\n" //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" -//usage: "\nOptions:" //usage: "\n -4,-6 Force IP or IPv6 name resolution" //usage: "\n -c CNT Send only CNT pings" //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" @@ -89,7 +105,6 @@ //usage: "[OPTIONS] HOST" //usage:# define ping6_full_usage "\n\n" //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" -//usage: "\nOptions:" //usage: "\n -c CNT Send only CNT pings" //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" //usage: "\n -I IFACE/IP Use interface or IP address as source" @@ -134,31 +149,6 @@ enum { PINGINTERVAL = 1, /* 1 second */ }; -/* Common routines */ - -static int in_cksum(unsigned short *buf, int sz) -{ - int nleft = sz; - int sum = 0; - unsigned short *w = buf; - unsigned short ans = 0; - - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - if (nleft == 1) { - *(unsigned char *) (&ans) = *(unsigned char *) w; - sum += ans; - } - - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - ans = ~sum; - return ans; -} - #if !ENABLE_FEATURE_FANCY_PING /* Simple version */ @@ -186,7 +176,7 @@ static void ping4(len_and_sockaddr *lsa) pkt = (struct icmp *) G.packet; memset(pkt, 0, sizeof(G.packet)); pkt->icmp_type = ICMP_ECHO; - pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(G.packet)); + pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); @@ -418,16 +408,18 @@ static void print_stats_and_exit(int junk UNUSED_PARAM) exit(nreceived == 0 || (deadline && nreceived < pingcount)); } -static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) +static void sendping_tail(void (*sp)(int), int size_pkt) { int sz; CLR((uint16_t)ntransmitted % MAX_DUP_CHK); ntransmitted++; + size_pkt += datalen; + /* sizeof(pingaddr) can be larger than real sa size, but I think * it doesn't matter */ - sz = xsendto(pingsock, pkt, size_pkt, &pingaddr.sa, sizeof(pingaddr)); + sz = xsendto(pingsock, G.snd_packet, size_pkt, &pingaddr.sa, sizeof(pingaddr)); if (sz != size_pkt) bb_error_msg_and_die(bb_msg_write_error); @@ -476,14 +468,14 @@ static void sendping4(int junk UNUSED_PARAM) /* No hton: we'll read it back on the same machine */ *(uint32_t*)&pkt->icmp_dun = monotonic_us(); - pkt->icmp_cksum = in_cksum((unsigned short *) pkt, datalen + ICMP_MINLEN); + pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, datalen + ICMP_MINLEN); - sendping_tail(sendping4, pkt, datalen + ICMP_MINLEN); + sendping_tail(sendping4, ICMP_MINLEN); } #if ENABLE_PING6 static void sendping6(int junk UNUSED_PARAM) { - struct icmp6_hdr *pkt = alloca(datalen + sizeof(struct icmp6_hdr) + 4); + struct icmp6_hdr *pkt = G.snd_packet; //memset(pkt, 0, datalen + sizeof(struct icmp6_hdr) + 4); pkt->icmp6_type = ICMP6_ECHO_REQUEST; @@ -495,9 +487,9 @@ static void sendping6(int junk UNUSED_PARAM) /*if (datalen >= 4)*/ *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); - //TODO? pkt->icmp_cksum = in_cksum(...); + //TODO? pkt->icmp_cksum = inet_cksum(...); - sendping_tail(sendping6, pkt, datalen + sizeof(struct icmp6_hdr)); + sendping_tail(sendping6, sizeof(struct icmp6_hdr)); } #endif @@ -621,7 +613,7 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from) } } #if ENABLE_PING6 -static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hoplimit) +static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit) { struct icmp6_hdr *icmppkt; char buf[INET6_ADDRSTRLEN]; @@ -641,7 +633,7 @@ static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hop if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t)) tp = (uint32_t *) &icmppkt->icmp6_data8[4]; unpack_tail(sz, tp, - inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr, + inet_ntop(AF_INET6, &from->sin6_addr, buf, sizeof(buf)), recv_seq, hoplimit); } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) { @@ -732,7 +724,7 @@ static void ping6(len_and_sockaddr *lsa) ICMP6_FILTER_SETPASSALL(&filt); } if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, - sizeof(filt)) < 0) + sizeof(filt)) < 0) bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); } #endif /*ICMP6_FILTER*/ @@ -791,7 +783,7 @@ static void ping6(len_and_sockaddr *lsa) move_from_unaligned_int(hoplimit, CMSG_DATA(mp)); } } - unpack6(G.rcv_packet, c, /*&from,*/ hoplimit); + unpack6(G.rcv_packet, c, &from, hoplimit); if (pingcount && nreceived >= pingcount) break; }