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