2 * By Patrick Reynolds <reynolds@cs.duke.edu>
3 * Distributed under GPL.
9 * pong 1.2.3.0 # as root!
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
19 #include <netinet/ip_icmp.h>
20 #include <sys/socket.h>
26 #undef I_CARE_ABOUT_BAD_RETURN_PACKETS
33 struct sockaddr_in dest;
37 int in_cksum(u_short *addr, int len);
39 void foo(int i) { foo_set = 1; }
41 int main(int argc, char **argv) {
43 if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
44 perror("pong: socket");
48 fprintf(stderr, "Usage:\n %s aaa.bbb.ccc.0\n\n", argv[0]);
51 bzero(&dest, sizeof(dest));
52 dest.sin_family = AF_INET;
53 inet_aton(argv[1], &dest.sin_addr);
61 unsigned char buf[sizeof(struct icmphdr)];
62 struct icmphdr *p = (struct icmphdr *)buf;
65 fprintf(stderr, "Sending packets");
70 p->un.echo.sequence = 0;
73 p->checksum = in_cksum((u_short *)p, datalen + 8);
75 dest.sin_addr.s_addr &= 0xffffff;
76 for (i=1; i<=254; i++) {
79 dest.sin_addr.s_addr &= 0xffffff;
80 dest.sin_addr.s_addr |= (i<<24);
81 ret = sendto(sock, (char *)buf, 8 + datalen, 0,
82 (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
83 if (ret != 8 + datalen) {
85 perror("pong: sendto");
86 printf("pong: wrote %d chars, ret=%d\n", 8+datalen, ret);
95 fprintf(stderr, "Gathering responses");
96 bzero(vec, nhosts*sizeof(int));
101 struct sockaddr_in from;
103 struct timeval tv = { 1, 0 };
104 socklen_t fromlen = sizeof(from);
107 if (select(sock+1, &rfds, NULL, NULL, &tv) <= 0) continue;
108 ret = recvfrom(sock, (char *)incoming, 128, 0, (struct sockaddr *)&from,
110 #ifdef I_CARE_ABOUT_BAD_RETURN_PACKETS
111 if (ret != datalen + 16 && (ret >= 0 || errno != EINTR)) {
113 perror("pong: recvfrom");
115 vec[from.sin_addr.s_addr >> 24] = PONG_BROKEN;
116 printf("pong: read %d chars, ret=%d, host=%d\n", 16+datalen, ret,
117 from.sin_addr.s_addr>>24);
124 vec[from.sin_addr.s_addr >> 24] = PONG_OKAY;
130 int in_cksum(u_short *addr, int len) {
131 register int nleft = len;
132 register u_short *w = addr;
133 register int sum = 0;
141 *(u_char *)(&answer) = *(u_char *)w ;
144 sum = (sum >> 16) + (sum & 0xffff);
152 for (i=0; i<=255; i++)
154 unsigned int ip = ntohl(dest.sin_addr.s_addr);
156 printf("%d.%d.%d.%d: %s\n", ip>>24, (ip>>16)&0xff, (ip>>8)&0xff, i,
157 vec[i]==PONG_OKAY ? "found" : "broken");
159 printf("\nTotal hosts: %d\n", count);