aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/snoopy/ospf.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-12-26 04:48:52 +0000
committerrsc <devnull@localhost>2005-12-26 04:48:52 +0000
commit87a52e0485d3281ebea6bf4b725aa8023690e96f (patch)
tree0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/snoopy/ospf.c
parent35d26aa32167e84326cdb745c0e906393b8de71d (diff)
downloadplan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.bz2
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip
new goodies
Diffstat (limited to 'src/cmd/ip/snoopy/ospf.c')
-rwxr-xr-xsrc/cmd/ip/snoopy/ospf.c404
1 files changed, 404 insertions, 0 deletions
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 <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, 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; 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, ")");
+}
+
+static void
+p_compile(Filter *f)
+{
+ sysfatal("unknown ospf field: %s", f->s);
+}
+
+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,
+};