From 87a52e0485d3281ebea6bf4b725aa8023690e96f Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 26 Dec 2005 04:48:52 +0000 Subject: new goodies --- src/cmd/ip/snoopy/pppoe_disc.c | 172 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100755 src/cmd/ip/snoopy/pppoe_disc.c (limited to 'src/cmd/ip/snoopy/pppoe_disc.c') diff --git a/src/cmd/ip/snoopy/pppoe_disc.c b/src/cmd/ip/snoopy/pppoe_disc.c new file mode 100755 index 00000000..4f17ebd7 --- /dev/null +++ b/src/cmd/ip/snoopy/pppoe_disc.c @@ -0,0 +1,172 @@ +#include +#include +#include +#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, + p_fields, + defaultframer +}; + +Proto pppoe_sess = +{ + "pppoe_sess", + p_compilesess, + p_filter, + p_seprintsess, + p_mux, + p_fields, + defaultframer +}; + -- cgit v1.2.3