#include <u.h>
#include <libc.h>
#include <ip.h>
#include "dat.h"
#include "protos.h"

typedef struct Hdr	Hdr;
struct Hdr
{	uchar	type;
	uchar	code;
	uchar	cksum[2];	/* Checksum */
	uchar	data[1];
};

enum
{
	ICMP6LEN=	4
};

enum
{
	Ot,	/* type */
	Op,	/* next protocol */};

static Field p_fields[] = 
{
	{"t",		Fnum,	Ot,	"type",	} ,
	{0}
};

enum
{	
	/* ICMPv6 types */
	EchoReply	= 0,
	UnreachableV6	= 1,
	PacketTooBigV6	= 2,
	TimeExceedV6	= 3,
	ParamProblemV6	= 4,
	Redirect	= 5,
	EchoRequest	= 8,
	TimeExceed	= 11,
	InParmProblem	= 12,
	Timestamp	= 13,
	TimestampReply	= 14,
	InfoRequest	= 15,
	InfoReply	= 16,
	AddrMaskRequest = 17,
	AddrMaskReply   = 18,
	EchoRequestV6	= 128,
	EchoReplyV6	= 129,
	RouterSolicit	= 133,
	RouterAdvert	= 134,
	NbrSolicit	= 135,
	NbrAdvert	= 136,
	RedirectV6	= 137,

	Maxtype6	= 137
};

static Mux p_mux[] =
{
	{"ip6",	UnreachableV6, },
	{"ip6",	RedirectV6, },
	{"ip6",	TimeExceedV6, },
	{0}
};

char *icmpmsg6[256] =
{
[EchoReply]		"EchoReply",
[UnreachableV6]		"UnreachableV6",
[PacketTooBigV6]	"PacketTooBigV6",
[TimeExceedV6]		"TimeExceedV6",
[Redirect]		"Redirect",
[EchoRequest]		"EchoRequest",
[TimeExceed]		"TimeExceed",
[InParmProblem]		"InParmProblem",
[Timestamp]		"Timestamp",
[TimestampReply]	"TimestampReply",
[InfoRequest]		"InfoRequest",
[InfoReply]		"InfoReply",
[AddrMaskRequest]	"AddrMaskRequest",
[AddrMaskReply]		"AddrMaskReply",
[EchoRequestV6]		"EchoRequestV6",
[EchoReplyV6]		"EchoReplyV6",
[RouterSolicit]		"RouterSolicit",
[RouterAdvert]		"RouterAdvert",
[NbrSolicit]		"NbrSolicit",
[NbrAdvert]		"NbrAdvert",
[RedirectV6]		"RedirectV6"
};

static char *unreachcode[] =
{
[0]	"no route to destination",
[1]	"comm with destination administratively prohibited",
[2]	"icmp unreachable: unassigned error code (2)",
[3]	"address unreachable",
[4]	"port unreachable",
[5]	"icmp unreachable: unknown code"
};

static char *timexcode[] =
{
[0]	"hop limit exc",
[1]	"reassmbl time exc",
[2]	"icmp time exc: unknown code"
};

static char *parpcode[] =
{
[0]	"erroneous header field encountered",
[1]	"unrecognized Next Header type encountered",
[2]	"unrecognized IPv6 option encountered",
[3]	"icmp par prob: unknown code"
};
enum 
{
	sll	= 1,
	tll	= 2,
	pref	= 3,
	redir	= 4,
	mtu	= 5
};

static char *icmp6opts[256] = 
{
[0]	"unknown opt",
[1]	"sll_addr",
[2]	"tll_addr",
[3]	"pref_opt",
[4]	"redirect",
[5]	"mtu_opt"
};

static void
p_compile(Filter *f)
{
	if(f->op == '='){
		compile_cmp(icmp6.name, f, p_fields);
		return;
	}
	if(strcmp(f->s, "ip6") == 0){
		f->pr = p_mux->pr;
		f->subop = Op;
		return;
	}
	sysfatal("unknown icmp field or protocol: %s", f->s);
}

static int
p_filter(Filter *f, Msg *m)
{
	Hdr *h;

	if(m->pe - m->ps < ICMP6LEN)
		return 0;

	h = (Hdr*)m->ps;
	m->ps += ICMP6LEN;

	switch(f->subop){

	case Ot:
		if(h->type == f->ulv)
			return 1;
		break;
	case Op:
		switch(h->type){
		case UnreachableV6:
		case RedirectV6:
		case TimeExceedV6:
			m->ps += 4;
			return 1;
		}
	}
	return 0;
}

static char*
opt_seprint(Msg *m)
{
	int otype, osz, pktsz;
	uchar *a;
	char *p = m->p;
	char *e = m->e;
	char *opt;
	char optbuf[12];

	pktsz = m->pe - m->ps;
	a = m->ps;
	while (pktsz > 0) {
		otype = *a;
		opt = icmp6opts[otype];
		if(opt == nil){
			sprint(optbuf, "0x%ux", otype);
			opt = optbuf;
		}
		osz = (*(a+1)) * 8;

		switch (otype) {
		default:
			p = seprint(p, e, "\n	  option=%s ", opt);
			m->pr = &dump;
			return p;

		case sll:
		case tll:
			if ((pktsz < osz) || (osz != 8)) { 
				p = seprint(p, e, "\n	  option=%s bad size=%d", opt, osz);
				m->pr = &dump;
				return p;
			}
			p = seprint(p, e, "\n	  option=%s maddr=%E", opt, a+2);
			pktsz -= osz;
			a += osz;
			break;

		case pref:
			if ((pktsz < osz) || (osz != 32)) { 
				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);
				m->pr = &dump;
				return p;
			}

			p = seprint(p, e, "\n	  option=%s pref=%I preflen=%3.3d lflag=%1.1d aflag=%1.1d unused1=%1.1d validlt=%d preflt=%d unused2=%1.1d",
				opt,
				a+16,
				(int) (*(a+2)),
				(*(a+3) & (1 << 7))!=0,
				(*(a+3) & (1 << 6))!=0,
				(*(a+3) & 63) != 0,
				NetL(a+4),
				NetL(a+8),
				NetL(a+12)!=0);

			pktsz -= osz;
			a += osz;			
			break;

		case redir:
			if (pktsz < osz) { 
				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);
				m->pr = &dump;
				return p;
			}

			p = seprint(p, e, "\n	  option=%s len %d", opt, osz);
			a += osz;
			m->ps = a;
			return p;			
			break;

		case mtu:
			if ((pktsz < osz) || (osz != 8)) { 
				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);
				m->pr = &dump;
				return p;
			}

			p = seprint(p, e, "\n	  option=%s unused=%1.1d mtu=%d", opt, NetL(a+2)!=0, NetL(a+4));
			pktsz -= osz;
			a += osz;
			break;
		}
	}

	m->ps = a;
	return p;
}

static int
p_seprint(Msg *m)
{
	Hdr *h;
	char *tn;
	char *p = m->p;
	char *e = m->e;
	int i;
	uchar *a;
/*	ushort cksum2, cksum; */

	h = (Hdr*)m->ps;
	m->ps += ICMP6LEN;
	m->pr = &dump;
	a = m->ps;

	if(m->pe - m->ps < ICMP6LEN)
		return -1;

	tn = icmpmsg6[h->type];
	if(tn == nil)
		p = seprint(p, e, "t=%ud c=%d ck=%4.4ux", h->type,
			h->code, (ushort)NetS(h->cksum));
	else
		p = seprint(p, e, "t=%s c=%d ck=%4.4ux", tn,
			h->code, (ushort)NetS(h->cksum));

	/*
	if(Cflag){
		cksum = NetS(h->cksum);
		h->cksum[0] = 0;
		h->cksum[1] = 0;
		cksum2 = ~ptclbsum((uchar*)h, m->pe - m->ps + ICMP6LEN) & 0xffff;
		if(cksum != cksum2)
			p = seprint(p,e, " !ck=%4.4ux", cksum2);
	}
	*/

	switch(h->type){

	case UnreachableV6:
		m->ps += 4;
		m->pr = &ip6;
		if (h->code >= nelem(unreachcode))
			i = nelem(unreachcode)-1;
		else
			i = h->code;
		p = seprint(p, e, " code=%s unused=%1.1d ", unreachcode[i], NetL(a)!=0);
		break;

	case PacketTooBigV6:
		m->ps += 4;
		m->pr = &ip6;
		p = seprint(p, e, " mtu=%4.4d ", NetL(a));
		break;

	case TimeExceedV6:
		m->ps += 4;
		m->pr = &ip6;
		if (h->code >= nelem(timexcode))
			i = nelem(timexcode)-1;
		else
			i = h->code;
		p = seprint(p, e, " code=%s unused=%1.1d ", timexcode[i], NetL(a)!=0);
		break;

	case ParamProblemV6:
		m->ps += 4;
		m->pr = &ip6;
		if (h->code > nelem(parpcode))
			i = nelem(parpcode)-1;
		else
			i = h->code;
		p = seprint(p, e, " code=%s ptr=%2.2ux", parpcode[i], h->data[0]);
		break;

	case EchoReplyV6:
	case EchoRequestV6:
		m->ps += 4;
		p = seprint(p, e, " id=%ux seq=%ux",
			NetS(h->data), NetS(h->data+2));
		break;

	case RouterSolicit:
		m->ps += 4;
		m->pr = nil;
		m->p = seprint(p, e, " unused=%1.1d ", NetL(a)!=0);
		p = opt_seprint(m);
		break;

	case RouterAdvert:
		m->ps += 12;
		m->pr = nil;
		m->p = seprint(p, e, " hoplim=%3.3d mflag=%1.1d oflag=%1.1d unused=%1.1d routerlt=%8.8d reachtime=%d rxmtimer=%d",
			(int) *a,
			(*(a+1) & (1 << 7)) != 0,
			(*(a+1) & (1 << 6)) != 0,
			(*(a+1) & 63) != 0,
			NetS(a+2),
			NetL(a+4),
			NetL(a+8));
		p = opt_seprint(m);
		break;

	case NbrSolicit:
		m->ps += 20;
		m->pr = nil;
		m->p = seprint(p, e, " unused=%1.1d targ %I", NetL(a)!=0, a+4);
		p = opt_seprint(m);
		break;

	case NbrAdvert:
		m->ps += 20;
		m->pr = nil;
		m->p = seprint(p, e, " rflag=%1.1d sflag=%1.1d oflag=%1.1d targ=%I",
			(*a & (1 << 7)) != 0,
			(*a & (1 << 6)) != 0,
			(*a & (1 << 5)) != 0,
			a+4);
		p = opt_seprint(m);
		break;

	case RedirectV6:
		m->ps += 36;
		m->pr = &ip6;
		m->p = seprint(p, e, " unused=%1.1d targ=%I dest=%I", NetL(a)!=0, a+4, a+20);
		p = opt_seprint(m);
		break;

	case Timestamp:
	case TimestampReply:
		m->ps += 12;
		p = seprint(p, e, " orig=%ud rcv=%ux xmt=%ux",
			NetL(h->data), NetL(h->data+4),
			NetL(h->data+8));
		m->pr = nil;
		break;

	case InfoRequest:
	case InfoReply:
		break;

	}
	m->p = p;
	return 0;
}

Proto icmp6 =
{
	"icmp6",
	p_compile,
	p_filter,
	p_seprint,
	p_mux,
	"%lud",
	p_fields,
	defaultframer
};
