ping.c (1890B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 5 6 typedef struct Icmp Icmp; 7 struct Icmp 8 { 9 uchar vihl; /* Version and header length */ 10 uchar tos; /* Type of service */ 11 uchar length[2]; /* packet length */ 12 uchar id[2]; /* Identification */ 13 uchar frag[2]; /* Fragment information */ 14 uchar ttl; /* Time to live */ 15 uchar proto; /* Protocol */ 16 uchar ipcksum[2]; /* Header checksum */ 17 uchar src[4]; /* Ip source */ 18 uchar dst[4]; /* Ip destination */ 19 uchar type; 20 uchar code; 21 uchar cksum[2]; 22 uchar icmpid[2]; 23 uchar seq[2]; 24 uchar data[1]; 25 }; 26 27 enum 28 { /* Packet Types */ 29 EchoReply = 0, 30 Unreachable = 3, 31 SrcQuench = 4, 32 EchoRequest = 8, 33 TimeExceed = 11, 34 Timestamp = 13, 35 TimestampReply = 14, 36 InfoRequest = 15, 37 InfoReply = 16, 38 39 ICMP_IPSIZE = 20, 40 ICMP_HDRSIZE = 8 41 }; 42 43 static void 44 catch(void *a, char *msg) 45 { 46 USED(a); 47 if(strstr(msg, "alarm")) 48 noted(NCONT); 49 else 50 noted(NDFLT); 51 } 52 53 #define MSG "dhcp probe" 54 55 /* 56 * make sure noone is using the address 57 */ 58 int 59 icmpecho(uchar *a) 60 { 61 int fd; 62 char buf[512]; 63 Icmp *ip; 64 int i, n, len; 65 ushort sseq, x; 66 int rv; 67 68 return 0; 69 rv = 0; 70 71 sprint(buf, "%I", a); 72 fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0); 73 if(fd < 0){ 74 return 0; 75 } 76 77 sseq = getpid()*time(0); 78 79 ip = (Icmp*)buf; 80 notify(catch); 81 for(i = 0; i < 3; i++){ 82 ip->type = EchoRequest; 83 ip->code = 0; 84 strcpy((char*)ip->data, MSG); 85 ip->seq[0] = sseq; 86 ip->seq[1] = sseq>>8; 87 len = ICMP_IPSIZE+ICMP_HDRSIZE+sizeof(MSG); 88 89 /* send a request */ 90 if(write(fd, buf, len) < len) 91 break; 92 93 /* wait 1/10th second for a reply and try again */ 94 alarm(100); 95 n = read(fd, buf, sizeof(buf)); 96 alarm(0); 97 if(n <= 0) 98 continue; 99 100 /* an answer to our echo request? */ 101 x = (ip->seq[1]<<8)|ip->seq[0]; 102 if(n >= len) 103 if(ip->type == EchoReply) 104 if(x == sseq) 105 if(strcmp((char*)ip->data, MSG) == 0){ 106 rv = 1; 107 break; 108 } 109 } 110 close(fd); 111 return rv; 112 }