xref: /plan9/sys/src/cmd/ip/dhcpd/ping.c (revision f9e1cf08d3be51592e03e639fc848a68dc31a55e)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "../icmp.h"
5 
6 static void
7 catch(void *a, char *msg)
8 {
9 	USED(a);
10 	if(strstr(msg, "alarm"))
11 		noted(NCONT);
12 	else
13 		noted(NDFLT);
14 }
15 
16 #define MSG "dhcp probe"
17 
18 /*
19  *  make sure noone is using the address
20  *  TODO: ipv6 ping
21  */
22 int
23 icmpecho(uchar *a)
24 {
25 	int fd;
26 	char buf[512];
27 	Icmp *ip;
28 	int i, n, len;
29 	ushort sseq, x;
30 	int rv;
31 
32 	rv = 0;
33 	if (!isv4(a))
34 		return 0;
35 	sprint(buf, "%I", a);
36 	fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
37 	if(fd < 0){
38 		return 0;
39 	}
40 
41 	sseq = getpid()*time(0);
42 
43 	ip = (Icmp*)buf;
44 	notify(catch);
45 	for(i = 0; i < 3; i++){
46 		ip->type = EchoRequest;
47 		ip->code = 0;
48 		strcpy((char*)ip->data, MSG);
49 		ip->seq[0] = sseq;
50 		ip->seq[1] = sseq>>8;
51 		len = IPV4HDR_LEN+ICMP_HDRSIZE+sizeof(MSG);
52 
53 		/* send a request */
54 		if(write(fd, buf, len) < len)
55 			break;
56 
57 		/* wait 1/10th second for a reply and try again */
58 		alarm(100);
59 		n = read(fd, buf, sizeof(buf));
60 		alarm(0);
61 		if(n <= 0)
62 			continue;
63 
64 		/* an answer to our echo request? */
65 		x = (ip->seq[1]<<8)|ip->seq[0];
66 		if(n >= len)
67 		if(ip->type == EchoReply)
68 		if(x == sseq)
69 		if(strcmp((char*)ip->data, MSG) == 0){
70 			rv = 1;
71 			break;
72 		}
73 	}
74 	close(fd);
75 	return rv;
76 }
77