From 87a52e0485d3281ebea6bf4b725aa8023690e96f Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 26 Dec 2005 04:48:52 +0000 Subject: new goodies --- src/cmd/ip/snoopy/ospf.c | 404 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100755 src/cmd/ip/snoopy/ospf.c (limited to 'src/cmd/ip/snoopy/ospf.c') diff --git a/src/cmd/ip/snoopy/ospf.c b/src/cmd/ip/snoopy/ospf.c new file mode 100755 index 00000000..35ed55e1 --- /dev/null +++ b/src/cmd/ip/snoopy/ospf.c @@ -0,0 +1,404 @@ +#include +#include +#include +#include +#include "dat.h" +#include "protos.h" + + +/* + * OSPF packets + */ +typedef struct Ospfpkt Ospfpkt; +struct Ospfpkt +{ + uchar version; + uchar type; + uchar length[2]; + uchar router[4]; + uchar area[4]; + uchar sum[2]; + uchar autype[2]; + uchar auth[8]; + uchar data[1]; +}; +#define OSPF_HDRSIZE 24 + +enum +{ + OSPFhello= 1, + OSPFdd= 2, + OSPFlsrequest= 3, + OSPFlsupdate= 4, + OSPFlsack= 5, +}; + + +char *ospftype[] = { + [OSPFhello] "hello", + [OSPFdd] "data definition", + [OSPFlsrequest] "link state request", + [OSPFlsupdate] "link state update", + [OSPFlsack] "link state ack", +}; + +char* +ospfpkttype(int x) +{ + static char type[16]; + + if(x > 0 && x <= OSPFlsack) + return ospftype[x]; + sprint(type, "type %d", x); + return type; +} + +char* +ospfauth(Ospfpkt *ospf) +{ + static char auth[100]; + + switch(ospf->type){ + case 0: + return "no authentication"; + case 1: + sprint(auth, "password(%8.8ux %8.8ux)", NetL(ospf->auth), + NetL(ospf->auth+4)); + break; + case 2: + sprint(auth, "crypto(plen %d id %d dlen %d)", NetS(ospf->auth), + ospf->auth[2], ospf->auth[3]); + break; + default: + sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype), NetL(ospf->auth), + NetL(ospf->auth+4)); + } + return auth; +} + +typedef struct Ospfhello Ospfhello; +struct Ospfhello +{ + uchar mask[4]; + uchar interval[2]; + uchar options; + uchar pri; + uchar deadint[4]; + uchar designated[4]; + uchar bdesignated[4]; + uchar neighbor[1]; +}; + +char* +seprintospfhello(char *p, char *e, void *a, int x) +{ + Ospfhello *h = a; + + USED(x); + return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)", + ospftype[OSPFhello], + h->mask, NetS(h->interval), h->options, h->pri, + NetL(h->deadint), h->designated, h->bdesignated); +} + +enum +{ + LSARouter= 1, + LSANetwork= 2, + LSASummN= 3, + LSASummR= 4, + LSAASext= 5 +}; + + +char *lsatype[] = { + [LSARouter] "Router LSA", + [LSANetwork] "Network LSA", + [LSASummN] "Summary LSA (Network)", + [LSASummR] "Summary LSA (Router)", + [LSAASext] "LSA AS external", +}; + +char* +lsapkttype(int x) +{ + static char type[16]; + + if(x > 0 && x <= LSAASext) + return lsatype[x]; + sprint(type, "type %d", x); + return type; +} + +/* OSPF Link State Advertisement Header */ +/* rfc2178 section 12.1 */ +/* data of Ospfpkt point to a 4-uchar value that is the # of LSAs */ +struct OspfLSAhdr { + uchar lsage[2]; + uchar options; /* 0x2=stub area, 0x1=TOS routing capable */ + + uchar lstype; /* 1=Router-LSAs + * 2=Network-LSAs + * 3=Summary-LSAs (to network) + * 4=Summary-LSAs (to AS boundary routers) + * 5=AS-External-LSAs + */ + uchar lsid[4]; + uchar advtrt[4]; + + uchar lsseqno[4]; + uchar lscksum[2]; + uchar lsalen[2]; /* includes the 20 byte lsa header */ +}; + +struct Ospfrt { + uchar linkid[4]; + uchar linkdata[4]; + uchar typ; + uchar numtos; + uchar metric[2]; + +}; + +struct OspfrtLSA { + struct OspfLSAhdr hdr; + uchar netmask[4]; +}; + +struct OspfntLSA { + struct OspfLSAhdr hdr; + uchar netmask[4]; + uchar attrt[4]; +}; + +/* Summary Link State Advertisement info */ +struct Ospfsumm { + uchar flag; /* always zero */ + uchar metric[3]; +}; + +struct OspfsummLSA { + struct OspfLSAhdr hdr; + uchar netmask[4]; + struct Ospfsumm lsa; +}; + +/* AS external Link State Advertisement info */ +struct OspfASext { + uchar flag; /* external */ + uchar metric[3]; + uchar fwdaddr[4]; + uchar exrttag[4]; +}; + +struct OspfASextLSA { + struct OspfLSAhdr hdr; + uchar netmask[4]; + struct OspfASext lsa; +}; + +/* OSPF Link State Update Packet */ +struct OspfLSupdpkt { + uchar lsacnt[4]; + union { + uchar hdr[1]; + struct OspfrtLSA rt[1]; + struct OspfntLSA nt[1]; + struct OspfsummLSA sum[1]; + struct OspfASextLSA as[1]; + }; +}; + +char* +seprintospflsaheader(char *p, char *e, struct OspfLSAhdr *h) +{ + return seprint(p, e, "age %d opt %ux type %ux lsid %V adv_rt %V seqno %ux c %4.4ux l %d", + NetS(h->lsage), h->options&0xff, h->lstype, + h->lsid, h->advtrt, NetL(h->lsseqno), NetS(h->lscksum), + NetS(h->lsalen)); +} + +/* OSPF Database Description Packet */ +struct OspfDDpkt { + uchar intMTU[2]; + uchar options; + uchar bits; + uchar DDseqno[4]; + struct OspfLSAhdr hdr[1]; /* LSA headers... */ +}; + +char* +seprintospfdatadesc(char *p, char *e, void *a, int len) +{ + int nlsa, i; + struct OspfDDpkt *g; + + g = (struct OspfDDpkt *)a; + nlsa = len/sizeof(struct OspfLSAhdr); + for (i=0; ihdr[i])); + p = seprint(p, e, ")"); + } + return seprint(p, e, ")"); +} + +char* +seprintospflsupdate(char *p, char *e, void *a, int len) +{ + int nlsa, i; + struct OspfLSupdpkt *g; + struct OspfLSAhdr *h; + + g = (struct OspfLSupdpkt *)a; + nlsa = NetL(g->lsacnt); + h = (struct OspfLSAhdr *)(g->hdr); + p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsupdate)); + + switch(h->lstype) { + case LSARouter: + { +/* struct OspfrtLSA *h; + */ + } + break; + case LSANetwork: + { + struct OspfntLSA *h; + + for (i=0; int[i]); + p = seprint(p, e, "lsa%d(", i); + p = seprintospflsaheader(p, e, &(h->hdr)); + p = seprint(p, e, " mask %V attrt %V)", + h->netmask, h->attrt); + } + } + break; + case LSASummN: + case LSASummR: + { + struct OspfsummLSA *h; + + for (i=0; isum[i]); + p = seprint(p, e, "lsa%d(", i); + p = seprintospflsaheader(p, e, &(h->hdr)); + p = seprint(p, e, " mask %V met %d)", + h->netmask, Net3(h->lsa.metric)); + } + } + break; + case LSAASext: + { + struct OspfASextLSA *h; + + for (i=0; ias[i]); + p = seprint(p, e, " lsa%d(", i); + p = seprintospflsaheader(p, e, &(h->hdr)); + p = seprint(p, e, " mask %V extflg %1.1ux met %d fwdaddr %V extrtflg %ux)", + h->netmask, h->lsa.flag, Net3(h->lsa.metric), + h->lsa.fwdaddr, NetL(h->lsa.exrttag)); + } + } + break; + default: + p = seprint(p, e, "Not an LS update, lstype %d ", h->lstype); + p = seprint(p, e, " %.*H", len>64?64:len, a); + break; + } + return seprint(p, e, ")"); +} + +char* +seprintospflsack(char *p, char *e, void *a, int len) +{ + int nlsa, i; + struct OspfLSAhdr *h; + + h = (struct OspfLSAhdr *)a; + nlsa = len/sizeof(struct OspfLSAhdr); + p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsack)); + for (i=0; is); +} + +static int +p_filter(Filter *f, Msg *m) +{ + USED(f); + USED(m); + return 0; +} + +int +p_seprint(Msg *m) +{ + Ospfpkt *ospf; + int len, x; + char *p, *e; + + len = m->pe - m->ps; + if(len < OSPF_HDRSIZE) + return -1; + p = m->p; + e = m->e; + + /* adjust packet size */ + ospf = (Ospfpkt*)m->ps; + x = NetS(ospf->length); + if(x < len) + return -1; + x -= OSPF_HDRSIZE; + + p = seprint(p, e, "ver=%d type=%d len=%d r=%V a=%V c=%4.4ux %s ", + ospf->version, ospf->type, x, + ospf->router, ospf->area, NetS(ospf->sum), + ospfauth(ospf)); + + switch (ospf->type) { + case OSPFhello: + p = seprintospfhello(p, e, ospf->data, x); + break; + case OSPFdd: + p = seprintospfdatadesc(p, e, ospf->data, x); + break; + case OSPFlsrequest: + p = seprint(p, e, " %s->", ospfpkttype(ospf->type)); + goto Default; + case OSPFlsupdate: + p = seprintospflsupdate(p, e, ospf->data, x); + break; + case OSPFlsack: + p = seprintospflsack(p, e, ospf->data, x); + break; + default: +Default: + p = seprint(p, e, " data=%.*H", x>64?64:x, ospf->data); + } + m->p = p; + m->pr = nil; + return 0; +} + +Proto ospf = +{ + "ospf", + p_compile, + p_filter, + p_seprint, + nil, + nil, + defaultframer, +}; -- cgit v1.2.3