#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,
};
