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, 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