/* * SNAP. */ #include #include #include #include "dat.h" #include "protos.h" enum { Oorg, Oet, OuiEther = 0, OuiCisco = 0xc, OuiCisco90 = 0xf8, OuiRfc2684 = 0x80c2, OuiAppletalk = 0x80007, }; static Mux p_mux[] = { {"ip", 0x0800, } , {"arp", 0x0806, } , {"rarp", 0x0806, } , {"ip6", 0x86dd, } , {"pppoe_disc", 0x8863, }, {"pppoe_sess", 0x8864, }, {"eapol", 0x888e, }, { 0 } }; typedef struct Hdr Hdr; struct Hdr { uchar org[3]; uchar et[2]; }; static Field p_fields[] = { { "org", Fnum, Oorg, "org" }, { "et", Fnum, Oet, "et" }, { 0 } }; static void p_compile(Filter *f) { Mux *m; if(f->op == '='){ compile_cmp(snap.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 = Oet; return; } } sysfatal("unknown snap field or protocol: %s", f->s); } static int p_filter(Filter *f, Msg *m) { Hdr *h; if(m->pe - m->ps < sizeof(Hdr)) return 0; h = (Hdr*)m->ps; m->ps += 5; switch(f->subop){ case Oorg: return f->ulv == Net3(h->org); case Oet: return f->ulv == NetS(h->et); } return 0; } static int p_seprint(Msg *m) { Hdr *h; if(m->pe - m->ps < sizeof(Hdr)) return 0; h = (Hdr*)m->ps; m->ps += 5; demux(p_mux, NetS(h->et), NetS(h->et), m, &dump); m->p = seprint(m->p, m->e, "org=%06x et=%04x", Net3(h->org), NetS(h->et)); return 0; } Proto snap = { "snap", p_compile, p_filter, p_seprint, p_mux, nil, nil, defaultframer };