diff options
author | Eric Andersen <andersen@codepoet.org> | 1999-12-11 08:41:28 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 1999-12-11 08:41:28 +0000 |
commit | 19db07b3d4ca4c333f9a53bfbc113b44f3c55750 (patch) | |
tree | 6c916e01a70d0d351778cffbee53a2d7e3d2f3b5 /networking/ping.c | |
parent | 59248bad97413798ac0cfdc5fcc75c7635a7ab1c (diff) | |
download | busybox-w32-19db07b3d4ca4c333f9a53bfbc113b44f3c55750.tar.gz busybox-w32-19db07b3d4ca4c333f9a53bfbc113b44f3c55750.tar.bz2 busybox-w32-19db07b3d4ca4c333f9a53bfbc113b44f3c55750.zip |
Ok, so this is reallt 0.38...
-Erik
Diffstat (limited to 'networking/ping.c')
-rw-r--r-- | networking/ping.c | 164 |
1 files changed, 123 insertions, 41 deletions
diff --git a/networking/ping.c b/networking/ping.c index 4176ab390..92b62def3 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ping.c,v 1.5 1999/12/09 06:11:36 andersen Exp $ | 2 | * $Id: ping.c,v 1.6 1999/12/11 08:41:28 andersen Exp $ |
3 | * Mini ping implementation for busybox | 3 | * Mini ping implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> | 5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> |
@@ -63,28 +63,7 @@ | |||
63 | #define CLR(bit) (A(bit) &= (~B(bit))) | 63 | #define CLR(bit) (A(bit) &= (~B(bit))) |
64 | #define TST(bit) (A(bit) & B(bit)) | 64 | #define TST(bit) (A(bit) & B(bit)) |
65 | 65 | ||
66 | static const char* ping_usage = "ping [OPTION]... host\n\n" | 66 | /* common routines */ |
67 | "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" | ||
68 | "Options:\n" | ||
69 | "\t-q\t\tQuiet mode, only displays output at start and when finished.\n" | ||
70 | "\t-c COUNT\tSend only COUNT pings.\n"; | ||
71 | |||
72 | static char *hostname = NULL; | ||
73 | static struct sockaddr_in pingaddr; | ||
74 | static int pingsock = -1; | ||
75 | static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0; | ||
76 | static int myid = 0, options = 0; | ||
77 | static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0; | ||
78 | static char rcvd_tbl[MAX_DUP_CHK / 8]; | ||
79 | |||
80 | static void pingstats(int); | ||
81 | static void sendping(int); | ||
82 | static void unpack(char *, int, struct sockaddr_in *); | ||
83 | static void ping(char *); | ||
84 | static int in_cksum(unsigned short *, int); | ||
85 | |||
86 | /**************************************************************************/ | ||
87 | |||
88 | static int in_cksum(unsigned short *buf, int sz) | 67 | static int in_cksum(unsigned short *buf, int sz) |
89 | { | 68 | { |
90 | int nleft = sz; | 69 | int nleft = sz; |
@@ -108,6 +87,114 @@ static int in_cksum(unsigned short *buf, int sz) | |||
108 | return(ans); | 87 | return(ans); |
109 | } | 88 | } |
110 | 89 | ||
90 | /* simple version */ | ||
91 | #ifdef BB_SIMPLE_PING | ||
92 | static const char* ping_usage = "ping host\n\n"; | ||
93 | |||
94 | static char* hostname = NULL; | ||
95 | |||
96 | static void noresp(int ign) | ||
97 | { | ||
98 | printf("No response from %s\n", hostname); | ||
99 | exit(0); | ||
100 | } | ||
101 | |||
102 | static int ping(const char *host) | ||
103 | { | ||
104 | struct hostent *h; | ||
105 | struct sockaddr_in pingaddr; | ||
106 | struct icmp *pkt; | ||
107 | int pingsock, c; | ||
108 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; | ||
109 | |||
110 | if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ | ||
111 | perror("ping"); | ||
112 | exit(1); | ||
113 | } | ||
114 | |||
115 | /* drop root privs if running setuid */ | ||
116 | setuid(getuid()); | ||
117 | |||
118 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); | ||
119 | pingaddr.sin_family = AF_INET; | ||
120 | if (!(h = gethostbyname(host))) { | ||
121 | fprintf(stderr, "ping: unknown host %s\n", host); | ||
122 | exit(1); | ||
123 | } | ||
124 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); | ||
125 | hostname = h->h_name; | ||
126 | |||
127 | pkt = (struct icmp *)packet; | ||
128 | memset(pkt, 0, sizeof(packet)); | ||
129 | pkt->icmp_type = ICMP_ECHO; | ||
130 | pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet)); | ||
131 | |||
132 | c = sendto(pingsock, packet, sizeof(packet), 0, | ||
133 | (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in)); | ||
134 | |||
135 | if (c < 0 || c != sizeof(packet)) { | ||
136 | if (c < 0) perror("ping"); | ||
137 | fprintf(stderr, "ping: write incomplete\n"); | ||
138 | exit(1); | ||
139 | } | ||
140 | |||
141 | signal(SIGALRM, noresp); | ||
142 | alarm(5); /* give the host 5000ms to respond */ | ||
143 | /* listen for replies */ | ||
144 | while (1) { | ||
145 | struct sockaddr_in from; | ||
146 | size_t fromlen = sizeof(from); | ||
147 | |||
148 | if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, | ||
149 | (struct sockaddr *)&from, &fromlen)) < 0) { | ||
150 | if (errno == EINTR) continue; | ||
151 | perror("ping"); | ||
152 | continue; | ||
153 | } | ||
154 | if (c >= 76) { /* ip + icmp */ | ||
155 | struct iphdr *iphdr = (struct iphdr *)packet; | ||
156 | pkt = (struct icmp *)(packet + (iphdr->ihl << 2)); /* skip ip hdr */ | ||
157 | if (pkt->icmp_type == ICMP_ECHOREPLY) break; | ||
158 | } | ||
159 | } | ||
160 | printf("%s is alive!\n", hostname); | ||
161 | return(TRUE); | ||
162 | } | ||
163 | |||
164 | extern int ping_main(int argc, char **argv) | ||
165 | { | ||
166 | argc--; | ||
167 | argv++; | ||
168 | if (argc < 1) usage(ping_usage); | ||
169 | ping(*argv); | ||
170 | exit(TRUE); | ||
171 | } | ||
172 | |||
173 | #else | ||
174 | /* full(er) version */ | ||
175 | static const char* ping_usage = "ping [OPTION]... host\n\n" | ||
176 | "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" | ||
177 | "Options:\n" | ||
178 | "\t-q\t\tQuiet mode, only displays output at start and when finished.\n" | ||
179 | "\t-c COUNT\tSend only COUNT pings.\n"; | ||
180 | |||
181 | static char *hostname = NULL; | ||
182 | static struct sockaddr_in pingaddr; | ||
183 | static int pingsock = -1; | ||
184 | |||
185 | static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0; | ||
186 | static int myid = 0, options = 0; | ||
187 | static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0; | ||
188 | static char rcvd_tbl[MAX_DUP_CHK / 8]; | ||
189 | |||
190 | static void sendping(int); | ||
191 | static void pingstats(int); | ||
192 | static void unpack(char *, int, struct sockaddr_in *); | ||
193 | |||
194 | static void ping(char *); | ||
195 | |||
196 | /**************************************************************************/ | ||
197 | |||
111 | static void pingstats(int ign) { | 198 | static void pingstats(int ign) { |
112 | signal(SIGINT, SIG_IGN); | 199 | signal(SIGINT, SIG_IGN); |
113 | 200 | ||
@@ -249,24 +336,20 @@ static void ping(char *host) | |||
249 | 336 | ||
250 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); | 337 | memset(&pingaddr, 0, sizeof(struct sockaddr_in)); |
251 | pingaddr.sin_family = AF_INET; | 338 | pingaddr.sin_family = AF_INET; |
252 | if (inet_aton(host, &pingaddr.sin_addr)) { | 339 | if (!(h = gethostbyname(host))) { |
253 | hostname = host; | 340 | fprintf(stderr, "ping: unknown host %s\n", host); |
254 | } else { | 341 | exit(1); |
255 | if (!(h = gethostbyname(host))) { | 342 | } |
256 | fprintf(stderr, "ping: unknown host %s\n", host); | ||
257 | exit(1); | ||
258 | } | ||
259 | 343 | ||
260 | if (h->h_addrtype != AF_INET) { | 344 | if (h->h_addrtype != AF_INET) { |
261 | fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n"); | 345 | fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n"); |
262 | exit(1); | 346 | exit(1); |
263 | } | ||
264 | |||
265 | pingaddr.sin_family = AF_INET; /* h->h_addrtype */ | ||
266 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); | ||
267 | strncpy(buf, h->h_name, sizeof(buf)-1); | ||
268 | hostname = buf; | ||
269 | } | 347 | } |
348 | |||
349 | pingaddr.sin_family = AF_INET; /* h->h_addrtype */ | ||
350 | memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); | ||
351 | strncpy(buf, h->h_name, sizeof(buf)-1); | ||
352 | hostname = buf; | ||
270 | 353 | ||
271 | /* enable broadcast pings */ | 354 | /* enable broadcast pings */ |
272 | sockopt = 1; | 355 | sockopt = 1; |
@@ -331,6 +414,7 @@ extern int ping_main(int argc, char **argv) | |||
331 | ping(*argv); | 414 | ping(*argv); |
332 | exit(TRUE); | 415 | exit(TRUE); |
333 | } | 416 | } |
417 | #endif | ||
334 | 418 | ||
335 | /* | 419 | /* |
336 | * Copyright (c) 1989 The Regents of the University of California. | 420 | * Copyright (c) 1989 The Regents of the University of California. |
@@ -367,5 +451,3 @@ extern int ping_main(int argc, char **argv) | |||
367 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 451 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
368 | * SUCH DAMAGE. | 452 | * SUCH DAMAGE. |
369 | */ | 453 | */ |
370 | |||
371 | |||