#include <u.h>
#include <libc.h>
#include <ip.h>
#include "dat.h"
#include "protos.h"
typedef struct Hdr Hdr;
struct Hdr {
uchar verstype;
uchar code;
uchar sessid[2];
uchar length[2]; /* of payload */
};
enum
{
HDRSIZE = 1+1+2+2
};
static Mux p_mux[] =
{
{"ppp", 0, } ,
{0}
};
enum
{
Overs,
Otype,
Ocode,
Osess,
};
static Field p_fields[] =
{
{"v", Fnum, Overs, "version", } ,
{"t", Fnum, Otype, "type", } ,
{"c", Fnum, Ocode, "code" } ,
{"s", Fnum, Osess, "sessid" } ,
{0}
};
static void
p_compilesess(Filter *f)
{
// Mux *m;
if(f->op == '='){
compile_cmp(pppoe_sess.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 = Ot;
return;
}
*/
sysfatal("unknown pppoe field or protocol: %s", f->s);
}
static void
p_compiledisc(Filter *f)
{
// Mux *m;
if(f->op == '='){
compile_cmp(pppoe_disc.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 = Ot;
return;
}
*/
sysfatal("unknown pppoe field or protocol: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
Hdr *h;
if(m->pe - m->ps < HDRSIZE)
return 0;
h = (Hdr*)m->ps;
m->ps += HDRSIZE;
switch(f->subop){
case Overs:
return (h->verstype>>4) == f->ulv;
case Otype:
return (h->verstype&0xF) == f->ulv;
case Ocode:
return h->code == f->ulv;
case Osess:
return NetS(h->sessid) == f->ulv;
}
return 0;
}
/* BUG: print all the discovery types */
static int
p_seprintdisc(Msg *m)
{
Hdr *h;
int len;
len = m->pe - m->ps;
if(len < HDRSIZE)
return -1;
h = (Hdr*)m->ps;
m->ps += HDRSIZE;
m->pr = nil;
m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
return 0;
}
static int
p_seprintsess(Msg *m)
{
Hdr *h;
int len;
len = m->pe - m->ps;
if(len < HDRSIZE)
return -1;
h = (Hdr*)m->ps;
m->ps += HDRSIZE;
/* this will call ppp for me */
demux(p_mux, 0, 0, m, &dump);
m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
return 0;
}
Proto pppoe_disc =
{
"pppoe_disc",
p_compiledisc,
p_filter,
p_seprintdisc,
p_mux,
"%lud",
p_fields,
defaultframer
};
Proto pppoe_sess =
{
"pppoe_sess",
p_compilesess,
p_filter,
p_seprintsess,
p_mux,
"%lud",
p_fields,
defaultframer
};
|