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

typedef struct Hdr	Hdr;
struct Hdr
{
	uchar	sport[2];
	uchar	dport[2];
	uchar	seq[4];
	uchar	ack[4];
	uchar	flag[2];
	uchar	win[2];
	uchar	cksum[2];
	uchar	urg[2];
	uchar	opt[1];
};

typedef struct PseudoHdr{
	uchar	src[4];
	uchar	dst[4];
	uchar	zero;
	uchar	proto;
	uchar	length[2];
	uchar	hdrdata[1580];
} PseudoHdr;

enum
{
	TCPLEN= 20
};

enum
{
	Os,
	Od,
	Osd
};

static Field p_fields[] = 
{
	{"s",		Fnum,	Os,	"source port",	} ,
	{"d",		Fnum,	Od,	"dest port",	} ,
	{"a",		Fnum,	Osd,	"source/dest port",	} ,
	{"sd",		Fnum,	Osd,	"source/dest port",	} ,
	{0}
};

static Mux p_mux[] =
{
	{"ninep",	17007, },	/* exportfs */
	{"ninep",	564, },		/* 9fs */
	{"ninep",	17005, },	/* ocpu */
	{"ninep",	17010, },	/* ncpu */
	{"ninep",	17013, },	/* cpu */
	{0}
};

enum
{
	EOLOPT		= 0,
	NOOPOPT		= 1,
	MSSOPT		= 2,
	MSS_LENGTH	= 4,		/* Mean segment size */
	WSOPT		= 3,
	WS_LENGTH	= 3,		/* Bits to scale window size by */
};

static void
p_compile(Filter *f)
{
	Mux *m;

	if(f->op == '='){
		compile_cmp(udp.name, f, p_fields);
		return;
	}
	for(m = p_mux; m->name != nil; m++)
		if(strcmp(f->s, m->name) == 0){
			f->pr = m->pr;
			f->ulv = m->val;
			f->subop = Osd;
			return;
		}
	sysfatal("unknown tcp field or protocol: %s", f->s);
}

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

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

	h = (Hdr*)m->ps;
	m->ps += ((NetS(h->flag)>>10)&0x3f);

	switch(f->subop){
	case Os:
		return NetS(h->sport) == f->ulv;
	case Od:
		return NetS(h->dport) == f->ulv;
	case Osd:
		return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv;
	}
	return 0;
}

enum
{
	URG		= 0x20,		/* Data marked urgent */
	ACK		= 0x10,		/* Aknowledge is valid */
	PSH		= 0x08,		/* Whole data pipe is pushed */
	RST		= 0x04,		/* Reset connection */
	SYN		= 0x02,		/* Pkt. is synchronise */
	FIN		= 0x01,		/* Start close down */
};

static char*
flags(int f)
{
	static char fl[20];
	char *p;

	p = fl;
	if(f & URG)
		*p++ = 'U';
	if(f & ACK)
		*p++ = 'A';
	if(f & PSH)
		*p++ = 'P';
	if(f & RST)
		*p++ = 'R';
	if(f & SYN)
		*p++ = 'S';
	if(f & FIN)
		*p++ = 'F';
	*p = 0;
	return fl;
}


static int
p_seprint(Msg *m)
{
	Hdr *h;
	int dport, sport;
	int len, flag, optlen;
	uchar *optr;

	if(m->pe - m->ps < TCPLEN)
		return -1;
	h = (Hdr*)m->ps;

	/* get tcp header length */
	flag = NetS(h->flag);
	len = (flag>>10)&~3;
	flag &= 0x3ff;
	m->ps += len;

	/* next protocol */
	dport = NetS(h->dport);
	sport = NetS(h->sport);
	demux(p_mux, sport, dport, m, &dump);

	m->p = seprint(m->p, m->e, "s=%d d=%d seq=%lud ack=%lud fl=%s win=%d ck=%4.4ux",
			NetS(h->sport), dport,
			(ulong)NetL(h->seq), (ulong)NetL(h->ack),
			flags(flag), NetS(h->win),
			NetS(h->cksum));

	/* tcp options */
	len -= TCPLEN;
	optr = h->opt;
	while(len > 0) {
		if(*optr == EOLOPT){
			m->p = seprint(m->p, m->e, " opt=EOL");
			break;
		}
		if(*optr == NOOPOPT) {
			m->p = seprint(m->p, m->e, " opt=NOOP");
			len--;
			optr++;
			continue;
		}
		optlen = optr[1];
		if(optlen < 2 || optlen > len)
			break;
		switch(*optr) {
		case MSSOPT:
			m->p = seprint(m->p, m->e, " opt%d=(mss %ud)", optlen, nhgets(optr+2));
			break;
		case WSOPT:
			m->p = seprint(m->p, m->e, " opt%d=(wscale %ud)", optlen, *(optr+2));
			break;
		default:
			m->p = seprint(m->p, m->e, " opt%d=(%ud %.*H)", optlen, *optr, optlen-2,optr+2);
		}
		len -= optlen;
		optr += optlen;
	}

	if(Cflag){
		/* editing in progress by ehg */
	}
	return 0;
}

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