/* 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 */
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;
}