ticmp.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
ticmp.c (2963B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <ip.h> | |
4 #include "dat.h" | |
5 #include "protos.h" | |
6 | |
7 typedef struct Hdr Hdr; | |
8 struct Hdr | |
9 { uchar type; | |
10 uchar code; | |
11 uchar cksum[2]; /* Checksum */ | |
12 uchar data[1]; | |
13 }; | |
14 | |
15 enum | |
16 { | |
17 ICMPLEN= 4 | |
18 }; | |
19 | |
20 enum | |
21 { | |
22 Ot, /* type */ | |
23 Op, /* next protocol */ | |
24 }; | |
25 | |
26 static Field p_fields[] = | |
27 { | |
28 {"t", Fnum, Ot, "type", } , | |
29 {0} | |
30 }; | |
31 | |
32 enum | |
33 { | |
34 EchoRep= 0, | |
35 Unreachable= 3, | |
36 SrcQuench= 4, | |
37 Redirect= 5, | |
38 EchoReq= 8, | |
39 TimeExceed= 11, | |
40 ParamProb= 12, | |
41 TSreq= 13, | |
42 TSrep= 14, | |
43 InfoReq= 15, | |
44 InfoRep= 16 | |
45 }; | |
46 | |
47 static Mux p_mux[] = | |
48 { | |
49 {"ip", Unreachable, }, | |
50 {"ip", SrcQuench, }, | |
51 {"ip", Redirect, }, | |
52 {"ip", TimeExceed, }, | |
53 {"ip", ParamProb, }, | |
54 {0} | |
55 }; | |
56 | |
57 char *icmpmsg[256] = | |
58 { | |
59 [EchoRep] "EchoRep", | |
60 [Unreachable] "Unreachable", | |
61 [SrcQuench] "SrcQuench", | |
62 [Redirect] "Redirect", | |
63 [EchoReq] "EchoReq", | |
64 [TimeExceed] "TimeExceed", | |
65 [ParamProb] "ParamProb", | |
66 [TSreq] "TSreq", | |
67 [TSrep] "TSrep", | |
68 [InfoReq] "InfoReq", | |
69 [InfoRep] "InfoRep" | |
70 }; | |
71 | |
72 static void | |
73 p_compile(Filter *f) | |
74 { | |
75 if(f->op == '='){ | |
76 compile_cmp(udp.name, f, p_fields); | |
77 return; | |
78 } | |
79 if(strcmp(f->s, "ip") == 0){ | |
80 f->pr = p_mux->pr; | |
81 f->subop = Op; | |
82 return; | |
83 } | |
84 sysfatal("unknown icmp field or protocol: %s", f->s); | |
85 } | |
86 | |
87 static int | |
88 p_filter(Filter *f, Msg *m) | |
89 { | |
90 Hdr *h; | |
91 | |
92 if(m->pe - m->ps < ICMPLEN) | |
93 return 0; | |
94 | |
95 h = (Hdr*)m->ps; | |
96 m->ps += ICMPLEN; | |
97 | |
98 switch(f->subop){ | |
99 case Ot: | |
100 if(h->type == f->ulv) | |
101 return 1; | |
102 break; | |
103 case Op: | |
104 switch(h->type){ | |
105 case Unreachable: | |
106 case TimeExceed: | |
107 case SrcQuench: | |
108 case Redirect: | |
109 case ParamProb: | |
110 m->ps += 4; | |
111 return 1; | |
112 } | |
113 } | |
114 return 0; | |
115 } | |
116 | |
117 static int | |
118 p_seprint(Msg *m) | |
119 { | |
120 Hdr *h; | |
121 char *tn; | |
122 char *p = m->p; | |
123 char *e = m->e; | |
124 ushort cksum2, cksum; | |
125 | |
126 h = (Hdr*)m->ps; | |
127 m->ps += ICMPLEN; | |
128 m->pr = &dump; | |
129 | |
130 if(m->pe - m->ps < ICMPLEN) | |
131 return -1; | |
132 | |
133 tn = icmpmsg[h->type]; | |
134 if(tn == nil) | |
135 p = seprint(p, e, "t=%ud c=%d ck=%4.4ux", h->type, | |
136 h->code, (ushort)NetS(h->cksum)); | |
137 else | |
138 p = seprint(p, e, "t=%s c=%d ck=%4.4ux", tn, | |
139 h->code, (ushort)NetS(h->cksum)); | |
140 if(Cflag){ | |
141 cksum = NetS(h->cksum); | |
142 h->cksum[0] = 0; | |
143 h->cksum[1] = 0; | |
144 cksum2 = ~ptclbsum((uchar*)h, m->pe - m->ps + ICMPLEN) &… | |
145 if(cksum != cksum2) | |
146 p = seprint(p,e, " !ck=%4.4ux", cksum2); | |
147 } | |
148 switch(h->type){ | |
149 case EchoRep: | |
150 case EchoReq: | |
151 m->ps += 4; | |
152 p = seprint(p, e, " id=%ux seq=%ux", | |
153 NetS(h->data), NetS(h->data+2)); | |
154 break; | |
155 case TSreq: | |
156 case TSrep: | |
157 m->ps += 12; | |
158 p = seprint(p, e, " orig=%ud rcv=%ux xmt=%ux", | |
159 NetL(h->data), NetL(h->data+4), | |
160 NetL(h->data+8)); | |
161 m->pr = nil; | |
162 break; | |
163 case InfoReq: | |
164 case InfoRep: | |
165 break; | |
166 case Unreachable: | |
167 case TimeExceed: | |
168 case SrcQuench: | |
169 m->ps += 4; | |
170 m->pr = &ip; | |
171 break; | |
172 case Redirect: | |
173 m->ps += 4; | |
174 m->pr = &ip; | |
175 p = seprint(p, e, "gw=%V", h->data); | |
176 break; | |
177 case ParamProb: | |
178 m->ps += 4; | |
179 m->pr = &ip; | |
180 p = seprint(p, e, "ptr=%2.2ux", h->data[0]); | |
181 break; | |
182 } | |
183 m->p = p; | |
184 return 0; | |
185 } | |
186 | |
187 Proto icmp = | |
188 { | |
189 "icmp", | |
190 p_compile, | |
191 p_filter, | |
192 p_seprint, | |
193 p_mux, | |
194 "%lud", | |
195 p_fields, | |
196 defaultframer | |
197 }; |