1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "../icmp.h"
5
6 static void
catch(void * a,char * msg)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
icmpecho(uchar * a)23 icmpecho(uchar *a)
24 {
25 int fd, i, n, len, rv;
26 ushort sseq, x;
27 char buf[512];
28 Icmphdr *ip;
29
30 rv = 0;
31 if (!isv4(a))
32 return 0;
33 sprint(buf, "%I", a);
34 fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
35 if(fd < 0){
36 return 0;
37 }
38
39 sseq = getpid()*time(0);
40
41 ip = (Icmphdr *)(buf + IPV4HDR_LEN);
42 notify(catch);
43 for(i = 0; i < 3; i++){
44 ip->type = EchoRequest;
45 ip->code = 0;
46 strcpy((char*)ip->data, MSG);
47 ip->seq[0] = sseq;
48 ip->seq[1] = sseq>>8;
49 len = IPV4HDR_LEN + ICMP_HDRSIZE + sizeof(MSG);
50
51 /* send a request */
52 if(write(fd, buf, len) < len)
53 break;
54
55 /* wait 1/10th second for a reply and try again */
56 alarm(100);
57 n = read(fd, buf, sizeof(buf));
58 alarm(0);
59 if(n <= 0)
60 continue;
61
62 /* an answer to our echo request? */
63 x = (ip->seq[1]<<8) | ip->seq[0];
64 if(n >= len && ip->type == EchoReply && x == sseq &&
65 strcmp((char*)ip->data, MSG) == 0){
66 rv = 1;
67 break;
68 }
69 }
70 close(fd);
71 return rv;
72 }
73