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