Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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->auth),	
70
			ospf->auth[2], ospf->auth[3]);
71
		break;
72
	default:
73
		sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype), NetL(ospf->auth),	
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 deadt %d designated %V bdesignated %V)",
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 capable */
138
 
139
	uchar	lstype;	/* 1=Router-LSAs
140
						 * 2=Network-LSAs
141
						 * 3=Summary-LSAs (to network)
142
						 * 4=Summary-LSAs (to AS boundary routers)
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 header */
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 seqno %ux c %4.4ux l %d",
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.1ux met %d fwdaddr %V extrtflg %ux)",
300
					h->netmask, h->lsa.flag, Net3(h->lsa.metric),
301
					h->lsa.fwdaddr, NetL(h->lsa.exrttag));
302
			}
303
		}
304
		break;
305
	default:
306
		p = seprint(p, e, "Not an LS update, lstype %d ", h->lstype);
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
};