add aoe and cec support to snoopy. Reference: /n/sources/patch/applied/snoopy-aoe Date: Wed Jun 6 23:40:31 CES 2007 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/ip/snoopy/mkfile Wed Jun 6 23:37:30 2007 +++ /sys/src/cmd/ip/snoopy/mkfile Wed Jun 6 23:37:28 2007 @@ -2,8 +2,12 @@ TARG=snoopy PROTOS=\ + aoe\ + aoeata\ + aoecmd\ arp\ bootp\ + cec\ dhcp\ dns\ dump\ --- /sys/src/cmd/ip/snoopy/ether.c Wed Jun 6 23:37:40 2007 +++ /sys/src/cmd/ip/snoopy/ether.c Wed Jun 6 23:37:38 2007 @@ -24,6 +24,8 @@ {"pppoe_disc", 0x8863, }, {"pppoe_sess", 0x8864, }, {"eapol", 0x888e, }, + {"aoe", 0x88a2, } , + {"cec", 0xbcbc, } , {0} }; --- /sys/src/cmd/ip/snoopy/aoe.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ip/snoopy/aoe.c Wed Jun 6 23:37:50 2007 @@ -0,0 +1,102 @@ +#include +#include +#include +#include "dat.h" +#include "protos.h" + +typedef struct{ + uchar verflags; + uchar error; + uchar major[2]; + uchar minor; + uchar cmd; + uchar tag[4]; +}Hdr; + +enum{ + Hsize = 10, +}; + +enum{ + Omajor, + Ominor, + Ocmd, +}; + +static Mux p_mux[] = { + {"aoeata", 0}, + {"aoecmd", 1}, + {0}, +}; + +static Field p_fields[] = +{ + {"slot", Fnum, Ominor, "shelf", }, + {"shelf", Fnum, Omajor, "slot", }, + {"cmd", Fnum, Ocmd, "cmd", }, + {0} +}; + +static void +p_compile(Filter *f) +{ + if(f->op == '='){ + compile_cmp(aoe.name, f, p_fields); + return; + } + sysfatal("unknown aoe field: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + switch(f->subop){ + case Omajor: + return NetS(h->major) == f->ulv; + case Ominor: + return h->minor == f->ulv; + case Ocmd: + return h->cmd == f->ulv; + } + return 0; +} + +static int +p_seprint(Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + demux(p_mux, h->cmd, h->cmd, m, &dump); + + m->p = seprint(m->p, m->e, "ver=%d flag=%4b err=%d %d.%d cmd=%ux tag=%ux", + h->verflags>>4, h->verflags&0xf, + h->error, NetS(h->major), h->minor, + h->cmd, NetL(h->tag)); + return 0; +} + +Proto aoe = +{ + "aoe", + p_compile, + p_filter, + p_seprint, + p_mux, + nil, + p_fields, + defaultframer, +}; --- /sys/src/cmd/ip/snoopy/aoeata.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ip/snoopy/aoeata.c Wed Jun 6 23:38:00 2007 @@ -0,0 +1,127 @@ +#include +#include +#include +#include "dat.h" +#include "protos.h" + +typedef struct{ + uchar aflag; + uchar feat; + uchar sectors; + uchar cmd; + uchar lba[6]; +}Hdr; + +enum{ + Hsize = 10, +}; + +enum{ + Oaflag, + Ocmd, + Ofeat, + Osectors, + Olba, + + Ostat, + Oerr, +}; + +static Field p_fields[] = +{ + {"aflag", Fnum, Oaflag, "aflag", }, + {"cmd", Fnum, Ocmd, "command register", }, + {"feat", Fnum, Ofeat, "features", }, + {"sectors", Fnum, Osectors, "number of sectors", } , + {"lba", Fnum, Olba, "lba", }, + {"stat", Fnum, Ostat, "status", }, + {"err", Fnum, Oerr, "error", }, + {0} +}; + +static void +p_compile(Filter *f) +{ + if(f->op == '='){ + compile_cmp(aoeata.name, f, p_fields); + return; + } + sysfatal("unknown aoeata field: %s", f->s); +} + +uvlong +llba(uchar *c) +{ + uvlong l; + + l = c[0]; + l |= c[1]<<8; + l |= c[2]<<16; + l |= c[3]<<24; + l |= (uvlong)c[4]<<32; + l |= (uvlong)c[5]<<40; + return l; +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + switch(f->subop){ + case Oaflag: + return h->aflag == f->ulv; + case Ocmd: + return h->cmd == f->ulv; + case Ofeat: + return h->feat == f->ulv; + case Osectors: + return h->sectors == f->ulv; + case Olba: + return llba(h->lba) == f->vlv; + + // this is wrong, but we don't have access to the direction here + case Ostat: + return h->cmd == f->ulv; + case Oerr: + return h->feat == f->ulv; + } + return 0; +} + +static int +p_seprint(Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + /* no next protocol */ + m->pr = nil; + + m->p = seprint(m->p, m->e, "aflag=%ux errfeat=%ux sectors=%ux cmdstat=%ux lba=%lld", + h->aflag, h->feat, h->sectors, h->cmd, llba(h->lba)); + return 0; +} + +Proto aoeata = +{ + "aoeata", + p_compile, + p_filter, + p_seprint, + nil, + nil, + p_fields, + defaultframer, +}; --- /sys/src/cmd/ip/snoopy/aoecmd.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ip/snoopy/aoecmd.c Wed Jun 6 23:38:11 2007 @@ -0,0 +1,87 @@ +#include +#include +#include +#include "dat.h" +#include "protos.h" + +typedef struct{ + uchar bc[2]; + uchar fw[2]; + uchar sc; + uchar ccmd; + uchar len[2]; +}Hdr; + +enum{ + Hsize = 8, +}; + +enum{ + Ocmd, +}; + +static Field p_fields[] = +{ + {"cmd", Fnum, Ocmd, "cmd", }, + {0} +}; + +static void +p_compile(Filter *f) +{ + if(f->op == '='){ + compile_cmp(aoecmd.name, f, p_fields); + return; + } + sysfatal("unknown aoecmd field: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + switch(f->subop){ + case Ocmd: + return h->ccmd&0xf == f->ulv; + } + return 0; +} + +static int +p_seprint(Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + /* no next protocol */ + m->pr = nil; + + m->p = seprint(m->p, m->e, "bc=%d fw=%.4x sc=%d ver=%d ccmd=%d len=%d cfg=", + NetS(h->bc), NetS(h->fw), h->sc, h->ccmd>>4, h->ccmd&0xf, NetS(h->len)); + m->p = seprint(m->p, m->e, "%.*s", NetS(h->len), (char*)m->ps); + return 0; +} + +Proto aoecmd = +{ + "aoecmd", + p_compile, + p_filter, + p_seprint, + nil, + nil, + p_fields, + defaultframer, +}; --- /sys/src/cmd/ip/snoopy/cec.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ip/snoopy/cec.c Wed Jun 6 23:38:23 2007 @@ -0,0 +1,116 @@ +#include +#include +#include +#include "dat.h" +#include "protos.h" + +typedef struct{ + uchar type; + uchar conn; + uchar seq; + uchar len; +}Hdr; + +enum{ + Hsize = 4, +}; + +enum{ + Otype, + Oconn, + Oseq, + Olen, +}; + +static Field p_fields[] = +{ + {"type", Fnum, Otype, "type", }, + {"conn", Fnum, Oconn, "conn", }, + {"seq", Fnum, Oseq, "seq", }, + {"len", Fnum, Olen, "len", }, + {0} +}; + +static void +p_compile(Filter *f) +{ + if(f->op == '='){ + compile_cmp(aoe.name, f, p_fields); + return; + } + sysfatal("unknown aoe field: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + switch(f->subop){ + case Otype: + return h->type == f->ulv; + case Oconn: + return h->conn = f->ulv; + case Oseq: + return h->seq = f->ulv; + case Olen: + return h->len = f->ulv; + } + return 0; +} + +static char* ttab[] = { + "Tinita", + "Tinitb", + "Tinitc", + "Tdata", + "Tack", + "Tdiscover", + "Toffer", + "Treset", +}; + +static int +p_seprint(Msg *m) +{ + Hdr *h; + char *s, buf[4]; + + if(m->pe-m->ps < Hsize) + return 0; + + h = (Hdr*)m->ps; + m->ps += Hsize; + + m->pr = nil; + + if(h->type < nelem(ttab)) + s = ttab[h->type]; + else{ + snprint(buf, sizeof buf, "%d", h->type); + s = buf; + } + + m->p = seprint(m->p, m->e, "type=%s conn=%d seq=%d len=%d %.*s", + s, h->conn, h->seq, h->len, + h->len, (char*)m->ps); + return 0; +} + +Proto cec = +{ + "cec", + p_compile, + p_filter, + p_seprint, + nil, + nil, + p_fields, + defaultframer, +};