aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorerik <erik@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-02-08 19:58:47 +0000
committererik <erik@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-02-08 19:58:47 +0000
commita18125005d67c38a8ad7fb454571bb996664ad96 (patch)
treec90bda10731ad9333ce3b404f993354c9fc104b8 /networking
parent8ef3b44285a8ce5b83bed9cf32ce5f40b30ba72f (diff)
downloadbusybox-w32-a18125005d67c38a8ad7fb454571bb996664ad96.tar.gz
busybox-w32-a18125005d67c38a8ad7fb454571bb996664ad96.tar.bz2
busybox-w32-a18125005d67c38a8ad7fb454571bb996664ad96.zip
Some formatting updates (ran the code through indent)
-Erik git-svn-id: svn://busybox.net/trunk/busybox@357 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'networking')
-rw-r--r--networking/hostname.c193
-rw-r--r--networking/nslookup.c185
-rw-r--r--networking/ping.c618
3 files changed, 511 insertions, 485 deletions
diff --git a/networking/hostname.c b/networking/hostname.c
index 68a560950..8cc334da0 100644
--- a/networking/hostname.c
+++ b/networking/hostname.c
@@ -1,5 +1,6 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $ 3 * $Id: hostname.c,v 1.7 2000/02/08 19:58:47 erik Exp $
3 * Mini hostname implementation for busybox 4 * Mini hostname implementation for busybox
4 * 5 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 6 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -29,110 +30,116 @@
29#include <unistd.h> 30#include <unistd.h>
30#include <stdio.h> 31#include <stdio.h>
31 32
32static const char* hostname_usage = 33static const char *hostname_usage =
33"hostname [OPTION] {hostname | -F file}\n\n" 34 "hostname [OPTION] {hostname | -F file}\n\n"
34"Get or set the hostname or DNS domain name. If a hostname is given\n" 35 "Get or set the hostname or DNS domain name. If a hostname is given\n"
35"(or a file with the -F parameter), the host name will be set.\n\n" 36 "(or a file with the -F parameter), the host name will be set.\n\n"
36"Options:\n" 37 "Options:\n"
37"\t-s\t\tShort\n" 38 "\t-s\t\tShort\n"
38"\t-i\t\tAddresses for the hostname\n" 39
39"\t-d\t\tDNS domain name\n" 40 "\t-i\t\tAddresses for the hostname\n"
40"\t-F FILE\t\tUse the contents of FILE to specify the hostname\n"; 41 "\t-d\t\tDNS domain name\n"
42 "\t-F FILE\t\tUse the contents of FILE to specify the hostname\n";
41 43
42 44
43void do_sethostname(char *s, int isfile) 45void do_sethostname(char *s, int isfile)
44{ 46{
45 FILE *f; 47 FILE *f;
46 char buf[255]; 48 char buf[255];
47 49
48 if (!s) return; 50 if (!s)
49 if (!isfile) { 51 return;
50 if (sethostname(s, strlen(s)) < 0) { 52 if (!isfile) {
51 if (errno == EPERM) 53 if (sethostname(s, strlen(s)) < 0) {
52 fprintf(stderr, "hostname: you must be root to change the hostname\n"); 54 if (errno == EPERM)
53 else 55 fprintf(stderr,
54 perror("sethostname"); 56 "hostname: you must be root to change the hostname\n");
55 exit(1); 57 else
56 } 58 perror("sethostname");
57 } else { 59 exit(1);
58 if ((f = fopen(s, "r")) == NULL) { 60 }
59 perror(s);
60 exit(1);
61 } else { 61 } else {
62 fgets(buf, 255, f); 62 if ((f = fopen(s, "r")) == NULL) {
63 fclose(f); 63 perror(s);
64 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0; 64 exit(1);
65 if (sethostname(buf, strlen(buf)) < 0) { 65 } else {
66 perror("sethostname"); 66 fgets(buf, 255, f);
67 exit(1); 67 fclose(f);
68 } 68 if (buf[strlen(buf) - 1] == '\n')
69 buf[strlen(buf) - 1] = 0;
70 if (sethostname(buf, strlen(buf)) < 0) {
71 perror("sethostname");
72 exit(1);
73 }
74 }
69 } 75 }
70 }
71} 76}
72 77
73int hostname_main(int argc, char **argv) 78int hostname_main(int argc, char **argv)
74{ 79{
75 int opt_short = 0; 80 int opt_short = 0;
76 int opt_domain = 0; 81 int opt_domain = 0;
77 int opt_ip = 0; 82 int opt_ip = 0;
78 struct hostent *h; 83 struct hostent *h;
79 char *filename = NULL; 84 char *filename = NULL;
80 char buf[255]; 85 char buf[255];
81 char *s = NULL; 86 char *s = NULL;
82
83 if (argc < 1) usage(hostname_usage);
84 87
85 while (--argc > 0 && **(++argv) == '-') { 88 if (argc < 1)
86 while (*(++(*argv))) {
87 switch (**argv) {
88 case 's':
89 opt_short = 1;
90 break;
91 case 'i':
92 opt_ip = 1;
93 break;
94 case 'd':
95 opt_domain = 1;
96 break;
97 case 'F':
98 filename = optarg;
99 if (--argc == 0) {
100 usage(hostname_usage);
101 }
102 filename = *(++argv);
103 break;
104 default:
105 usage(hostname_usage); 89 usage(hostname_usage);
106 } 90
107 if (filename!=NULL) 91 while (--argc > 0 && **(++argv) == '-') {
108 break; 92 while (*(++(*argv))) {
93 switch (**argv) {
94 case 's':
95 opt_short = 1;
96 break;
97 case 'i':
98 opt_ip = 1;
99 break;
100 case 'd':
101 opt_domain = 1;
102 break;
103 case 'F':
104 filename = optarg;
105 if (--argc == 0) {
106 usage(hostname_usage);
107 }
108 filename = *(++argv);
109 break;
110 default:
111 usage(hostname_usage);
112 }
113 if (filename != NULL)
114 break;
115 }
109 } 116 }
110 }
111 117
112 if (argc >= 1) { 118 if (argc >= 1) {
113 do_sethostname(*argv, 0); 119 do_sethostname(*argv, 0);
114 } else if (filename!=NULL) { 120 } else if (filename != NULL) {
115 do_sethostname(filename, 1); 121 do_sethostname(filename, 1);
116 } else { 122 } else {
117 gethostname(buf, 255); 123 gethostname(buf, 255);
118 if (opt_short) { 124 if (opt_short) {
119 s = strchr(buf, '.'); 125 s = strchr(buf, '.');
120 if (!s) s = buf; *s = 0; 126 if (!s)
121 printf("%s\n", buf); 127 s = buf;
122 } else if (opt_domain) { 128 *s = 0;
123 s = strchr(buf, '.'); 129 printf("%s\n", buf);
124 printf("%s\n", (s ? s+1 : "")); 130 } else if (opt_domain) {
125 } else if (opt_ip) { 131 s = strchr(buf, '.');
126 h = gethostbyname(buf); 132 printf("%s\n", (s ? s + 1 : ""));
127 if (!h) { 133 } else if (opt_ip) {
128 printf("Host not found\n"); 134 h = gethostbyname(buf);
129 exit(1); 135 if (!h) {
130 } 136 printf("Host not found\n");
131 printf("%s\n", inet_ntoa(*(struct in_addr *)(h->h_addr))); 137 exit(1);
132 } else { 138 }
133 printf("%s\n", buf); 139 printf("%s\n", inet_ntoa(*(struct in_addr *) (h->h_addr)));
134 } 140 } else {
135 } 141 printf("%s\n", buf);
136 exit( 0); 142 }
143 }
144 exit(0);
137} 145}
138
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 969d0b19b..ffa720174 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -1,3 +1,4 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * Mini nslookup implementation for busybox 3 * Mini nslookup implementation for busybox
3 * 4 *
@@ -41,148 +42,136 @@
41 | + find out how the real nslookup gets the default name server 42 | + find out how the real nslookup gets the default name server
42 */ 43 */
43 44
44static const char nslookup_usage[] = 45static const char nslookup_usage[] = "nslookup [HOST]\n\n";
45 "nslookup [HOST]\n\n"
46;
47 46
48 47
49/* I have to see how the real nslookup does this. 48/* I have to see how the real nslookup does this.
50 * I could dig through /etc/resolv.conf, but is there a 49 * I could dig through /etc/resolv.conf, but is there a
51 * better (programatic) way? 50 * better (programatic) way?
52 */ 51 */
53static void 52static void server_fprint(FILE * dst)
54server_fprint(FILE *dst)
55{ 53{
56 fprintf(dst, "Server: %s\n", "something"); 54 fprintf(dst, "Server: %s\n", "something");
57 fprintf(dst, "Address: %s\n\n", "something"); 55 fprintf(dst, "Address: %s\n\n", "something");
58} 56}
59 57
60/* only works for IPv4 */ 58/* only works for IPv4 */
61static int 59static int addr_fprint(char *addr, FILE * dst)
62addr_fprint(char *addr, FILE *dst)
63{ 60{
64 uint8_t split[4]; 61 uint8_t split[4];
65 uint32_t ip; 62 uint32_t ip;
66 uint32_t *x = (uint32_t *) addr; 63 uint32_t *x = (uint32_t *) addr;
67 64
68 ip = ntohl(*x); 65 ip = ntohl(*x);
69 split[0] = (ip & 0xff000000) >> 24; 66 split[0] = (ip & 0xff000000) >> 24;
70 split[1] = (ip & 0x00ff0000) >> 16; 67 split[1] = (ip & 0x00ff0000) >> 16;
71 split[2] = (ip & 0x0000ff00) >> 8; 68 split[2] = (ip & 0x0000ff00) >> 8;
72 split[3] = (ip & 0x000000ff); 69 split[3] = (ip & 0x000000ff);
73 fprintf ( 70 fprintf(dst, "%d.%d.%d.%d", split[0], split[1], split[2], split[3]
74 dst, "%d.%d.%d.%d", 71 );
75 split[0], split[1], split[2], split[3] 72 return 0;
76 );
77 return 0;
78} 73}
79 74
80/* changes a c-string matching the perl regex \d+\.\d+\.\d+\.\d+ 75/* changes a c-string matching the perl regex \d+\.\d+\.\d+\.\d+
81 * into a uint32_t 76 * into a uint32_t
82 */ 77 */
83static uint32_t 78static uint32_t str_to_addr(const char *addr)
84str_to_addr(const char *addr)
85{ 79{
86 uint32_t split[4]; 80 uint32_t split[4];
87 uint32_t ip; 81 uint32_t ip;
88 82
89 sscanf(addr, "%d.%d.%d.%d", 83 sscanf(addr, "%d.%d.%d.%d",
90 &split[0], &split[1], &split[2], &split[3]); 84 &split[0], &split[1], &split[2], &split[3]);
91 85
92 /* assuming sscanf worked */ 86 /* assuming sscanf worked */
93 ip = (split[0] << 24) | 87 ip = (split[0] << 24) |
94 (split[1] << 16) | 88 (split[1] << 16) | (split[2] << 8) | (split[3]);
95 (split[2] << 8) |
96 (split[3]);
97 89
98 return htonl(ip); 90 return htonl(ip);
99} 91}
100 92
101/* takes the NULL-terminated array h_addr_list, and 93/* takes the NULL-terminated array h_addr_list, and
102 * prints its contents appropriately 94 * prints its contents appropriately
103 */ 95 */
104static int 96static int addr_list_fprint(char **h_addr_list, FILE * dst)
105addr_list_fprint(char **h_addr_list, FILE *dst)
106{ 97{
107 int i, j; 98 int i, j;
108 char *addr_string = (h_addr_list[1]) 99 char *addr_string = (h_addr_list[1])
109 ? "Addresses" 100 ? "Addresses" : "Address";
110 : "Address"; 101
111 102 fprintf(dst, "%s: ", addr_string);
112 fprintf(dst, "%s: ", addr_string); 103 for (i = 0, j = 0; h_addr_list[i]; i++, j++) {
113 for (i = 0, j = 0; h_addr_list[i]; i++, j++) { 104 addr_fprint(h_addr_list[i], dst);
114 addr_fprint(h_addr_list[i], dst); 105
115 106 /* real nslookup does this */
116 /* real nslookup does this */ 107 if (j == 4) {
117 if (j == 4) { 108 if (h_addr_list[i + 1]) {
118 if (h_addr_list[i+1]) { 109 fprintf(dst, "\n ");
119 fprintf(dst, "\n "); 110 }
120 } 111 j = 0;
121 j = 0; 112 } else {
122 } else { 113 if (h_addr_list[i + 1]) {
123 if (h_addr_list[i+1]) { 114 fprintf(dst, ", ");
124 fprintf(dst, ", "); 115 }
125 } 116 }
126 }
127 117
128 } 118 }
129 fprintf(dst,"\n"); 119 fprintf(dst, "\n");
130 return 0; 120 return 0;
131} 121}
132 122
133/* gethostbyaddr wrapper */ 123/* gethostbyaddr wrapper */
134static struct hostent * 124static struct hostent *gethostbyaddr_wrapper(const char *address)
135gethostbyaddr_wrapper(const char *address)
136{ 125{
137 struct in_addr addr; 126 struct in_addr addr;
138 127
139 addr.s_addr = str_to_addr(address); 128 addr.s_addr = str_to_addr(address);
140 return gethostbyaddr((char *) &addr, 4, AF_INET); /* IPv4 only for now */ 129 return gethostbyaddr((char *) &addr, 4, AF_INET); /* IPv4 only for now */
141} 130}
142 131
143/* print the results as nslookup would */ 132/* print the results as nslookup would */
144static struct hostent * 133static struct hostent *hostent_fprint(struct hostent *host, FILE * dst)
145hostent_fprint(struct hostent *host, FILE *dst)
146{ 134{
147 if (host) { 135 if (host) {
148 fprintf(dst, "Name: %s\n", host->h_name); 136 fprintf(dst, "Name: %s\n", host->h_name);
149 addr_list_fprint(host->h_addr_list, dst); 137 addr_list_fprint(host->h_addr_list, dst);
150 } else { 138 } else {
151 fprintf(dst, "*** %s\n", hstrerror(h_errno)); 139 fprintf(dst, "*** %s\n", hstrerror(h_errno));
152 } 140 }
153 return host; 141 return host;
154} 142}
155 143
156 144
157/* naive function to check whether char *s is an ip address */ 145/* naive function to check whether char *s is an ip address */
158static int 146static int is_ip_address(const char *s)
159is_ip_address(const char *s)
160{ 147{
161 while (*s) { 148 while (*s) {
162 if ((isdigit(*s)) || (*s == '.')) { s++; continue; } 149 if ((isdigit(*s)) || (*s == '.')) {
163 return 0; 150 s++;
164 } 151 continue;
165 return 1; 152 }
153 return 0;
154 }
155 return 1;
166} 156}
167 157
168/* ________________________________________________________________________ */ 158/* ________________________________________________________________________ */
169int 159int nslookup_main(int argc, char **argv)
170nslookup_main(int argc, char **argv)
171{ 160{
172 struct hostent *host; 161 struct hostent *host;
173 162
174 if (argc < 2) { 163 if (argc < 2) {
175 usage(nslookup_usage); 164 usage(nslookup_usage);
176 } 165 }
177 166
178 server_fprint(stdout); 167 server_fprint(stdout);
179 if (is_ip_address(argv[1])) { 168 if (is_ip_address(argv[1])) {
180 host = gethostbyaddr_wrapper(argv[1]); 169 host = gethostbyaddr_wrapper(argv[1]);
181 } else { 170 } else {
182 host = gethostbyname(argv[1]); 171 host = gethostbyname(argv[1]);
183 } 172 }
184 hostent_fprint(host, stdout); 173 hostent_fprint(host, stdout);
185 return 0; 174 return 0;
186} 175}
187 176
188/* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */ 177/* $Id: nslookup.c,v 1.4 2000/02/08 19:58:47 erik Exp $ */
diff --git a/networking/ping.c b/networking/ping.c
index 3ffbdc553..c9cf5ffb4 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -1,5 +1,6 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $ 3 * $Id: ping.c,v 1.11 2000/02/08 19:58:47 erik Exp $
3 * Mini ping implementation for busybox 4 * Mini ping implementation for busybox
4 * 5 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 6 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -53,7 +54,7 @@
53#define MAXPACKET 65468 54#define MAXPACKET 65468
54#define MAX_DUP_CHK (8 * 128) 55#define MAX_DUP_CHK (8 * 128)
55#define MAXWAIT 10 56#define MAXWAIT 10
56#define PINGINTERVAL 1 /* second */ 57#define PINGINTERVAL 1 /* second */
57 58
58#define O_QUIET (1 << 0) 59#define O_QUIET (1 << 0)
59 60
@@ -66,118 +67,124 @@
66/* common routines */ 67/* common routines */
67static int in_cksum(unsigned short *buf, int sz) 68static int in_cksum(unsigned short *buf, int sz)
68{ 69{
69 int nleft = sz; 70 int nleft = sz;
70 int sum = 0; 71 int sum = 0;
71 unsigned short *w = buf; 72 unsigned short *w = buf;
72 unsigned short ans = 0; 73 unsigned short ans = 0;
73 74
74 while (nleft > 1) { 75 while (nleft > 1) {
75 sum += *w++; 76 sum += *w++;
76 nleft -= 2; 77 nleft -= 2;
77 } 78 }
78 79
79 if (nleft == 1) { 80 if (nleft == 1) {
80 *(unsigned char *)(&ans) = *(unsigned char *)w; 81 *(unsigned char *) (&ans) = *(unsigned char *) w;
81 sum += ans; 82 sum += ans;
82 } 83 }
83 84
84 sum = (sum >> 16) + (sum & 0xFFFF); 85 sum = (sum >> 16) + (sum & 0xFFFF);
85 sum += (sum >> 16); 86 sum += (sum >> 16);
86 ans = ~sum; 87 ans = ~sum;
87 return(ans); 88 return (ans);
88} 89}
89 90
90/* simple version */ 91/* simple version */
91#ifdef BB_SIMPLE_PING 92#ifdef BB_SIMPLE_PING
92static const char* ping_usage = "ping host\n\n"; 93static const char *ping_usage = "ping host\n\n";
93 94
94static char* hostname = NULL; 95static char *hostname = NULL;
95 96
96static void noresp(int ign) 97static void noresp(int ign)
97{ 98{
98 printf("No response from %s\n", hostname); 99 printf("No response from %s\n", hostname);
99 exit(0); 100 exit(0);
100} 101}
101 102
102static int ping(const char *host) 103static int ping(const char *host)
103{ 104{
104 struct hostent *h; 105 struct hostent *h;
105 struct sockaddr_in pingaddr; 106 struct sockaddr_in pingaddr;
106 struct icmp *pkt; 107 struct icmp *pkt;
107 int pingsock, c; 108 int pingsock, c;
108 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; 109 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
109 110
110 if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ 111 if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */
111 perror("ping"); 112 perror("ping");
112 exit(1); 113 exit(1);
113 } 114 }
114 115
115 /* drop root privs if running setuid */ 116 /* drop root privs if running setuid */
116 setuid(getuid()); 117 setuid(getuid());
117 118
118 memset(&pingaddr, 0, sizeof(struct sockaddr_in)); 119 memset(&pingaddr, 0, sizeof(struct sockaddr_in));
119 pingaddr.sin_family = AF_INET; 120
120 if (!(h = gethostbyname(host))) { 121 pingaddr.sin_family = AF_INET;
121 fprintf(stderr, "ping: unknown host %s\n", host); 122 if (!(h = gethostbyname(host))) {
122 exit(1); 123 fprintf(stderr, "ping: unknown host %s\n", host);
123 } 124 exit(1);
124 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); 125 }
125 hostname = h->h_name; 126 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
126 127 hostname = h->h_name;
127 pkt = (struct icmp *)packet; 128
128 memset(pkt, 0, sizeof(packet)); 129 pkt = (struct icmp *) packet;
129 pkt->icmp_type = ICMP_ECHO; 130 memset(pkt, 0, sizeof(packet));
130 pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet)); 131 pkt->icmp_type = ICMP_ECHO;
131 132 pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
132 c = sendto(pingsock, packet, sizeof(packet), 0, 133
133 (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in)); 134 c = sendto(pingsock, packet, sizeof(packet), 0,
134 135 (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
135 if (c < 0 || c != sizeof(packet)) { 136
136 if (c < 0) perror("ping"); 137 if (c < 0 || c != sizeof(packet)) {
137 fprintf(stderr, "ping: write incomplete\n"); 138 if (c < 0)
138 exit(1); 139 perror("ping");
139 } 140 fprintf(stderr, "ping: write incomplete\n");
140 141 exit(1);
141 signal(SIGALRM, noresp); 142 }
142 alarm(5); /* give the host 5000ms to respond */ 143
143 /* listen for replies */ 144 signal(SIGALRM, noresp);
144 while (1) { 145 alarm(5); /* give the host 5000ms to respond */
145 struct sockaddr_in from; 146 /* listen for replies */
146 size_t fromlen = sizeof(from); 147 while (1) {
147 148 struct sockaddr_in from;
148 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, 149 size_t fromlen = sizeof(from);
149 (struct sockaddr *)&from, &fromlen)) < 0) { 150
150 if (errno == EINTR) continue; 151 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
151 perror("ping"); 152 (struct sockaddr *) &from, &fromlen)) < 0) {
152 continue; 153 if (errno == EINTR)
154 continue;
155 perror("ping");
156 continue;
157 }
158 if (c >= 76) { /* ip + icmp */
159 struct iphdr *iphdr = (struct iphdr *) packet;
160
161 pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */
162 if (pkt->icmp_type == ICMP_ECHOREPLY)
163 break;
164 }
153 } 165 }
154 if (c >= 76) { /* ip + icmp */ 166 printf("%s is alive!\n", hostname);
155 struct iphdr *iphdr = (struct iphdr *)packet; 167 return (TRUE);
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} 168}
163 169
164extern int ping_main(int argc, char **argv) 170extern int ping_main(int argc, char **argv)
165{ 171{
166 argc--; 172 argc--;
167 argv++; 173 argv++;
168 if (argc < 1) usage(ping_usage); 174 if (argc < 1)
169 ping(*argv); 175 usage(ping_usage);
170 exit(TRUE); 176 ping(*argv);
177 exit(TRUE);
171} 178}
172 179
173#else 180#else
174/* full(er) version */ 181/* full(er) version */
175static const char* ping_usage = "ping [OPTION]... host\n\n" 182static const char *ping_usage = "ping [OPTION]... host\n\n"
176"Send ICMP ECHO_REQUEST packets to network hosts.\n\n" 183 "Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
177"Options:\n" 184 "Options:\n"
178"\t-q\t\tQuiet mode, only displays output at start" 185 "\t-q\t\tQuiet mode, only displays output at start"
179"\t\t\tand when finished.\n" 186
180"\t-c COUNT\tSend only COUNT pings.\n"; 187 "\t\t\tand when finished.\n" "\t-c COUNT\tSend only COUNT pings.\n";
181 188
182static char *hostname = NULL; 189static char *hostname = NULL;
183static struct sockaddr_in pingaddr; 190static struct sockaddr_in pingaddr;
@@ -196,224 +203,247 @@ static void ping(char *);
196 203
197/**************************************************************************/ 204/**************************************************************************/
198 205
199static void pingstats(int ign) { 206static void pingstats(int ign)
200 signal(SIGINT, SIG_IGN); 207{
201 208 signal(SIGINT, SIG_IGN);
202 printf("\n--- %s ping statistics ---\n", hostname); 209
203 printf("%ld packets transmitted, ", ntransmitted); 210 printf("\n--- %s ping statistics ---\n", hostname);
204 printf("%ld packets received, ", nreceived); 211 printf("%ld packets transmitted, ", ntransmitted);
205 if (nrepeats) 212 printf("%ld packets received, ", nreceived);
206 printf("%ld duplicates, ", nrepeats); 213 if (nrepeats)
207 if (ntransmitted) 214 printf("%ld duplicates, ", nrepeats);
208 printf("%ld%% packet loss\n", 215 if (ntransmitted)
209 (ntransmitted - nreceived)*100/ntransmitted); 216 printf("%ld%% packet loss\n",
210 if (nreceived) 217 (ntransmitted - nreceived) * 100 / ntransmitted);
211 printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n", 218 if (nreceived)
212 tmin/10, tmin%10, 219 printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n",
213 (tsum/(nreceived+nrepeats))/10, 220 tmin / 10, tmin % 10,
214 (tsum/(nreceived+nrepeats))%10, 221 (tsum / (nreceived + nrepeats)) / 10,
215 tmax/10, tmax%10); 222 (tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10);
216 exit(0); 223 exit(0);
217} 224}
218 225
219static void sendping(int ign) 226static void sendping(int ign)
220{ 227{
221 struct icmp *pkt; 228 struct icmp *pkt;
222 int i; 229 int i;
223 char packet[DEFDATALEN + 8]; 230 char packet[DEFDATALEN + 8];
224 231
225 pkt = (struct icmp *)packet; 232 pkt = (struct icmp *) packet;
226 233
227 pkt->icmp_type = ICMP_ECHO; 234 pkt->icmp_type = ICMP_ECHO;
228 pkt->icmp_code = 0; 235 pkt->icmp_code = 0;
229 pkt->icmp_cksum = 0; 236 pkt->icmp_cksum = 0;
230 pkt->icmp_seq = ntransmitted++; 237 pkt->icmp_seq = ntransmitted++;
231 pkt->icmp_id = myid; 238 pkt->icmp_id = myid;
232 CLR(pkt->icmp_seq % MAX_DUP_CHK); 239 CLR(pkt->icmp_seq % MAX_DUP_CHK);
233 240
234 gettimeofday((struct timeval *)&packet[8], NULL); 241 gettimeofday((struct timeval *) &packet[8], NULL);
235 pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet)); 242 pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
236 243
237 i = sendto(pingsock, packet, sizeof(packet), 0, 244 i = sendto(pingsock, packet, sizeof(packet), 0,
238 (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in)); 245 (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
239 246
240 if (i < 0 || i != sizeof(packet)) { 247 if (i < 0 || i != sizeof(packet)) {
241 if (i < 0) perror("ping"); 248 if (i < 0)
242 fprintf(stderr, "ping wrote %d chars; %d expected\n", i, sizeof(packet)); 249 perror("ping");
243 exit(1); 250 fprintf(stderr, "ping wrote %d chars; %d expected\n", i,
244 } 251 sizeof(packet));
245 252 exit(1);
246 signal(SIGALRM, sendping); 253 }
247 if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ 254
248 alarm(PINGINTERVAL); 255 signal(SIGALRM, sendping);
249 } else { /* done, wait for the last ping to come back */ 256 if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */
250 /* todo, don't necessarily need to wait so long... */ 257 alarm(PINGINTERVAL);
251 signal(SIGALRM, pingstats); 258 } else { /* done, wait for the last ping to come back */
252 alarm(MAXWAIT); 259 /* todo, don't necessarily need to wait so long... */
253 } 260 signal(SIGALRM, pingstats);
261 alarm(MAXWAIT);
262 }
254} 263}
255 264
256static void unpack(char *buf, int sz, struct sockaddr_in *from) 265static void unpack(char *buf, int sz, struct sockaddr_in *from)
257{ 266{
258 struct icmp *icmppkt; 267 struct icmp *icmppkt;
259 struct iphdr *iphdr; 268 struct iphdr *iphdr;
260 struct timeval tv, *tp; 269 struct timeval tv, *tp;
261 int hlen, dupflag; 270 int hlen, dupflag;
262 unsigned long triptime; 271 unsigned long triptime;
263 272
264 gettimeofday(&tv, NULL); 273 gettimeofday(&tv, NULL);
265 274
266 /* check IP header */ 275 /* check IP header */
267 iphdr = (struct iphdr *)buf; 276 iphdr = (struct iphdr *) buf;
268 hlen = iphdr->ihl << 2; 277 hlen = iphdr->ihl << 2;
269 /* discard if too short */ 278 /* discard if too short */
270 if (sz < (DEFDATALEN + ICMP_MINLEN)) return; 279 if (sz < (DEFDATALEN + ICMP_MINLEN))
271 280 return;
272 sz -= hlen; 281
273 icmppkt = (struct icmp *)(buf + hlen); 282 sz -= hlen;
274 283 icmppkt = (struct icmp *) (buf + hlen);
275 if (icmppkt->icmp_type == ICMP_ECHOREPLY) { 284
276 if (icmppkt->icmp_id != myid) return; /* not our ping */ 285 if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
277 ++nreceived; 286 if (icmppkt->icmp_id != myid)
278 tp = (struct timeval *)icmppkt->icmp_data; 287 return; /* not our ping */
279 288 ++nreceived;
280 if ((tv.tv_usec -= tp->tv_usec) < 0) { 289 tp = (struct timeval *) icmppkt->icmp_data;
281 --tv.tv_sec; 290
282 tv.tv_usec += 1000000; 291 if ((tv.tv_usec -= tp->tv_usec) < 0) {
283 } 292 --tv.tv_sec;
284 tv.tv_sec -= tp->tv_sec; 293 tv.tv_usec += 1000000;
285 294 }
286 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); 295 tv.tv_sec -= tp->tv_sec;
287 tsum += triptime; 296
288 if (triptime < tmin) tmin = triptime; 297 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
289 if (triptime > tmax) tmax = triptime; 298 tsum += triptime;
290 299 if (triptime < tmin)
291 if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) { 300 tmin = triptime;
292 ++nrepeats; 301 if (triptime > tmax)
293 --nreceived; 302 tmax = triptime;
294 dupflag = 1; 303
304 if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) {
305 ++nrepeats;
306 --nreceived;
307 dupflag = 1;
308 } else {
309 SET(icmppkt->icmp_seq % MAX_DUP_CHK);
310 dupflag = 0;
311 }
312
313 if (options & O_QUIET)
314 return;
315
316 printf("%d bytes from %s: icmp_seq=%u", sz,
317 inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
318 icmppkt->icmp_seq);
319 printf(" ttl=%d", iphdr->ttl);
320 printf(" time=%lu.%lu ms", triptime / 10, triptime % 10);
321 if (dupflag)
322 printf(" (DUP!)");
323 printf("\n");
295 } else { 324 } else {
296 SET(icmppkt->icmp_seq % MAX_DUP_CHK); 325 fprintf(stderr,
297 dupflag = 0; 326 "Warning: unknown ICMP packet received (not echo-reply)\n");
298 } 327 }
299
300 if (options & O_QUIET) return;
301
302 printf("%d bytes from %s: icmp_seq=%u", sz,
303 inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
304 icmppkt->icmp_seq);
305 printf(" ttl=%d", iphdr->ttl);
306 printf(" time=%lu.%lu ms", triptime/10, triptime%10);
307 if (dupflag) printf(" (DUP!)");
308 printf("\n");
309 } else {
310 fprintf(stderr, "Warning: unknown ICMP packet received (not echo-reply)\n");
311 }
312} 328}
313 329
314static void ping(char *host) 330static void ping(char *host)
315{ 331{
316 struct protoent *proto; 332 struct protoent *proto;
317 struct hostent *h; 333 struct hostent *h;
318 char buf[MAXHOSTNAMELEN]; 334 char buf[MAXHOSTNAMELEN];
319 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; 335 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
320 int sockopt; 336 int sockopt;
321 337
322 proto = getprotobyname("icmp"); 338 proto = getprotobyname("icmp");
323 /* if getprotobyname failed, just silently force 339 /* if getprotobyname failed, just silently force
324 * proto->p_proto to have the correct value for "icmp" */ 340 * proto->p_proto to have the correct value for "icmp" */
325 if ((pingsock = socket(AF_INET, SOCK_RAW, 341 if ((pingsock = socket(AF_INET, SOCK_RAW,
326 (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ 342 (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */
327 if (errno == EPERM) { 343 if (errno == EPERM) {
328 fprintf(stderr, "ping: permission denied. (are you root?)\n"); 344 fprintf(stderr, "ping: permission denied. (are you root?)\n");
329 } else { 345 } else {
330 perror("ping"); 346 perror("ping");
347 }
348 exit(1);
331 } 349 }
332 exit(1); 350
333 } 351 /* drop root privs if running setuid */
334 352 setuid(getuid());
335 /* drop root privs if running setuid */ 353
336 setuid(getuid()); 354 memset(&pingaddr, 0, sizeof(struct sockaddr_in));
337 355
338 memset(&pingaddr, 0, sizeof(struct sockaddr_in)); 356 pingaddr.sin_family = AF_INET;
339 pingaddr.sin_family = AF_INET; 357 if (!(h = gethostbyname(host))) {
340 if (!(h = gethostbyname(host))) { 358 fprintf(stderr, "ping: unknown host %s\n", host);
341 fprintf(stderr, "ping: unknown host %s\n", host); 359 exit(1);
342 exit(1); 360 }
343 } 361
344 362 if (h->h_addrtype != AF_INET) {
345 if (h->h_addrtype != AF_INET) { 363 fprintf(stderr,
346 fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n"); 364 "ping: unknown address type; only AF_INET is currently supported.\n");
347 exit(1); 365 exit(1);
348 }
349
350 pingaddr.sin_family = AF_INET; /* h->h_addrtype */
351 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
352 strncpy(buf, h->h_name, sizeof(buf)-1);
353 hostname = buf;
354
355 /* enable broadcast pings */
356 sockopt = 1;
357 setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt, sizeof(sockopt));
358
359 /* set recv buf for broadcast pings */
360 sockopt = 48 * 1024;
361 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt));
362
363 printf("PING %s (%s): %d data bytes\n",
364 hostname, inet_ntoa(*(struct in_addr *)&pingaddr.sin_addr.s_addr),
365 DEFDATALEN);
366
367 signal(SIGINT, pingstats);
368
369 /* start the ping's going ... */
370 sendping(0);
371
372 /* listen for replies */
373 while (1) {
374 struct sockaddr_in from;
375 size_t fromlen = sizeof(from);
376 int c;
377
378 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
379 (struct sockaddr *)&from, &fromlen)) < 0) {
380 if (errno == EINTR) continue;
381 perror("ping");
382 continue;
383 } 366 }
384 unpack(packet, c, &from); 367
385 if (pingcount > 0 && nreceived >= pingcount) break; 368 pingaddr.sin_family = AF_INET; /* h->h_addrtype */
386 } 369 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
387 pingstats(0); 370 strncpy(buf, h->h_name, sizeof(buf) - 1);
371 hostname = buf;
372
373 /* enable broadcast pings */
374 sockopt = 1;
375 setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *) &sockopt,
376 sizeof(sockopt));
377
378 /* set recv buf for broadcast pings */
379 sockopt = 48 * 1024;
380 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt,
381 sizeof(sockopt));
382
383 printf("PING %s (%s): %d data bytes\n",
384 hostname,
385 inet_ntoa(*(struct in_addr *) &pingaddr.sin_addr.s_addr),
386 DEFDATALEN);
387
388 signal(SIGINT, pingstats);
389
390 /* start the ping's going ... */
391 sendping(0);
392
393 /* listen for replies */
394 while (1) {
395 struct sockaddr_in from;
396 size_t fromlen = sizeof(from);
397 int c;
398
399 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
400 (struct sockaddr *) &from, &fromlen)) < 0) {
401 if (errno == EINTR)
402 continue;
403 perror("ping");
404 continue;
405 }
406 unpack(packet, c, &from);
407 if (pingcount > 0 && nreceived >= pingcount)
408 break;
409 }
410 pingstats(0);
388} 411}
389 412
390extern int ping_main(int argc, char **argv) 413extern int ping_main(int argc, char **argv)
391{ 414{
392 char *thisarg; 415 char *thisarg;
393 416
394 argc--; 417 argc--;
395 argv++; 418 argv++;
396 options = 0; 419 options = 0;
397 /* Parse any options */ 420 /* Parse any options */
398 while (argc > 1) { 421 while (argc > 1) {
399 if (**argv != '-') usage(ping_usage); 422 if (**argv != '-')
400 thisarg = *argv; thisarg++; 423 usage(ping_usage);
401 switch (*thisarg) { 424 thisarg = *argv;
402 case 'q': options |= O_QUIET; break; 425 thisarg++;
403 case 'c': 426 switch (*thisarg) {
404 argc--; argv++; 427 case 'q':
405 pingcount = atoi(*argv); 428 options |= O_QUIET;
406 break; 429 break;
407 default: 430 case 'c':
408 usage(ping_usage); 431 argc--;
409 } 432 argv++;
410 argc--; argv++; 433 pingcount = atoi(*argv);
411 } 434 break;
412 if (argc < 1) usage(ping_usage); 435 default:
413 436 usage(ping_usage);
414 myid = getpid() & 0xFFFF; 437 }
415 ping(*argv); 438 argc--;
416 exit(TRUE); 439 argv++;
440 }
441 if (argc < 1)
442 usage(ping_usage);
443
444 myid = getpid() & 0xFFFF;
445 ping(*argv);
446 exit(TRUE);
417} 447}
418#endif 448#endif
419 449