X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=networking%2Fping.c;h=a38f356d61c53ed83d9e806d0ef002ff0cf00551;hb=a8992635b117723e65078ada845cc88a9cb77aa3;hp=a4363098e6e341fede7a4b8727667fe6944f1edd;hpb=4e573f4729a2a6e2aeba56fcfc8ed4c1d41e83e9;p=oweals%2Fbusybox.git diff --git a/networking/ping.c b/networking/ping.c index a4363098e..a38f356d6 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -1,6 +1,6 @@ /* vi: set sw=4 ts=4: */ /* - * $Id: ping.c,v 1.26 2000/11/14 23:29:24 andersen Exp $ + * $Id: ping.c,v 1.55 2003/07/22 08:56:51 andersen Exp $ * Mini ping implementation for busybox * * Copyright (C) 1999 by Randolph Chung @@ -31,7 +31,6 @@ * Original copyright notice is retained at the end of this file. */ -#include "busybox.h" #include #include #include @@ -47,96 +46,19 @@ #include #include #include +#include +#include +#include +#include "busybox.h" -/* It turns out that libc5 doesn't have proper icmp support - * built into it header files, so we have to supplement it */ -#if ! defined __GLIBC__ && ! defined __UCLIBC__ -typedef unsigned int socklen_t; - -#define ICMP_MINLEN 8 /* abs minimum */ - -struct icmp_ra_addr -{ - u_int32_t ira_addr; - u_int32_t ira_preference; -}; - - -struct icmp -{ - u_int8_t icmp_type; /* type of message, see below */ - u_int8_t icmp_code; /* type sub code */ - u_int16_t icmp_cksum; /* ones complement checksum of struct */ - union - { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* gateway address */ - struct ih_idseq /* echo datagram */ - { - u_int16_t icd_id; - u_int16_t icd_seq; - } ih_idseq; - u_int32_t ih_void; - - /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ - struct ih_pmtu - { - u_int16_t ipm_void; - u_int16_t ipm_nextmtu; - } ih_pmtu; - - struct ih_rtradv - { - u_int8_t irt_num_addrs; - u_int8_t irt_wpa; - u_int16_t irt_lifetime; - } ih_rtradv; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu -#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs -#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa -#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime - union - { - struct - { - u_int32_t its_otime; - u_int32_t its_rtime; - u_int32_t its_ttime; - } id_ts; - struct - { - struct ip idi_ip; - /* options and then 64 bits of data */ - } id_ip; - struct icmp_ra_addr id_radv; - u_int32_t id_mask; - u_int8_t id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_radv icmp_dun.id_radv -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -}; -#endif - -#define DEFDATALEN 56 -#define MAXIPLEN 60 -#define MAXICMPLEN 76 -#define MAXPACKET 65468 +static const int DEFDATALEN = 56; +static const int MAXIPLEN = 60; +static const int MAXICMPLEN = 76; +static const int MAXPACKET = 65468; #define MAX_DUP_CHK (8 * 128) -#define MAXWAIT 10 -#define PINGINTERVAL 1 /* second */ +static const int MAXWAIT = 10; +static const int PINGINTERVAL = 1; /* second */ #define O_QUIET (1 << 0) @@ -173,13 +95,12 @@ static int in_cksum(unsigned short *buf, int sz) } /* simple version */ -#ifdef BB_FEATURE_SIMPLE_PING +#ifndef CONFIG_FEATURE_FANCY_PING static char *hostname = NULL; - static void noresp(int ign) { printf("No response from %s\n", hostname); - exit(0); + exit(EXIT_FAILURE); } static void ping(const char *host) @@ -190,21 +111,12 @@ static void ping(const char *host) int pingsock, c; char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; - if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ - perror("ping: creating a raw socket"); - exit(1); - } - - /* drop root privs if running setuid */ - setuid(getuid()); + pingsock = create_icmp_socket(); memset(&pingaddr, 0, sizeof(struct sockaddr_in)); pingaddr.sin_family = AF_INET; - if (!(h = gethostbyname(host))) { - errorMsg("unknown host %s\n", host); - exit(1); - } + h = xgethostbyname(host); memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); hostname = h->h_name; @@ -216,12 +128,8 @@ static void ping(const char *host) c = sendto(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); - if (c < 0 || c != sizeof(packet)) { - if (c < 0) - perror("ping: sendto"); - errorMsg("write incomplete\n"); - exit(1); - } + if (c < 0 || c != sizeof(packet)) + bb_perror_msg_and_die("sendto"); signal(SIGALRM, noresp); alarm(5); /* give the host 5000ms to respond */ @@ -234,7 +142,7 @@ static void ping(const char *host) (struct sockaddr *) &from, &fromlen)) < 0) { if (errno == EINTR) continue; - perror("ping: recvfrom"); + bb_perror_msg("recvfrom"); continue; } if (c >= 76) { /* ip + icmp */ @@ -254,23 +162,24 @@ extern int ping_main(int argc, char **argv) argc--; argv++; if (argc < 1) - usage(ping_usage); + bb_show_usage(); ping(*argv); - exit(TRUE); + return EXIT_SUCCESS; } -#else /* ! BB_FEATURE_SIMPLE_PING */ +#else /* ! CONFIG_FEATURE_FANCY_PING */ /* full(er) version */ -static char *hostname = NULL; static struct sockaddr_in pingaddr; static int pingsock = -1; -static int datalen = DEFDATALEN; +static int datalen; /* intentionally uninitialized to work around gcc bug */ -static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0; -static int myid = 0, options = 0; -static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0; +static long ntransmitted, nreceived, nrepeats, pingcount; +static int myid, options; +static unsigned long tmin = ULONG_MAX, tmax, tsum; static char rcvd_tbl[MAX_DUP_CHK / 8]; +struct hostent *hostent; + static void sendping(int); static void pingstats(int); static void unpack(char *, int, struct sockaddr_in *); @@ -283,7 +192,7 @@ static void pingstats(int junk) signal(SIGINT, SIG_IGN); - printf("\n--- %s ping statistics ---\n", hostname); + printf("\n--- %s ping statistics ---\n", hostent->h_name); printf("%ld packets transmitted, ", ntransmitted); printf("%ld packets received, ", nreceived); if (nrepeats) @@ -325,9 +234,9 @@ static void sendping(int junk) (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); if (i < 0) - fatalError("sendto: %s\n", strerror(errno)); + bb_perror_msg_and_die("sendto"); else if ((size_t)i != sizeof(packet)) - fatalError("ping wrote %d chars; %d expected\n", i, + bb_error_msg_and_die("ping wrote %d chars; %d expected", i, (int)sizeof(packet)); signal(SIGALRM, sendping); @@ -422,51 +331,25 @@ static void unpack(char *buf, int sz, struct sockaddr_in *from) printf("\n"); } else if (icmppkt->icmp_type != ICMP_ECHO) - errorMsg("Warning: Got ICMP %d (%s)\n", + bb_error_msg("Warning: Got ICMP %d (%s)", icmppkt->icmp_type, icmp_type_name (icmppkt->icmp_type)); } static void ping(const char *host) { - struct protoent *proto; - struct hostent *h; - char buf[MAXHOSTNAMELEN]; char packet[datalen + MAXIPLEN + MAXICMPLEN]; int sockopt; - proto = getprotobyname("icmp"); - /* if getprotobyname failed, just silently force - * proto->p_proto to have the correct value for "icmp" */ - if ((pingsock = socket(AF_INET, SOCK_RAW, - (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ - if (errno == EPERM) { - errorMsg("permission denied. (are you root?)\n"); - } else { - perror("ping: creating a raw socket"); - } - exit(1); - } - - /* drop root privs if running setuid */ - setuid(getuid()); + pingsock = create_icmp_socket(); memset(&pingaddr, 0, sizeof(struct sockaddr_in)); pingaddr.sin_family = AF_INET; - if (!(h = gethostbyname(host))) { - errorMsg("unknown host %s\n", host); - exit(1); - } - - if (h->h_addrtype != AF_INET) { - errorMsg("unknown address type; only AF_INET is currently supported.\n"); - exit(1); - } + hostent = xgethostbyname(host); + if (hostent->h_addrtype != AF_INET) + bb_error_msg_and_die("unknown address type; only AF_INET is currently supported."); - pingaddr.sin_family = AF_INET; /* h->h_addrtype */ - memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); - strncpy(buf, h->h_name, sizeof(buf) - 1); - hostname = buf; + memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr)); /* enable broadcast pings */ sockopt = 1; @@ -479,7 +362,7 @@ static void ping(const char *host) sizeof(sockopt)); printf("PING %s (%s): %d data bytes\n", - hostname, + hostent->h_name, inet_ntoa(*(struct in_addr *) &pingaddr.sin_addr.s_addr), datalen); @@ -498,7 +381,7 @@ static void ping(const char *host) (struct sockaddr *) &from, &fromlen)) < 0) { if (errno == EINTR) continue; - perror("ping: recvfrom"); + bb_perror_msg("recvfrom"); continue; } unpack(packet, c, &from); @@ -512,6 +395,8 @@ extern int ping_main(int argc, char **argv) { char *thisarg; + datalen = DEFDATALEN; /* initialized here rather than in global scope to work around gcc bug */ + argc--; argv++; options = 0; @@ -525,30 +410,30 @@ extern int ping_main(int argc, char **argv) break; case 'c': if (--argc <= 0) - usage(ping_usage); + bb_show_usage(); argv++; pingcount = atoi(*argv); break; case 's': if (--argc <= 0) - usage(ping_usage); + bb_show_usage(); argv++; datalen = atoi(*argv); break; default: - usage(ping_usage); + bb_show_usage(); } argc--; argv++; } if (argc < 1) - usage(ping_usage); + bb_show_usage(); myid = getpid() & 0xFFFF; ping(*argv); - return(TRUE); + return EXIT_SUCCESS; } -#endif /* ! BB_FEATURE_SIMPLE_PING */ +#endif /* ! CONFIG_FEATURE_FANCY_PING */ /* * Copyright (c) 1989 The Regents of the University of California.