📄 ospf.c
字号:
#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, ")");}intp_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,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -