Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
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 };
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,
39 ICMP_IPSIZE = 20,
40 ICMP_HDRSIZE = 8
41 };
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 }
53 #define MSG "dhcp probe"
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;
68 return 0;
69 rv = 0;
71 sprint(buf, "%I", a);
72 fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
73 if(fd < 0){
74 return 0;
75 }
77 sseq = getpid()*time(0);
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);
89 /* send a request */
90 if(write(fd, buf, len) < len)
91 break;
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;
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;
110 close(fd);
111 return rv;