10 typedef struct Pingcache Pingcache;
19 uchar vihl; /* Version and header length */
20 uchar tos; /* Type of service */
21 uchar length[2]; /* packet length */
22 uchar id[2]; /* Identification */
23 uchar frag[2]; /* Fragment information */
24 uchar ttl; /* Time to live */
25 uchar proto; /* Protocol */
26 uchar ipcksum[2]; /* Header checksum */
27 uchar src[4]; /* Ip source */
28 uchar dst[4]; /* Ip destination */
37 enum { /* Packet Types */
57 static Pingcache *Cache;
60 * We ignore the first result as that is probably bigger
61 * than expected due to IP sorting out the routing to the host
64 ping(char *host, int timeout)
74 for(c = Cache; c; c = c->next)
75 if(strcmp(c->host, host) == 0 && now < c->expire){
76 if(Debug && strstr(Debug, "dfs") != nil)
77 print("\t\tping host=%s timeout=%d - cache hit\n",
85 if((fd = dial(netmkaddr(host, "icmp", "1"), 0, 0, 0)) == -1)
88 for(seq = 0; seq < Npings; seq++){
90 for(i = Payload; i < sizeof buf; i++)
92 ip->type = EchoRequest;
97 if(write(fd, ip, sizeof buf) != sizeof buf ||
98 read(fd, ip, sizeof buf) != sizeof buf)
101 if(ip->type != EchoReply || ip->code != 0 ||
102 ip->seq[0] != seq || ip->seq[1] != seq)
104 for(i = Payload; i < sizeof buf; i++)
105 if((uchar)buf[i] != (uchar)(i + seq))
107 rtt = (rtt + nsec() - then) / 2;
113 if(Debug && strstr(Debug, "dfs") != nil)
114 print("\t\tping host=%s timeout=%d rtt=%d - failed\n",
118 * failures get cached too
120 for(c = Cache; c; c = c->next)
121 if(strcmp(c->host, host) == 0)
124 c = emalloc9p(sizeof(Pingcache));
125 c->host = estrdup9p(host);
130 c->expire = now+Cachetime;