tip6.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tip6.c (5377B) | |
--- | |
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 { | |
10 uchar vcf[4]; /* Version and heade… | |
11 uchar length[2]; /* packet length */ | |
12 uchar proto; /* Protocol */ | |
13 uchar ttl; /* Time to live */ | |
14 uchar src[IPaddrlen]; /* IP source */ | |
15 uchar dst[IPaddrlen]; /* IP destination */ | |
16 }; | |
17 | |
18 enum | |
19 { | |
20 IP6HDR = 40, /* sizeof(Iphdr) */ | |
21 IP_VER = 0x60, /* Using IP version… | |
22 HBH_HDR = 0, | |
23 ROUT_HDR = 43, | |
24 FRAG_HDR = 44, | |
25 FRAG_HSZ = 8, /* in bytes */ | |
26 DEST_HDR = 60 | |
27 }; | |
28 | |
29 static Mux p_mux[] = | |
30 { | |
31 { "igmp", 2, }, | |
32 { "ggp", 3, }, | |
33 { "ip", 4, }, | |
34 { "st", 5, }, | |
35 { "tcp", 6, }, | |
36 { "ucl", 7, }, | |
37 { "egp", 8, }, | |
38 { "igp", 9, }, | |
39 { "bbn-rcc-mon", 10, }, | |
40 { "nvp-ii", 11, }, | |
41 { "pup", 12, }, | |
42 { "argus", 13, }, | |
43 { "emcon", 14, }, | |
44 { "xnet", 15, }, | |
45 { "chaos", 16, }, | |
46 { "udp", 17, }, | |
47 { "mux", 18, }, | |
48 { "dcn-meas", 19, }, | |
49 { "hmp", 20, }, | |
50 { "prm", 21, }, | |
51 { "xns-idp", 22, }, | |
52 { "trunk-1", 23, }, | |
53 { "trunk-2", 24, }, | |
54 { "leaf-1", 25, }, | |
55 { "leaf-2", 26, }, | |
56 { "rdp", 27, }, | |
57 { "irtp", 28, }, | |
58 { "iso-tp4", 29, }, | |
59 { "netblt", 30, }, | |
60 { "mfe-nsp", 31, }, | |
61 { "merit-inp", 32, }, | |
62 { "sep", 33, }, | |
63 { "3pc", 34, }, | |
64 { "idpr", 35, }, | |
65 { "xtp", 36, }, | |
66 { "ddp", 37, }, | |
67 { "idpr-cmtp", 38, }, | |
68 { "tp++", 39, }, | |
69 { "il", 40, }, | |
70 { "sip", 41, }, | |
71 { "sdrp", 42, }, | |
72 { "idrp", 45, }, | |
73 { "rsvp", 46, }, | |
74 { "gre", 47, }, | |
75 { "mhrp", 48, }, | |
76 { "bna", 49, }, | |
77 { "sipp-esp", 50, }, | |
78 { "sipp-ah", 51, }, | |
79 { "i-nlsp", 52, }, | |
80 { "swipe", 53, }, | |
81 { "nhrp", 54, }, | |
82 { "icmp6", 58, }, | |
83 { "any", 61, }, | |
84 { "cftp", 62, }, | |
85 { "any", 63, }, | |
86 { "sat-expak", 64, }, | |
87 { "kryptolan", 65, }, | |
88 { "rvd", 66, }, | |
89 { "ippc", 67, }, | |
90 { "any", 68, }, | |
91 { "sat-mon", 69, }, | |
92 { "visa", 70, }, | |
93 { "ipcv", 71, }, | |
94 { "cpnx", 72, }, | |
95 { "cphb", 73, }, | |
96 { "wsn", 74, }, | |
97 { "pvp", 75, }, | |
98 { "br-sat-mon", 76, }, | |
99 { "sun-nd", 77, }, | |
100 { "wb-mon", 78, }, | |
101 { "wb-expak", 79, }, | |
102 { "iso-ip", 80, }, | |
103 { "vmtp", 81, }, | |
104 { "secure-vmtp", 82, }, | |
105 { "vines", 83, }, | |
106 { "ttp", 84, }, | |
107 { "nsfnet-igp", 85, }, | |
108 { "dgp", 86, }, | |
109 { "tcf", 87, }, | |
110 { "igrp", 88, }, | |
111 { "ospf", 89, }, | |
112 { "sprite-rpc", 90, }, | |
113 { "larp", 91, }, | |
114 { "mtp", 92, }, | |
115 { "ax.25", 93, }, | |
116 { "ipip", 94, }, | |
117 { "micp", 95, }, | |
118 { "scc-sp", 96, }, | |
119 { "etherip", 97, }, | |
120 { "encap", 98, }, | |
121 { "any", 99, }, | |
122 { "gmtp", 100, }, | |
123 { "rudp", 254, }, | |
124 { 0 } | |
125 }; | |
126 | |
127 enum | |
128 { | |
129 Os, /* source */ | |
130 Od, /* destination */ | |
131 Osd, /* source or destination */ | |
132 Ot, /* type */ | |
133 }; | |
134 | |
135 static Field p_fields[] = | |
136 { | |
137 {"s", Fv6ip, Os, "source address", }… | |
138 {"d", Fv6ip, Od, "destination address", … | |
139 {"a", Fv6ip, Osd, "source|destination addre… | |
140 {"t", Fnum, Ot, "sub protocol number", … | |
141 {0} | |
142 }; | |
143 | |
144 static void | |
145 p_compile(Filter *f) | |
146 { | |
147 Mux *m; | |
148 | |
149 if(f->op == '='){ | |
150 compile_cmp(ip6.name, f, p_fields); | |
151 return; | |
152 } | |
153 for(m = p_mux; m->name != nil; m++) | |
154 if(strcmp(f->s, m->name) == 0){ | |
155 f->pr = m->pr; | |
156 f->ulv = m->val; | |
157 f->subop = Ot; | |
158 return; | |
159 } | |
160 sysfatal("unknown ip6 field or protocol: %s", f->s); | |
161 } | |
162 | |
163 static int | |
164 v6hdrlen(Hdr *h) | |
165 { | |
166 int plen, len = IP6HDR; | |
167 int pktlen = IP6HDR + NetS(h->length); | |
168 uchar nexthdr = h->proto; | |
169 uchar *pkt = (uchar*) h; | |
170 | |
171 pkt += len; | |
172 plen = len; | |
173 | |
174 while ( (nexthdr == HBH_HDR) || (nexthdr == ROUT_HDR) || | |
175 (nexthdr == FRAG_HDR) || (nexthdr == DEST_HDR) ) { | |
176 | |
177 if (nexthdr == FRAG_HDR) | |
178 len = FRAG_HSZ; | |
179 else | |
180 len = ( ((int) *(pkt+1)) + 1) * 8; | |
181 | |
182 if (plen + len > pktlen) | |
183 return -1; | |
184 | |
185 pkt += len; | |
186 nexthdr = *pkt; | |
187 plen += len; | |
188 } | |
189 return plen; | |
190 } | |
191 | |
192 static int | |
193 p_filter(Filter *f, Msg *m) | |
194 { | |
195 Hdr *h; | |
196 int hlen; | |
197 | |
198 if(m->pe - m->ps < IP6HDR) | |
199 return 0; | |
200 | |
201 h = (Hdr*)m->ps; | |
202 | |
203 if ((hlen = v6hdrlen(h)) < 0) | |
204 return 0; | |
205 else | |
206 m->ps += hlen; | |
207 switch(f->subop){ | |
208 case Os: | |
209 return !memcmp(h->src, f->a, IPaddrlen); | |
210 case Od: | |
211 return !memcmp(h->dst, f->a, IPaddrlen); | |
212 case Osd: | |
213 return !memcmp(h->src, f->a, IPaddrlen) || !memcmp(h->ds… | |
214 case Ot: | |
215 return h->proto == f->ulv; | |
216 } | |
217 return 0; | |
218 } | |
219 | |
220 static int | |
221 v6hdr_seprint(Msg *m) | |
222 { | |
223 int len = IP6HDR; | |
224 uchar *pkt = m->ps; | |
225 Hdr *h = (Hdr *) pkt; | |
226 int pktlen = IP6HDR + NetS(h->length); | |
227 uchar nexthdr = h->proto; | |
228 int plen; | |
229 | |
230 pkt += len; | |
231 plen = len; | |
232 | |
233 while ( (nexthdr == HBH_HDR) || (nexthdr == ROUT_HDR) || | |
234 (nexthdr == FRAG_HDR) || (nexthdr == DEST_HDR) ) { | |
235 | |
236 switch (nexthdr) { | |
237 case FRAG_HDR: | |
238 m->p = seprint(m->p, m->e, "\n xthdr=fr… | |
239 NetL(pkt+4), | |
240 NetS(pkt+2) & ~7, | |
241 (int) (*pkt), | |
242 (int) (*(pkt+3) & 0x1), | |
243 (int) *(pkt+1), | |
244 (int) (*(pkt+3) & 0x6) | |
245 ); | |
246 len = FRAG_HSZ; | |
247 break; | |
248 | |
249 case HBH_HDR: | |
250 case ROUT_HDR: | |
251 case DEST_HDR: | |
252 len = ( ((int) *(pkt+1)) + 1) * 8; | |
253 break; | |
254 } | |
255 | |
256 if (plen + len > pktlen) { | |
257 m->p = seprint(m->p, m->e, "bad pkt"); | |
258 m->pr = &dump; | |
259 return -1; | |
260 } | |
261 plen += len; | |
262 pkt += len; | |
263 nexthdr = *pkt; | |
264 } | |
265 | |
266 m->ps = pkt; | |
267 return 1; | |
268 | |
269 } | |
270 | |
271 static int | |
272 p_seprint(Msg *m) | |
273 { | |
274 Hdr *h; | |
275 int len; | |
276 | |
277 if(m->pe - m->ps < IP6HDR) | |
278 return -1; | |
279 h = (Hdr*)m->ps; | |
280 | |
281 demux(p_mux, h->proto, h->proto, m, &dump); | |
282 | |
283 /* truncate the message if there's extra */ | |
284 len = NetS(h->length) + IP6HDR; | |
285 if(len < m->pe - m->ps) | |
286 m->pe = m->ps + len; | |
287 | |
288 m->p = seprint(m->p, m->e, "s=%I d=%I ttl=%3d pr=%d ln=%d", | |
289 h->src, h->dst, | |
290 h->ttl, | |
291 h->proto, | |
292 NetS(h->length) | |
293 ); | |
294 | |
295 v6hdr_seprint(m); | |
296 | |
297 return 0; | |
298 } | |
299 | |
300 Proto ip6 = | |
301 { | |
302 "ip6", | |
303 p_compile, | |
304 p_filter, | |
305 p_seprint, | |
306 p_mux, | |
307 "%lud", | |
308 p_fields, | |
309 defaultframer | |
310 }; |