aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/snoopy/pppoe_disc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ip/snoopy/pppoe_disc.c')
-rwxr-xr-xsrc/cmd/ip/snoopy/pppoe_disc.c172
1 files changed, 172 insertions, 0 deletions
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 <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,
+ p_fields,
+ defaultframer
+};
+
+Proto pppoe_sess =
+{
+ "pppoe_sess",
+ p_compilesess,
+ p_filter,
+ p_seprintsess,
+ p_mux,
+ p_fields,
+ defaultframer
+};
+