xref: /plan9/sys/src/cmd/ip/snoopy/ospf.c (revision 2cca75a1b2b8c6083390679d69d5c50cf66d9a01)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include <libsec.h>
59a747e4fSDavid du Colombier #include "dat.h"
69a747e4fSDavid du Colombier #include "protos.h"
79a747e4fSDavid du Colombier 
89a747e4fSDavid du Colombier 
99a747e4fSDavid du Colombier /*
109a747e4fSDavid du Colombier  *  OSPF packets
119a747e4fSDavid du Colombier  */
129a747e4fSDavid du Colombier typedef struct Ospfpkt	Ospfpkt;
139a747e4fSDavid du Colombier struct Ospfpkt
149a747e4fSDavid du Colombier {
159a747e4fSDavid du Colombier 	uchar	version;
169a747e4fSDavid du Colombier 	uchar	type;
179a747e4fSDavid du Colombier 	uchar	length[2];
189a747e4fSDavid du Colombier 	uchar	router[4];
199a747e4fSDavid du Colombier 	uchar	area[4];
209a747e4fSDavid du Colombier 	uchar	sum[2];
219a747e4fSDavid du Colombier 	uchar	autype[2];
229a747e4fSDavid du Colombier 	uchar	auth[8];
239a747e4fSDavid du Colombier 	uchar	data[1];
249a747e4fSDavid du Colombier };
259a747e4fSDavid du Colombier #define OSPF_HDRSIZE	24
269a747e4fSDavid du Colombier 
279a747e4fSDavid du Colombier enum
289a747e4fSDavid du Colombier {
299a747e4fSDavid du Colombier 	OSPFhello=	1,
309a747e4fSDavid du Colombier 	OSPFdd=		2,
319a747e4fSDavid du Colombier 	OSPFlsrequest=	3,
329a747e4fSDavid du Colombier 	OSPFlsupdate=	4,
339a747e4fSDavid du Colombier 	OSPFlsack=	5,
349a747e4fSDavid du Colombier };
359a747e4fSDavid du Colombier 
369a747e4fSDavid du Colombier 
379a747e4fSDavid du Colombier char *ospftype[] = {
389a747e4fSDavid du Colombier 	[OSPFhello]	"hello",
399a747e4fSDavid du Colombier 	[OSPFdd]	"data definition",
409a747e4fSDavid du Colombier 	[OSPFlsrequest]	"link state request",
419a747e4fSDavid du Colombier 	[OSPFlsupdate]	"link state update",
429a747e4fSDavid du Colombier 	[OSPFlsack]	"link state ack",
439a747e4fSDavid du Colombier };
449a747e4fSDavid du Colombier 
459a747e4fSDavid du Colombier char*
ospfpkttype(int x)469a747e4fSDavid du Colombier ospfpkttype(int x)
479a747e4fSDavid du Colombier {
489a747e4fSDavid du Colombier 	static char type[16];
499a747e4fSDavid du Colombier 
509a747e4fSDavid du Colombier 	if(x > 0 && x <= OSPFlsack)
519a747e4fSDavid du Colombier 		return ospftype[x];
529a747e4fSDavid du Colombier 	sprint(type, "type %d", x);
539a747e4fSDavid du Colombier 	return type;
549a747e4fSDavid du Colombier }
559a747e4fSDavid du Colombier 
569a747e4fSDavid du Colombier char*
ospfauth(Ospfpkt * ospf)579a747e4fSDavid du Colombier ospfauth(Ospfpkt *ospf)
589a747e4fSDavid du Colombier {
599a747e4fSDavid du Colombier 	static char auth[100];
609a747e4fSDavid du Colombier 
619a747e4fSDavid du Colombier 	switch(ospf->type){
629a747e4fSDavid du Colombier 	case 0:
639a747e4fSDavid du Colombier 		return "no authentication";
649a747e4fSDavid du Colombier 	case 1:
659a747e4fSDavid du Colombier 		sprint(auth, "password(%8.8ux %8.8ux)", NetL(ospf->auth),
669a747e4fSDavid du Colombier 			NetL(ospf->auth+4));
679a747e4fSDavid du Colombier 		break;
689a747e4fSDavid du Colombier 	case 2:
699a747e4fSDavid du Colombier 		sprint(auth, "crypto(plen %d id %d dlen %d)", NetS(ospf->auth),
709a747e4fSDavid du Colombier 			ospf->auth[2], ospf->auth[3]);
719a747e4fSDavid du Colombier 		break;
729a747e4fSDavid du Colombier 	default:
739a747e4fSDavid du Colombier 		sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype), NetL(ospf->auth),
749a747e4fSDavid du Colombier 			NetL(ospf->auth+4));
759a747e4fSDavid du Colombier 	}
769a747e4fSDavid du Colombier 	return auth;
779a747e4fSDavid du Colombier }
789a747e4fSDavid du Colombier 
799a747e4fSDavid du Colombier typedef struct Ospfhello	Ospfhello;
809a747e4fSDavid du Colombier struct Ospfhello
819a747e4fSDavid du Colombier {
829a747e4fSDavid du Colombier 	uchar	mask[4];
839a747e4fSDavid du Colombier 	uchar	interval[2];
849a747e4fSDavid du Colombier 	uchar	options;
859a747e4fSDavid du Colombier 	uchar	pri;
869a747e4fSDavid du Colombier 	uchar	deadint[4];
879a747e4fSDavid du Colombier 	uchar	designated[4];
889a747e4fSDavid du Colombier 	uchar	bdesignated[4];
899a747e4fSDavid du Colombier 	uchar	neighbor[1];
909a747e4fSDavid du Colombier };
919a747e4fSDavid du Colombier 
929a747e4fSDavid du Colombier char*
seprintospfhello(char * p,char * e,void * a)93*2cca75a1SDavid du Colombier seprintospfhello(char *p, char *e, void *a)
949a747e4fSDavid du Colombier {
959a747e4fSDavid du Colombier 	Ospfhello *h = a;
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier 	return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)",
989a747e4fSDavid du Colombier 		ospftype[OSPFhello],
999a747e4fSDavid du Colombier 		h->mask, NetS(h->interval), h->options, h->pri,
1009a747e4fSDavid du Colombier 		NetL(h->deadint), h->designated, h->bdesignated);
1019a747e4fSDavid du Colombier }
1029a747e4fSDavid du Colombier 
1039a747e4fSDavid du Colombier enum
1049a747e4fSDavid du Colombier {
1059a747e4fSDavid du Colombier 	LSARouter=	1,
1069a747e4fSDavid du Colombier 	LSANetwork=	2,
1079a747e4fSDavid du Colombier 	LSASummN=	3,
1089a747e4fSDavid du Colombier 	LSASummR=	4,
1099a747e4fSDavid du Colombier 	LSAASext=	5
1109a747e4fSDavid du Colombier };
1119a747e4fSDavid du Colombier 
1129a747e4fSDavid du Colombier 
1139a747e4fSDavid du Colombier char *lsatype[] = {
1149a747e4fSDavid du Colombier 	[LSARouter]	"Router LSA",
1159a747e4fSDavid du Colombier 	[LSANetwork]	"Network LSA",
1169a747e4fSDavid du Colombier 	[LSASummN]	"Summary LSA (Network)",
1179a747e4fSDavid du Colombier 	[LSASummR]	"Summary LSA (Router)",
1189a747e4fSDavid du Colombier 	[LSAASext]	"LSA AS external",
1199a747e4fSDavid du Colombier };
1209a747e4fSDavid du Colombier 
1219a747e4fSDavid du Colombier char*
lsapkttype(int x)1229a747e4fSDavid du Colombier lsapkttype(int x)
1239a747e4fSDavid du Colombier {
1249a747e4fSDavid du Colombier 	static char type[16];
1259a747e4fSDavid du Colombier 
1269a747e4fSDavid du Colombier 	if(x > 0 && x <= LSAASext)
1279a747e4fSDavid du Colombier 		return lsatype[x];
1289a747e4fSDavid du Colombier 	sprint(type, "type %d", x);
1299a747e4fSDavid du Colombier 	return type;
1309a747e4fSDavid du Colombier }
1319a747e4fSDavid du Colombier 
1329a747e4fSDavid du Colombier /* OSPF Link State Advertisement Header */
1339a747e4fSDavid du Colombier /* rfc2178 section 12.1 */
1349a747e4fSDavid du Colombier /* data of Ospfpkt point to a 4-uchar value that is the # of LSAs */
1359a747e4fSDavid du Colombier struct OspfLSAhdr {
1369a747e4fSDavid du Colombier 	uchar	lsage[2];
1379a747e4fSDavid du Colombier 	uchar	options;	/* 0x2=stub area, 0x1=TOS routing capable */
1389a747e4fSDavid du Colombier 
1399a747e4fSDavid du Colombier 	uchar	lstype;	/* 1=Router-LSAs
1409a747e4fSDavid du Colombier 						 * 2=Network-LSAs
1419a747e4fSDavid du Colombier 						 * 3=Summary-LSAs (to network)
1429a747e4fSDavid du Colombier 						 * 4=Summary-LSAs (to AS boundary routers)
1439a747e4fSDavid du Colombier 						 * 5=AS-External-LSAs
1449a747e4fSDavid du Colombier 						 */
1459a747e4fSDavid du Colombier 	uchar	lsid[4];
1469a747e4fSDavid du Colombier 	uchar	advtrt[4];
1479a747e4fSDavid du Colombier 
1489a747e4fSDavid du Colombier 	uchar	lsseqno[4];
1499a747e4fSDavid du Colombier 	uchar	lscksum[2];
1509a747e4fSDavid du Colombier 	uchar	lsalen[2];	/* includes the 20 byte lsa header */
1519a747e4fSDavid du Colombier };
1529a747e4fSDavid du Colombier 
1539a747e4fSDavid du Colombier struct Ospfrt {
1549a747e4fSDavid du Colombier 	uchar	linkid[4];
1559a747e4fSDavid du Colombier 	uchar	linkdata[4];
1569a747e4fSDavid du Colombier 	uchar	typ;
1579a747e4fSDavid du Colombier 	uchar	numtos;
1589a747e4fSDavid du Colombier 	uchar	metric[2];
1599a747e4fSDavid du Colombier 
1609a747e4fSDavid du Colombier };
1619a747e4fSDavid du Colombier 
1629a747e4fSDavid du Colombier struct OspfrtLSA {
1639a747e4fSDavid du Colombier 	struct OspfLSAhdr	hdr;
1649a747e4fSDavid du Colombier 	uchar			netmask[4];
1659a747e4fSDavid du Colombier };
1669a747e4fSDavid du Colombier 
1679a747e4fSDavid du Colombier struct OspfntLSA {
1689a747e4fSDavid du Colombier 	struct OspfLSAhdr	hdr;
1699a747e4fSDavid du Colombier 	uchar			netmask[4];
1709a747e4fSDavid du Colombier 	uchar			attrt[4];
1719a747e4fSDavid du Colombier };
1729a747e4fSDavid du Colombier 
1739a747e4fSDavid du Colombier /* Summary Link State Advertisement info */
1749a747e4fSDavid du Colombier struct Ospfsumm {
1759a747e4fSDavid du Colombier 	uchar	flag;	/* always zero */
1769a747e4fSDavid du Colombier 	uchar	metric[3];
1779a747e4fSDavid du Colombier };
1789a747e4fSDavid du Colombier 
1799a747e4fSDavid du Colombier struct OspfsummLSA {
1809a747e4fSDavid du Colombier 	struct OspfLSAhdr	hdr;
1819a747e4fSDavid du Colombier 	uchar			netmask[4];
1829a747e4fSDavid du Colombier 	struct Ospfsumm		lsa;
1839a747e4fSDavid du Colombier };
1849a747e4fSDavid du Colombier 
1859a747e4fSDavid du Colombier /* AS external Link State Advertisement info */
1869a747e4fSDavid du Colombier struct OspfASext {
1879a747e4fSDavid du Colombier 	uchar	flag;	/* external */
1889a747e4fSDavid du Colombier 	uchar	metric[3];
1899a747e4fSDavid du Colombier 	uchar	fwdaddr[4];
1909a747e4fSDavid du Colombier 	uchar	exrttag[4];
1919a747e4fSDavid du Colombier };
1929a747e4fSDavid du Colombier 
1939a747e4fSDavid du Colombier struct OspfASextLSA {
1949a747e4fSDavid du Colombier 	struct OspfLSAhdr	hdr;
1959a747e4fSDavid du Colombier 	uchar			netmask[4];
1969a747e4fSDavid du Colombier 	struct OspfASext	lsa;
1979a747e4fSDavid du Colombier };
1989a747e4fSDavid du Colombier 
1999a747e4fSDavid du Colombier /* OSPF Link State Update Packet */
2009a747e4fSDavid du Colombier struct OspfLSupdpkt {
2019a747e4fSDavid du Colombier 	uchar	lsacnt[4];
2029a747e4fSDavid du Colombier 	union {
2039a747e4fSDavid du Colombier 		uchar			hdr[1];
2049a747e4fSDavid du Colombier 		struct OspfrtLSA	rt[1];
2059a747e4fSDavid du Colombier 		struct OspfntLSA	nt[1];
2069a747e4fSDavid du Colombier 		struct OspfsummLSA	sum[1];
2079a747e4fSDavid du Colombier 		struct OspfASextLSA	as[1];
2089a747e4fSDavid du Colombier 	};
2099a747e4fSDavid du Colombier };
2109a747e4fSDavid du Colombier 
2119a747e4fSDavid du Colombier char*
seprintospflsaheader(char * p,char * e,struct OspfLSAhdr * h)2129a747e4fSDavid du Colombier seprintospflsaheader(char *p, char *e, struct OspfLSAhdr *h)
2139a747e4fSDavid du Colombier {
2149a747e4fSDavid du Colombier 	return seprint(p, e, "age %d opt %ux type %ux lsid %V adv_rt %V seqno %ux c %4.4ux l %d",
2159a747e4fSDavid du Colombier 		NetS(h->lsage), h->options&0xff, h->lstype,
2169a747e4fSDavid du Colombier 		h->lsid, h->advtrt, NetL(h->lsseqno), NetS(h->lscksum),
2179a747e4fSDavid du Colombier 		NetS(h->lsalen));
2189a747e4fSDavid du Colombier }
2199a747e4fSDavid du Colombier 
2209a747e4fSDavid du Colombier /* OSPF Database Description Packet */
2219a747e4fSDavid du Colombier struct OspfDDpkt {
2229a747e4fSDavid du Colombier 	uchar	intMTU[2];
2239a747e4fSDavid du Colombier 	uchar	options;
2249a747e4fSDavid du Colombier 	uchar	bits;
2259a747e4fSDavid du Colombier 	uchar	DDseqno[4];
2269a747e4fSDavid du Colombier 	struct OspfLSAhdr	hdr[1];		/* LSA headers... */
2279a747e4fSDavid du Colombier };
2289a747e4fSDavid du Colombier 
2299a747e4fSDavid du Colombier char*
seprintospfdatadesc(char * p,char * e,void * a,int len)2309a747e4fSDavid du Colombier seprintospfdatadesc(char *p, char *e, void *a, int len)
2319a747e4fSDavid du Colombier {
2329a747e4fSDavid du Colombier 	int nlsa, i;
2339a747e4fSDavid du Colombier 	struct OspfDDpkt *g;
2349a747e4fSDavid du Colombier 
2359a747e4fSDavid du Colombier 	g = (struct OspfDDpkt *)a;
2369a747e4fSDavid du Colombier 	nlsa = len/sizeof(struct OspfLSAhdr);
2379a747e4fSDavid du Colombier 	for (i=0; i<nlsa; i++) {
2389a747e4fSDavid du Colombier 		p = seprint(p, e, "lsa%d(", i);
2399a747e4fSDavid du Colombier 		p = seprintospflsaheader(p, e, &(g->hdr[i]));
2409a747e4fSDavid du Colombier 		p = seprint(p, e, ")");
2419a747e4fSDavid du Colombier 	}
2429a747e4fSDavid du Colombier 	return seprint(p, e, ")");
2439a747e4fSDavid du Colombier }
2449a747e4fSDavid du Colombier 
2459a747e4fSDavid du Colombier char*
seprintospflsupdate(char * p,char * e,void * a,int len)2469a747e4fSDavid du Colombier seprintospflsupdate(char *p, char *e, void *a, int len)
2479a747e4fSDavid du Colombier {
2489a747e4fSDavid du Colombier 	int nlsa, i;
2499a747e4fSDavid du Colombier 	struct OspfLSupdpkt *g;
2509a747e4fSDavid du Colombier 	struct OspfLSAhdr *h;
2519a747e4fSDavid du Colombier 
2529a747e4fSDavid du Colombier 	g = (struct OspfLSupdpkt *)a;
2539a747e4fSDavid du Colombier 	nlsa = NetL(g->lsacnt);
2549a747e4fSDavid du Colombier 	h = (struct OspfLSAhdr *)(g->hdr);
2559a747e4fSDavid du Colombier 	p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsupdate));
2569a747e4fSDavid du Colombier 
2579a747e4fSDavid du Colombier 	switch(h->lstype) {
2589a747e4fSDavid du Colombier 	case LSARouter:
2599a747e4fSDavid du Colombier 		{
2609a747e4fSDavid du Colombier /*			struct OspfrtLSA *h;
2619a747e4fSDavid du Colombier  */
2629a747e4fSDavid du Colombier 		}
2639a747e4fSDavid du Colombier 		break;
2649a747e4fSDavid du Colombier 	case LSANetwork:
2659a747e4fSDavid du Colombier 		{
2669a747e4fSDavid du Colombier 			struct OspfntLSA *h;
2679a747e4fSDavid du Colombier 
2689a747e4fSDavid du Colombier 			for (i=0; i<nlsa; i++) {
2699a747e4fSDavid du Colombier 				h = &(g->nt[i]);
2709a747e4fSDavid du Colombier 				p = seprint(p, e, "lsa%d(", i);
2719a747e4fSDavid du Colombier 				p = seprintospflsaheader(p, e, &(h->hdr));
2729a747e4fSDavid du Colombier 				p = seprint(p, e, " mask %V attrt %V)",
2739a747e4fSDavid du Colombier 					h->netmask, h->attrt);
2749a747e4fSDavid du Colombier 			}
2759a747e4fSDavid du Colombier 		}
2769a747e4fSDavid du Colombier 		break;
2779a747e4fSDavid du Colombier 	case LSASummN:
2789a747e4fSDavid du Colombier 	case LSASummR:
2799a747e4fSDavid du Colombier 		{
2809a747e4fSDavid du Colombier 			struct OspfsummLSA *h;
2819a747e4fSDavid du Colombier 
2829a747e4fSDavid du Colombier 			for (i=0; i<nlsa; i++) {
2839a747e4fSDavid du Colombier 				h = &(g->sum[i]);
2849a747e4fSDavid du Colombier 				p = seprint(p, e, "lsa%d(", i);
2859a747e4fSDavid du Colombier 				p = seprintospflsaheader(p, e, &(h->hdr));
2869a747e4fSDavid du Colombier 				p = seprint(p, e, " mask %V met %d)",
2879a747e4fSDavid du Colombier 					h->netmask, Net3(h->lsa.metric));
2889a747e4fSDavid du Colombier 			}
2899a747e4fSDavid du Colombier 		}
2909a747e4fSDavid du Colombier 		break;
2919a747e4fSDavid du Colombier 	case LSAASext:
2929a747e4fSDavid du Colombier 		{
2939a747e4fSDavid du Colombier 			struct OspfASextLSA *h;
2949a747e4fSDavid du Colombier 
2959a747e4fSDavid du Colombier 			for (i=0; i<nlsa; i++) {
2969a747e4fSDavid du Colombier 				h = &(g->as[i]);
2979a747e4fSDavid du Colombier 				p = seprint(p, e, " lsa%d(", i);
2989a747e4fSDavid du Colombier 				p = seprintospflsaheader(p, e, &(h->hdr));
2999a747e4fSDavid du Colombier 				p = seprint(p, e, " mask %V extflg %1.1ux met %d fwdaddr %V extrtflg %ux)",
3009a747e4fSDavid du Colombier 					h->netmask, h->lsa.flag, Net3(h->lsa.metric),
3019a747e4fSDavid du Colombier 					h->lsa.fwdaddr, NetL(h->lsa.exrttag));
3029a747e4fSDavid du Colombier 			}
3039a747e4fSDavid du Colombier 		}
3049a747e4fSDavid du Colombier 		break;
3059a747e4fSDavid du Colombier 	default:
3069a747e4fSDavid du Colombier 		p = seprint(p, e, "Not an LS update, lstype %d ", h->lstype);
3079a747e4fSDavid du Colombier 		p = seprint(p, e, " %.*H", len>64?64:len, a);
3089a747e4fSDavid du Colombier 		break;
3099a747e4fSDavid du Colombier 	}
3109a747e4fSDavid du Colombier 	return seprint(p, e, ")");
3119a747e4fSDavid du Colombier }
3129a747e4fSDavid du Colombier 
3139a747e4fSDavid du Colombier char*
seprintospflsack(char * p,char * e,void * a,int len)3149a747e4fSDavid du Colombier seprintospflsack(char *p, char *e, void *a, int len)
3159a747e4fSDavid du Colombier {
3169a747e4fSDavid du Colombier 	int nlsa, i;
3179a747e4fSDavid du Colombier 	struct OspfLSAhdr *h;
3189a747e4fSDavid du Colombier 
3199a747e4fSDavid du Colombier 	h = (struct OspfLSAhdr *)a;
3209a747e4fSDavid du Colombier 	nlsa = len/sizeof(struct OspfLSAhdr);
3219a747e4fSDavid du Colombier 	p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsack));
3229a747e4fSDavid du Colombier 	for (i=0; i<nlsa; i++) {
3239a747e4fSDavid du Colombier 		p = seprint(p, e, " lsa%d(", i);
3249a747e4fSDavid du Colombier 		p = seprintospflsaheader(p, e, &(h[i]));
3259a747e4fSDavid du Colombier 		p = seprint(p, e, ")");
3269a747e4fSDavid du Colombier 	}
3279a747e4fSDavid du Colombier 	return seprint(p, e, ")");
3289a747e4fSDavid du Colombier }
3299a747e4fSDavid du Colombier 
3309a747e4fSDavid du Colombier int
p_seprint(Msg * m)3319a747e4fSDavid du Colombier p_seprint(Msg *m)
3329a747e4fSDavid du Colombier {
3339a747e4fSDavid du Colombier 	Ospfpkt *ospf;
3349a747e4fSDavid du Colombier 	int len, x;
3359a747e4fSDavid du Colombier 	char *p, *e;
3369a747e4fSDavid du Colombier 
3379a747e4fSDavid du Colombier 	len = m->pe - m->ps;
3389a747e4fSDavid du Colombier 	if(len < OSPF_HDRSIZE)
3399a747e4fSDavid du Colombier 		return -1;
3409a747e4fSDavid du Colombier 	p = m->p;
3419a747e4fSDavid du Colombier 	e = m->e;
3429a747e4fSDavid du Colombier 
3439a747e4fSDavid du Colombier 	/* adjust packet size */
3449a747e4fSDavid du Colombier 	ospf = (Ospfpkt*)m->ps;
3459a747e4fSDavid du Colombier 	x = NetS(ospf->length);
3469a747e4fSDavid du Colombier 	if(x < len)
3479a747e4fSDavid du Colombier 		return -1;
3489a747e4fSDavid du Colombier 	x -= OSPF_HDRSIZE;
3499a747e4fSDavid du Colombier 
3509a747e4fSDavid du Colombier 	p = seprint(p, e, "ver=%d type=%d len=%d r=%V a=%V c=%4.4ux %s ",
3519a747e4fSDavid du Colombier 		ospf->version, ospf->type, x,
3529a747e4fSDavid du Colombier 		ospf->router, ospf->area, NetS(ospf->sum),
3539a747e4fSDavid du Colombier 		ospfauth(ospf));
3549a747e4fSDavid du Colombier 
3559a747e4fSDavid du Colombier 	switch (ospf->type) {
3569a747e4fSDavid du Colombier 	case OSPFhello:
357*2cca75a1SDavid du Colombier 		p = seprintospfhello(p, e, ospf->data);
3589a747e4fSDavid du Colombier 		break;
3599a747e4fSDavid du Colombier 	case OSPFdd:
3609a747e4fSDavid du Colombier 		p = seprintospfdatadesc(p, e, ospf->data, x);
3619a747e4fSDavid du Colombier 		break;
3629a747e4fSDavid du Colombier 	case OSPFlsrequest:
3639a747e4fSDavid du Colombier 		p = seprint(p, e, " %s->", ospfpkttype(ospf->type));
3649a747e4fSDavid du Colombier 		goto Default;
3659a747e4fSDavid du Colombier 	case OSPFlsupdate:
3669a747e4fSDavid du Colombier 		p = seprintospflsupdate(p, e, ospf->data, x);
3679a747e4fSDavid du Colombier 		break;
3689a747e4fSDavid du Colombier 	case OSPFlsack:
3699a747e4fSDavid du Colombier 		p = seprintospflsack(p, e, ospf->data, x);
3709a747e4fSDavid du Colombier 		break;
3719a747e4fSDavid du Colombier 	default:
3729a747e4fSDavid du Colombier Default:
3739a747e4fSDavid du Colombier 		p = seprint(p, e, " data=%.*H", x>64?64:x, ospf->data);
3749a747e4fSDavid du Colombier 	}
3759a747e4fSDavid du Colombier 	m->p = p;
3769a747e4fSDavid du Colombier 	m->pr = nil;
3779a747e4fSDavid du Colombier 	return 0;
3789a747e4fSDavid du Colombier }
3799a747e4fSDavid du Colombier 
3809a747e4fSDavid du Colombier Proto ospf =
3819a747e4fSDavid du Colombier {
3829a747e4fSDavid du Colombier 	"ospf",
383*2cca75a1SDavid du Colombier 	nil,
384*2cca75a1SDavid du Colombier 	nil,
3859a747e4fSDavid du Colombier 	p_seprint,
3869a747e4fSDavid du Colombier 	nil,
3879a747e4fSDavid du Colombier 	nil,
388ed397113SDavid du Colombier 	nil,
3893ff48bf5SDavid du Colombier 	defaultframer,
3909a747e4fSDavid du Colombier };
391