tping.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tping.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 } |