123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- #include <u.h>
- #include <libc.h>
- #include <ip.h>
- #include <libsec.h>
- #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)
- {
- Ospfhello *h = a;
- 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; i<nlsa; i++) {
- p = seprint(p, e, "lsa%d(", i);
- p = seprintospflsaheader(p, e, &(g->hdr[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; i<nlsa; i++) {
- h = &(g->nt[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; i<nlsa; i++) {
- h = &(g->sum[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; i<nlsa; i++) {
- h = &(g->as[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; i<nlsa; i++) {
- p = seprint(p, e, " lsa%d(", i);
- p = seprintospflsaheader(p, e, &(h[i]));
- p = seprint(p, e, ")");
- }
- return seprint(p, e, ")");
- }
- 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);
- 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",
- nil,
- nil,
- p_seprint,
- nil,
- nil,
- nil,
- defaultframer,
- };
|