Blame


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