URI:
       tospf.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tospf.c (7359B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <ip.h>
            4 #include <libsec.h>
            5 #include "dat.h"
            6 #include "protos.h"
            7 
            8 
            9 /*
           10  *  OSPF packets
           11  */
           12 typedef struct Ospfpkt        Ospfpkt;
           13 struct Ospfpkt
           14 {
           15         uchar        version;
           16         uchar        type;
           17         uchar        length[2];
           18         uchar        router[4];
           19         uchar        area[4];
           20         uchar        sum[2];
           21         uchar        autype[2];
           22         uchar        auth[8];
           23         uchar        data[1];
           24 };
           25 #define OSPF_HDRSIZE        24
           26 
           27 enum
           28 {
           29         OSPFhello=        1,
           30         OSPFdd=                2,
           31         OSPFlsrequest=        3,
           32         OSPFlsupdate=        4,
           33         OSPFlsack=        5
           34 };
           35 
           36 
           37 char *ospftype[] = {
           38         [OSPFhello]        "hello",
           39         [OSPFdd]        "data definition",
           40         [OSPFlsrequest]        "link state request",
           41         [OSPFlsupdate]        "link state update",
           42         [OSPFlsack]        "link state ack"
           43 };
           44 
           45 char*
           46 ospfpkttype(int x)
           47 {
           48         static char type[16];
           49 
           50         if(x > 0 && x <= OSPFlsack)
           51                 return ospftype[x];
           52         sprint(type, "type %d", x);
           53         return type;
           54 }
           55 
           56 char*
           57 ospfauth(Ospfpkt *ospf)
           58 {
           59         static char auth[100];
           60 
           61         switch(ospf->type){
           62         case 0:
           63                 return "no authentication";
           64         case 1:
           65                 sprint(auth, "password(%8.8ux %8.8ux)", NetL(ospf->auth),
           66                         NetL(ospf->auth+4));
           67                 break;
           68         case 2:
           69                 sprint(auth, "crypto(plen %d id %d dlen %d)", NetS(ospf->auth),
           70                         ospf->auth[2], ospf->auth[3]);
           71                 break;
           72         default:
           73                 sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype), NetL(ospf->auth),
           74                         NetL(ospf->auth+4));
           75         }
           76         return auth;
           77 }
           78 
           79 typedef struct Ospfhello        Ospfhello;
           80 struct Ospfhello
           81 {
           82         uchar        mask[4];
           83         uchar        interval[2];
           84         uchar        options;
           85         uchar        pri;
           86         uchar        deadint[4];
           87         uchar        designated[4];
           88         uchar        bdesignated[4];
           89         uchar        neighbor[1];
           90 };
           91 
           92 char*
           93 seprintospfhello(char *p, char *e, void *a)
           94 {
           95         Ospfhello *h = a;
           96 
           97         return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)",
           98                 ospftype[OSPFhello],
           99                 h->mask, NetS(h->interval), h->options, h->pri,
          100                 NetL(h->deadint), h->designated, h->bdesignated);
          101 }
          102 
          103 enum
          104 {
          105         LSARouter=        1,
          106         LSANetwork=        2,
          107         LSASummN=        3,
          108         LSASummR=        4,
          109         LSAASext=        5
          110 };
          111 
          112 
          113 char *lsatype[] = {
          114         [LSARouter]        "Router LSA",
          115         [LSANetwork]        "Network LSA",
          116         [LSASummN]        "Summary LSA (Network)",
          117         [LSASummR]        "Summary LSA (Router)",
          118         [LSAASext]        "LSA AS external"
          119 };
          120 
          121 char*
          122 lsapkttype(int x)
          123 {
          124         static char type[16];
          125 
          126         if(x > 0 && x <= LSAASext)
          127                 return lsatype[x];
          128         sprint(type, "type %d", x);
          129         return type;
          130 }
          131 
          132 /* OSPF Link State Advertisement Header */
          133 /* rfc2178 section 12.1 */
          134 /* data of Ospfpkt point to a 4-uchar value that is the # of LSAs */
          135 struct OspfLSAhdr {
          136         uchar        lsage[2];
          137         uchar        options;        /* 0x2=stub area, 0x1=TOS routing capable */
          138 
          139         uchar        lstype;        /* 1=Router-LSAs
          140                                                  * 2=Network-LSAs
          141                                                  * 3=Summary-LSAs (to network)
          142                                                  * 4=Summary-LSAs (to AS boundary routers)
          143                                                  * 5=AS-External-LSAs
          144                                                  */
          145         uchar        lsid[4];
          146         uchar        advtrt[4];
          147 
          148         uchar        lsseqno[4];
          149         uchar        lscksum[2];
          150         uchar        lsalen[2];        /* includes the 20 byte lsa header */
          151 };
          152 
          153 struct Ospfrt {
          154         uchar        linkid[4];
          155         uchar        linkdata[4];
          156         uchar        typ;
          157         uchar        numtos;
          158         uchar        metric[2];
          159 
          160 };
          161 
          162 struct OspfrtLSA {
          163         struct OspfLSAhdr        hdr;
          164         uchar                        netmask[4];
          165 };
          166 
          167 struct OspfntLSA {
          168         struct OspfLSAhdr        hdr;
          169         uchar                        netmask[4];
          170         uchar                        attrt[4];
          171 };
          172 
          173 /* Summary Link State Advertisement info */
          174 struct Ospfsumm {
          175         uchar        flag;        /* always zero */
          176         uchar        metric[3];
          177 };
          178 
          179 struct OspfsummLSA {
          180         struct OspfLSAhdr        hdr;
          181         uchar                        netmask[4];
          182         struct Ospfsumm                lsa;
          183 };
          184 
          185 /* AS external Link State Advertisement info */
          186 struct OspfASext {
          187         uchar        flag;        /* external */
          188         uchar        metric[3];
          189         uchar        fwdaddr[4];
          190         uchar        exrttag[4];
          191 };
          192 
          193 struct OspfASextLSA {
          194         struct OspfLSAhdr        hdr;
          195         uchar                        netmask[4];
          196         struct OspfASext        lsa;
          197 };
          198 
          199 /* OSPF Link State Update Packet */
          200 struct OspfLSupdpkt {
          201         uchar        lsacnt[4];
          202         union {
          203                 uchar                        hdr[1];
          204                 struct OspfrtLSA        rt[1];
          205                 struct OspfntLSA        nt[1];
          206                 struct OspfsummLSA        sum[1];
          207                 struct OspfASextLSA        as[1];
          208         };
          209 };
          210 
          211 char*
          212 seprintospflsaheader(char *p, char *e, struct OspfLSAhdr *h)
          213 {
          214         return seprint(p, e, "age %d opt %ux type %ux lsid %V adv_rt %V seqno %ux c %4.4ux l %d",
          215                 NetS(h->lsage), h->options&0xff, h->lstype,
          216                 h->lsid, h->advtrt, NetL(h->lsseqno), NetS(h->lscksum),
          217                 NetS(h->lsalen));
          218 }
          219 
          220 /* OSPF Database Description Packet */
          221 struct OspfDDpkt {
          222         uchar        intMTU[2];
          223         uchar        options;
          224         uchar        bits;
          225         uchar        DDseqno[4];
          226         struct OspfLSAhdr        hdr[1];                /* LSA headers... */
          227 };
          228 
          229 char*
          230 seprintospfdatadesc(char *p, char *e, void *a, int len)
          231 {
          232         int nlsa, i;
          233         struct OspfDDpkt *g;
          234 
          235         g = (struct OspfDDpkt *)a;
          236         nlsa = len/sizeof(struct OspfLSAhdr);
          237         for (i=0; i<nlsa; i++) {
          238                 p = seprint(p, e, "lsa%d(", i);
          239                 p = seprintospflsaheader(p, e, &(g->hdr[i]));
          240                 p = seprint(p, e, ")");
          241         }
          242         return seprint(p, e, ")");
          243 }
          244 
          245 char*
          246 seprintospflsupdate(char *p, char *e, void *a, int len)
          247 {
          248         int nlsa, i;
          249         struct OspfLSupdpkt *g;
          250         struct OspfLSAhdr *h;
          251 
          252         g = (struct OspfLSupdpkt *)a;
          253         nlsa = NetL(g->lsacnt);
          254         h = (struct OspfLSAhdr *)(g->hdr);
          255         p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsupdate));
          256 
          257         switch(h->lstype) {
          258         case LSARouter:
          259                 {
          260 /*                        struct OspfrtLSA *h;
          261  */
          262                 }
          263                 break;
          264         case LSANetwork:
          265                 {
          266                         struct OspfntLSA *h;
          267 
          268                         for (i=0; i<nlsa; i++) {
          269                                 h = &(g->nt[i]);
          270                                 p = seprint(p, e, "lsa%d(", i);
          271                                 p = seprintospflsaheader(p, e, &(h->hdr));
          272                                 p = seprint(p, e, " mask %V attrt %V)",
          273                                         h->netmask, h->attrt);
          274                         }
          275                 }
          276                 break;
          277         case LSASummN:
          278         case LSASummR:
          279                 {
          280                         struct OspfsummLSA *h;
          281 
          282                         for (i=0; i<nlsa; i++) {
          283                                 h = &(g->sum[i]);
          284                                 p = seprint(p, e, "lsa%d(", i);
          285                                 p = seprintospflsaheader(p, e, &(h->hdr));
          286                                 p = seprint(p, e, " mask %V met %d)",
          287                                         h->netmask, Net3(h->lsa.metric));
          288                         }
          289                 }
          290                 break;
          291         case LSAASext:
          292                 {
          293                         struct OspfASextLSA *h;
          294 
          295                         for (i=0; i<nlsa; i++) {
          296                                 h = &(g->as[i]);
          297                                 p = seprint(p, e, " lsa%d(", i);
          298                                 p = seprintospflsaheader(p, e, &(h->hdr));
          299                                 p = seprint(p, e, " mask %V extflg %1.1ux met %d fwdaddr %V extrtflg %ux)",
          300                                         h->netmask, h->lsa.flag, Net3(h->lsa.metric),
          301                                         h->lsa.fwdaddr, NetL(h->lsa.exrttag));
          302                         }
          303                 }
          304                 break;
          305         default:
          306                 p = seprint(p, e, "Not an LS update, lstype %d ", h->lstype);
          307                 p = seprint(p, e, " %.*H", len>64?64:len, a);
          308                 break;
          309         }
          310         return seprint(p, e, ")");
          311 }
          312 
          313 char*
          314 seprintospflsack(char *p, char *e, void *a, int len)
          315 {
          316         int nlsa, i;
          317         struct OspfLSAhdr *h;
          318 
          319         h = (struct OspfLSAhdr *)a;
          320         nlsa = len/sizeof(struct OspfLSAhdr);
          321         p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsack));
          322         for (i=0; i<nlsa; i++) {
          323                 p = seprint(p, e, " lsa%d(", i);
          324                 p = seprintospflsaheader(p, e, &(h[i]));
          325                 p = seprint(p, e, ")");
          326         }
          327         return seprint(p, e, ")");
          328 }
          329 
          330 int
          331 p_seprint(Msg *m)
          332 {
          333         Ospfpkt *ospf;
          334         int len, x;
          335         char *p, *e;
          336 
          337         len = m->pe - m->ps;
          338         if(len < OSPF_HDRSIZE)
          339                 return -1;
          340         p = m->p;
          341         e = m->e;
          342 
          343         /* adjust packet size */
          344         ospf = (Ospfpkt*)m->ps;
          345         x = NetS(ospf->length);
          346         if(x < len)
          347                 return -1;
          348         x -= OSPF_HDRSIZE;
          349 
          350         p = seprint(p, e, "ver=%d type=%d len=%d r=%V a=%V c=%4.4ux %s ",
          351                 ospf->version, ospf->type, x,
          352                 ospf->router, ospf->area, NetS(ospf->sum),
          353                 ospfauth(ospf));
          354 
          355         switch (ospf->type) {
          356         case OSPFhello:
          357                 p = seprintospfhello(p, e, ospf->data);
          358                 break;
          359         case OSPFdd:
          360                 p = seprintospfdatadesc(p, e, ospf->data, x);
          361                 break;
          362         case OSPFlsrequest:
          363                 p = seprint(p, e, " %s->", ospfpkttype(ospf->type));
          364                 goto Default;
          365         case OSPFlsupdate:
          366                 p = seprintospflsupdate(p, e, ospf->data, x);
          367                 break;
          368         case OSPFlsack:
          369                 p = seprintospflsack(p, e, ospf->data, x);
          370                 break;
          371         default:
          372 Default:
          373                 p = seprint(p, e, " data=%.*H", x>64?64:x, ospf->data);
          374         }
          375         m->p = p;
          376         m->pr = nil;
          377         return 0;
          378 }
          379 
          380 Proto ospf =
          381 {
          382         "ospf",
          383         nil,
          384         nil,
          385         p_seprint,
          386         nil,
          387         nil,
          388         nil,
          389         defaultframer
          390 };