tospf.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tospf.c (7359B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <ip.h> | |
4 #include <libsec.h> | |
5 #include "dat.h" | |
6 #include "protos.h" | |
7 | |
8 | |
9 /* | |
10 * OSPF packets | |
11 */ | |
12 typedef struct Ospfpkt Ospfpkt; | |
13 struct Ospfpkt | |
14 { | |
15 uchar version; | |
16 uchar type; | |
17 uchar length[2]; | |
18 uchar router[4]; | |
19 uchar area[4]; | |
20 uchar sum[2]; | |
21 uchar autype[2]; | |
22 uchar auth[8]; | |
23 uchar data[1]; | |
24 }; | |
25 #define OSPF_HDRSIZE 24 | |
26 | |
27 enum | |
28 { | |
29 OSPFhello= 1, | |
30 OSPFdd= 2, | |
31 OSPFlsrequest= 3, | |
32 OSPFlsupdate= 4, | |
33 OSPFlsack= 5 | |
34 }; | |
35 | |
36 | |
37 char *ospftype[] = { | |
38 [OSPFhello] "hello", | |
39 [OSPFdd] "data definition", | |
40 [OSPFlsrequest] "link state request", | |
41 [OSPFlsupdate] "link state update", | |
42 [OSPFlsack] "link state ack" | |
43 }; | |
44 | |
45 char* | |
46 ospfpkttype(int x) | |
47 { | |
48 static char type[16]; | |
49 | |
50 if(x > 0 && x <= OSPFlsack) | |
51 return ospftype[x]; | |
52 sprint(type, "type %d", x); | |
53 return type; | |
54 } | |
55 | |
56 char* | |
57 ospfauth(Ospfpkt *ospf) | |
58 { | |
59 static char auth[100]; | |
60 | |
61 switch(ospf->type){ | |
62 case 0: | |
63 return "no authentication"; | |
64 case 1: | |
65 sprint(auth, "password(%8.8ux %8.8ux)", NetL(ospf->auth), | |
66 NetL(ospf->auth+4)); | |
67 break; | |
68 case 2: | |
69 sprint(auth, "crypto(plen %d id %d dlen %d)", NetS(ospf-… | |
70 ospf->auth[2], ospf->auth[3]); | |
71 break; | |
72 default: | |
73 sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype)… | |
74 NetL(ospf->auth+4)); | |
75 } | |
76 return auth; | |
77 } | |
78 | |
79 typedef struct Ospfhello Ospfhello; | |
80 struct Ospfhello | |
81 { | |
82 uchar mask[4]; | |
83 uchar interval[2]; | |
84 uchar options; | |
85 uchar pri; | |
86 uchar deadint[4]; | |
87 uchar designated[4]; | |
88 uchar bdesignated[4]; | |
89 uchar neighbor[1]; | |
90 }; | |
91 | |
92 char* | |
93 seprintospfhello(char *p, char *e, void *a) | |
94 { | |
95 Ospfhello *h = a; | |
96 | |
97 return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux dea… | |
98 ospftype[OSPFhello], | |
99 h->mask, NetS(h->interval), h->options, h->pri, | |
100 NetL(h->deadint), h->designated, h->bdesignated); | |
101 } | |
102 | |
103 enum | |
104 { | |
105 LSARouter= 1, | |
106 LSANetwork= 2, | |
107 LSASummN= 3, | |
108 LSASummR= 4, | |
109 LSAASext= 5 | |
110 }; | |
111 | |
112 | |
113 char *lsatype[] = { | |
114 [LSARouter] "Router LSA", | |
115 [LSANetwork] "Network LSA", | |
116 [LSASummN] "Summary LSA (Network)", | |
117 [LSASummR] "Summary LSA (Router)", | |
118 [LSAASext] "LSA AS external" | |
119 }; | |
120 | |
121 char* | |
122 lsapkttype(int x) | |
123 { | |
124 static char type[16]; | |
125 | |
126 if(x > 0 && x <= LSAASext) | |
127 return lsatype[x]; | |
128 sprint(type, "type %d", x); | |
129 return type; | |
130 } | |
131 | |
132 /* OSPF Link State Advertisement Header */ | |
133 /* rfc2178 section 12.1 */ | |
134 /* data of Ospfpkt point to a 4-uchar value that is the # of LSAs */ | |
135 struct OspfLSAhdr { | |
136 uchar lsage[2]; | |
137 uchar options; /* 0x2=stub area, 0x1=TOS routing c… | |
138 | |
139 uchar lstype; /* 1=Router-LSAs | |
140 * 2=Network-LSAs | |
141 * 3=Summary-LSAs (to ne… | |
142 * 4=Summary-LSAs (to AS… | |
143 * 5=AS-External-LSAs | |
144 */ | |
145 uchar lsid[4]; | |
146 uchar advtrt[4]; | |
147 | |
148 uchar lsseqno[4]; | |
149 uchar lscksum[2]; | |
150 uchar lsalen[2]; /* includes the 20 byte lsa heade… | |
151 }; | |
152 | |
153 struct Ospfrt { | |
154 uchar linkid[4]; | |
155 uchar linkdata[4]; | |
156 uchar typ; | |
157 uchar numtos; | |
158 uchar metric[2]; | |
159 | |
160 }; | |
161 | |
162 struct OspfrtLSA { | |
163 struct OspfLSAhdr hdr; | |
164 uchar netmask[4]; | |
165 }; | |
166 | |
167 struct OspfntLSA { | |
168 struct OspfLSAhdr hdr; | |
169 uchar netmask[4]; | |
170 uchar attrt[4]; | |
171 }; | |
172 | |
173 /* Summary Link State Advertisement info */ | |
174 struct Ospfsumm { | |
175 uchar flag; /* always zero */ | |
176 uchar metric[3]; | |
177 }; | |
178 | |
179 struct OspfsummLSA { | |
180 struct OspfLSAhdr hdr; | |
181 uchar netmask[4]; | |
182 struct Ospfsumm lsa; | |
183 }; | |
184 | |
185 /* AS external Link State Advertisement info */ | |
186 struct OspfASext { | |
187 uchar flag; /* external */ | |
188 uchar metric[3]; | |
189 uchar fwdaddr[4]; | |
190 uchar exrttag[4]; | |
191 }; | |
192 | |
193 struct OspfASextLSA { | |
194 struct OspfLSAhdr hdr; | |
195 uchar netmask[4]; | |
196 struct OspfASext lsa; | |
197 }; | |
198 | |
199 /* OSPF Link State Update Packet */ | |
200 struct OspfLSupdpkt { | |
201 uchar lsacnt[4]; | |
202 union { | |
203 uchar hdr[1]; | |
204 struct OspfrtLSA rt[1]; | |
205 struct OspfntLSA nt[1]; | |
206 struct OspfsummLSA sum[1]; | |
207 struct OspfASextLSA as[1]; | |
208 }; | |
209 }; | |
210 | |
211 char* | |
212 seprintospflsaheader(char *p, char *e, struct OspfLSAhdr *h) | |
213 { | |
214 return seprint(p, e, "age %d opt %ux type %ux lsid %V adv_rt %V … | |
215 NetS(h->lsage), h->options&0xff, h->lstype, | |
216 h->lsid, h->advtrt, NetL(h->lsseqno), NetS(h->lscksum), | |
217 NetS(h->lsalen)); | |
218 } | |
219 | |
220 /* OSPF Database Description Packet */ | |
221 struct OspfDDpkt { | |
222 uchar intMTU[2]; | |
223 uchar options; | |
224 uchar bits; | |
225 uchar DDseqno[4]; | |
226 struct OspfLSAhdr hdr[1]; /* LSA headers..… | |
227 }; | |
228 | |
229 char* | |
230 seprintospfdatadesc(char *p, char *e, void *a, int len) | |
231 { | |
232 int nlsa, i; | |
233 struct OspfDDpkt *g; | |
234 | |
235 g = (struct OspfDDpkt *)a; | |
236 nlsa = len/sizeof(struct OspfLSAhdr); | |
237 for (i=0; i<nlsa; i++) { | |
238 p = seprint(p, e, "lsa%d(", i); | |
239 p = seprintospflsaheader(p, e, &(g->hdr[i])); | |
240 p = seprint(p, e, ")"); | |
241 } | |
242 return seprint(p, e, ")"); | |
243 } | |
244 | |
245 char* | |
246 seprintospflsupdate(char *p, char *e, void *a, int len) | |
247 { | |
248 int nlsa, i; | |
249 struct OspfLSupdpkt *g; | |
250 struct OspfLSAhdr *h; | |
251 | |
252 g = (struct OspfLSupdpkt *)a; | |
253 nlsa = NetL(g->lsacnt); | |
254 h = (struct OspfLSAhdr *)(g->hdr); | |
255 p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsupdate)); | |
256 | |
257 switch(h->lstype) { | |
258 case LSARouter: | |
259 { | |
260 /* struct OspfrtLSA *h; | |
261 */ | |
262 } | |
263 break; | |
264 case LSANetwork: | |
265 { | |
266 struct OspfntLSA *h; | |
267 | |
268 for (i=0; i<nlsa; i++) { | |
269 h = &(g->nt[i]); | |
270 p = seprint(p, e, "lsa%d(", i); | |
271 p = seprintospflsaheader(p, e, &(h->hdr)… | |
272 p = seprint(p, e, " mask %V attrt %V)", | |
273 h->netmask, h->attrt); | |
274 } | |
275 } | |
276 break; | |
277 case LSASummN: | |
278 case LSASummR: | |
279 { | |
280 struct OspfsummLSA *h; | |
281 | |
282 for (i=0; i<nlsa; i++) { | |
283 h = &(g->sum[i]); | |
284 p = seprint(p, e, "lsa%d(", i); | |
285 p = seprintospflsaheader(p, e, &(h->hdr)… | |
286 p = seprint(p, e, " mask %V met %d)", | |
287 h->netmask, Net3(h->lsa.metric)); | |
288 } | |
289 } | |
290 break; | |
291 case LSAASext: | |
292 { | |
293 struct OspfASextLSA *h; | |
294 | |
295 for (i=0; i<nlsa; i++) { | |
296 h = &(g->as[i]); | |
297 p = seprint(p, e, " lsa%d(", i); | |
298 p = seprintospflsaheader(p, e, &(h->hdr)… | |
299 p = seprint(p, e, " mask %V extflg %1.1u… | |
300 h->netmask, h->lsa.flag, Net3(h-… | |
301 h->lsa.fwdaddr, NetL(h->lsa.exrt… | |
302 } | |
303 } | |
304 break; | |
305 default: | |
306 p = seprint(p, e, "Not an LS update, lstype %d ", h->lst… | |
307 p = seprint(p, e, " %.*H", len>64?64:len, a); | |
308 break; | |
309 } | |
310 return seprint(p, e, ")"); | |
311 } | |
312 | |
313 char* | |
314 seprintospflsack(char *p, char *e, void *a, int len) | |
315 { | |
316 int nlsa, i; | |
317 struct OspfLSAhdr *h; | |
318 | |
319 h = (struct OspfLSAhdr *)a; | |
320 nlsa = len/sizeof(struct OspfLSAhdr); | |
321 p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsack)); | |
322 for (i=0; i<nlsa; i++) { | |
323 p = seprint(p, e, " lsa%d(", i); | |
324 p = seprintospflsaheader(p, e, &(h[i])); | |
325 p = seprint(p, e, ")"); | |
326 } | |
327 return seprint(p, e, ")"); | |
328 } | |
329 | |
330 int | |
331 p_seprint(Msg *m) | |
332 { | |
333 Ospfpkt *ospf; | |
334 int len, x; | |
335 char *p, *e; | |
336 | |
337 len = m->pe - m->ps; | |
338 if(len < OSPF_HDRSIZE) | |
339 return -1; | |
340 p = m->p; | |
341 e = m->e; | |
342 | |
343 /* adjust packet size */ | |
344 ospf = (Ospfpkt*)m->ps; | |
345 x = NetS(ospf->length); | |
346 if(x < len) | |
347 return -1; | |
348 x -= OSPF_HDRSIZE; | |
349 | |
350 p = seprint(p, e, "ver=%d type=%d len=%d r=%V a=%V c=%4.4ux %s ", | |
351 ospf->version, ospf->type, x, | |
352 ospf->router, ospf->area, NetS(ospf->sum), | |
353 ospfauth(ospf)); | |
354 | |
355 switch (ospf->type) { | |
356 case OSPFhello: | |
357 p = seprintospfhello(p, e, ospf->data); | |
358 break; | |
359 case OSPFdd: | |
360 p = seprintospfdatadesc(p, e, ospf->data, x); | |
361 break; | |
362 case OSPFlsrequest: | |
363 p = seprint(p, e, " %s->", ospfpkttype(ospf->type)); | |
364 goto Default; | |
365 case OSPFlsupdate: | |
366 p = seprintospflsupdate(p, e, ospf->data, x); | |
367 break; | |
368 case OSPFlsack: | |
369 p = seprintospflsack(p, e, ospf->data, x); | |
370 break; | |
371 default: | |
372 Default: | |
373 p = seprint(p, e, " data=%.*H", x>64?64:x, ospf->data); | |
374 } | |
375 m->p = p; | |
376 m->pr = nil; | |
377 return 0; | |
378 } | |
379 | |
380 Proto ospf = | |
381 { | |
382 "ospf", | |
383 nil, | |
384 nil, | |
385 p_seprint, | |
386 nil, | |
387 nil, | |
388 nil, | |
389 defaultframer | |
390 }; |