/* 
 * IEEE 802.11.
 */

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

enum
{
	Tmgmt = 0,
	Tctl,
	Tdata,

	CtlPoll = 0xA,
	CtlRts,
	CtlCts,
	CtlAck,
	CtlCfEnd,
	CtlCfEndAck,

	Data = 0,
	DataCfAck,
	DataCfPoll,
	DataCfAckPoll,
	Nodata,
	NodataCfAck,
	NodataCfPoll,
	NodataCfAckPoll,
	
	FlagTods = 0x1,
	FlagFromds = 0x2,
	FlagMoreflag = 0x4,
	FlagRetry = 0x8,
	FlagPowerMgmt = 0x10,
	FlagMoreData = 0x20,
	FlagWep = 0x40,
	FlagOrder = 0x80,
	
	ProtoNone = 0,
	ProtoLlc,
};

static Mux p_mux[] =
{
	{ "llc", ProtoLlc },
	{ 0 }
};

typedef struct Hdr Hdr;
struct Hdr
{
	uchar vers;
	uchar type;
	uchar subtype;
	uchar flags;
	ushort dur;
	uchar aid;
	uchar ra[6];
	uchar ta[6];
	uchar bssid[6];
	uchar sa[6];
	uchar da[6];
	ushort seq;
	int proto;
	int hdrlen;
};

static int
unpackhdr(uchar *p, uchar *ep, Hdr *h)
{
	if(p+2 > ep)
		return -1;
	h->vers = p[0]&3;
	if(h->vers != 0){
		h->hdrlen = 2;
		return -1;
	}
	h->type = (p[0]>>2)&3;
	h->subtype = (p[0]>>4)&15;
	h->flags = p[1];
	h->hdrlen = 2;

	if(h->vers != 0)
		return 0;
	
	switch(h->type){
	case Tmgmt:
		// fc dur da sa bssid seq
		if(p+2+2+6+6+6+2 > ep)
			return -1;
		h->hdrlen = 24;
		h->dur = LittleS(p+2);
		memmove(h->da, p+4, 6);
		memmove(h->sa, p+10, 6);
		memmove(h->bssid, p+16, 6);
		h->seq = LittleS(p+22);
		break;
	
	case Tctl:
		switch(h->subtype){
		case CtlPoll:
			// fc aid bssid ta
			if(p+2+2+6+6 > ep)
				return -1;
			h->hdrlen = 16;
			h->aid = LittleS(p+2);
			memmove(h->bssid, p+4, 6);
			memmove(h->ta, p+10, 6);
			break;
		
		case CtlRts:
			// fc dur ra ta
			if(p+2+2+6+6 > ep)
				return -1;
			h->hdrlen = 16;
			h->dur = LittleS(p+2);
			memmove(h->ra, p+4, 6);
			memmove(h->ta, p+10, 6);
			break;
		
		case CtlCts:
		case CtlAck:
			// fc dur ra
			if(p+2+2+6 > ep)
				return -1;
			h->hdrlen = 10;
			h->dur = LittleS(p+2);
			memmove(h->ra, p+4, 6);
			break;
		
		case CtlCfEnd:
		case CtlCfEndAck:
			// fc dur ra bssid
			if(p+2+2+6+6 > ep)
				return -1;
			h->hdrlen = 16;
			h->dur = LittleS(p+2);
			memmove(h->ra, p+4, 6);
			memmove(h->bssid, p+10, 6);
			break;
		}
		break;
	
	case Tdata:
		if(p+24 > ep)
			return -1;
		h->hdrlen = 24;
		h->dur = LittleS(p+2);	// ??? maybe
		// Also, what is at p+22?

		switch(h->flags&(FlagFromds|FlagTods)){
		case 0:
			memmove(h->da, p+4, 6);
			memmove(h->sa, p+10, 6);
			memmove(h->bssid, p+16, 6);
			break;
		case FlagFromds:
			memmove(h->da, p+4, 6);
			memmove(h->bssid, p+10, 6);
			memmove(h->sa, p+16, 6);
			break;
		case FlagTods:
			memmove(h->bssid, p+4, 6);
			memmove(h->sa, p+10, 6);
			memmove(h->da, p+16, 6);
			break;
		case FlagFromds|FlagTods:
			if(p+30 > ep)
				return -1;
			h->hdrlen = 30;
			memmove(h->ra, p+4, 6);
			memmove(h->ta, p+10, 6);
			memmove(h->da, p+16, 6);
			memmove(h->sa, p+24, 6);	// 24 sic
			break;
		}
		p += h->hdrlen;
		h->proto = ProtoNone;
		if(!(h->flags&FlagWep))
			h->proto = ProtoLlc;
		break;
	}
	return 0;	
}

enum
{
	Os,
	Od,
	Ot,
	Or,
	Obssid,
	Oa,
	Opr,
};

static Field p_fields[] =
{
	{ "s",	Fether,	Os,	"source address" },
	{ "d",	Fether,	Od,	"destination address" },
	{ "t",	Fether,	Ot,	"transmit address" },
	{ "r",	Fether,	Or,	"receive address" },
	{ "bssid", Fether,	Obssid, "bssid address" },
	{ "a",	Fether,	Oa,	"any address" },
	{ "sd",	Fether,	Oa,	"source|destination address" },
	{ 0 }
};

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

	if(f->op == '='){
		compile_cmp(p80211.name, f, p_fields);
		return;
	}
	if(strcmp(f->s, "mgmt") == 0){
		f->pr = &p80211;
		f->ulv = Tmgmt;
		f->subop = Ot;
		return;
	}
	if(strcmp(f->s, "ctl") == 0){
		f->pr = &p80211;
		f->ulv = Tctl;
		f->subop = Ot;
		return;
	}
	if(strcmp(f->s, "data") == 0){
		f->pr = &p80211;
		f->ulv = Tdata;
		f->subop = Ot;
		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 = Opr;
			return;
		}
	}
	sysfatal("unknown 802.11 field or protocol: %s", f->s);
}

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

	memset(&h, 0, sizeof h);
	if(unpackhdr(m->ps, m->pe, &h) < 0)
		return 0;
	m->ps += h.hdrlen;

	switch(f->subop){
	case Os:
		return memcmp(h.sa, f->a, 6) == 0;
	case Od:
		return memcmp(h.da, f->a, 6) == 0;
	case Ot:
		return memcmp(h.ta, f->a, 6) == 0;
	case Or:
		return memcmp(h.ra, f->a, 6) == 0;
	case Obssid:
		return memcmp(h.bssid, f->a, 6) == 0;
	case Oa:
		return memcmp(h.sa, f->a, 6) == 0
			|| memcmp(h.da, f->a, 6) == 0
			|| memcmp(h.ta, f->a, 6) == 0
			|| memcmp(h.ra, f->a, 6) == 0
			|| memcmp(h.bssid, f->a, 6) == 0;
	case Opr:
		return h.proto == f->ulv;
	}
	return 0;
}

static int
p_seprint(Msg *m)
{
	Hdr h;
	
	memset(&h, 0, sizeof h);
	if(unpackhdr(m->ps, m->pe, &h) < 0)
		return -1;

	m->pr = &dump;
	m->p = seprint(m->p, m->e, "fc=%02x flags=%02x ", m->ps[0], m->ps[1]);
	switch(h.type){
	case Tmgmt:
		m->p = seprint(m->p, m->e, "mgmt dur=%d d=%E s=%E bssid=%E seq=%d",
			h.dur, h.da, h.sa, h.bssid, h.seq);
		break;
	case Tctl:
		switch(h.subtype){
		case CtlPoll:
			m->p = seprint(m->p, m->e, "ctl poll aid=%d bssid=%E t=%E",
				h.aid, h.bssid, h.ta);
			break;
		case CtlRts:
			m->p = seprint(m->p, m->e, "ctl rts dur=%d r=%E t=%E",
				h.dur, h.ra, h.ta);
			break;
		case CtlCts:
			m->p = seprint(m->p, m->e, "ctl cts dur=%d r=%E",
				h.dur, h.ra);
			break;
		case CtlAck:
			m->p = seprint(m->p, m->e, "ctl ack dur=%d r=%E",
				h.dur, h.ra);
			break;
		case CtlCfEnd:
			m->p = seprint(m->p, m->e, "ctl cf end dur=%d r=%E bssid=%E",
				h.dur, h.ra, h.bssid);
			break;
		case CtlCfEndAck:
			m->p = seprint(m->p, m->e, "ctl cf end ack dur=%d r=%E bssid=%E",
				h.dur, h.ra, h.bssid);
			break;
		default:
			m->p = seprint(m->p, m->e, "ctl %.*H", m->ps, h.hdrlen);
			break;
		}
		break;
	case Tdata:
		switch(h.flags&(FlagFromds|FlagTods)){
		case 0:
			m->p = seprint(m->p, m->e, "data d=%E s=%E bssid=%E",
				h.da, h.sa, h.bssid);
			break;
		case FlagFromds:
			m->p = seprint(m->p, m->e, "data fds d=%E bssid=%E s=%E",
				h.da, h.bssid, h.sa);
			break;
		case FlagTods:
			m->p = seprint(m->p, m->e, "data tds bssid=%E s=%E d=%E",
				h.bssid, h.sa, h.da);
			break;
		case FlagFromds|FlagTods:
			m->p = seprint(m->p, m->e, "data fds tds r=%E t=%E d=%E s=%E",
				h.ra, h.ta, h.da, h.sa);
			break;
		}
		if(!(h.flags&FlagWep))
			m->pr = &llc;
		break;
	}
	m->ps += h.hdrlen;
	return 0;
}

Proto p80211 =
{
	"802.11",
	p_compile,
	p_filter,
	p_seprint,
	p_mux,
	nil,
	nil,
	defaultframer
};
