snap.c (1521B)
1 /* 2 * SNAP. 3 */ 4 5 #include <u.h> 6 #include <libc.h> 7 #include <ip.h> 8 #include "dat.h" 9 #include "protos.h" 10 11 enum 12 { 13 Oorg, 14 Oet, 15 16 OuiEther = 0, 17 OuiCisco = 0xc, 18 OuiCisco90 = 0xf8, 19 OuiRfc2684 = 0x80c2, 20 OuiAppletalk = 0x80007, 21 }; 22 23 static Mux p_mux[] = 24 { 25 {"ip", 0x0800, } , 26 {"arp", 0x0806, } , 27 {"rarp", 0x0806, } , 28 {"ip6", 0x86dd, } , 29 {"pppoe_disc", 0x8863, }, 30 {"pppoe_sess", 0x8864, }, 31 {"eapol", 0x888e, }, 32 { 0 } 33 }; 34 35 typedef struct Hdr Hdr; 36 struct Hdr 37 { 38 uchar org[3]; 39 uchar et[2]; 40 }; 41 42 static Field p_fields[] = 43 { 44 { "org", Fnum, Oorg, "org" }, 45 { "et", Fnum, Oet, "et" }, 46 { 0 } 47 }; 48 49 static void 50 p_compile(Filter *f) 51 { 52 Mux *m; 53 54 if(f->op == '='){ 55 compile_cmp(snap.name, f, p_fields); 56 return; 57 } 58 for(m = p_mux; m->name != nil; m++){ 59 if(strcmp(f->s, m->name) == 0){ 60 f->pr = m->pr; 61 f->ulv = m->val; 62 f->subop = Oet; 63 return; 64 } 65 } 66 sysfatal("unknown snap field or protocol: %s", f->s); 67 } 68 69 static int 70 p_filter(Filter *f, Msg *m) 71 { 72 Hdr *h; 73 74 if(m->pe - m->ps < sizeof(Hdr)) 75 return 0; 76 h = (Hdr*)m->ps; 77 m->ps += 5; 78 switch(f->subop){ 79 case Oorg: 80 return f->ulv == Net3(h->org); 81 case Oet: 82 return f->ulv == NetS(h->et); 83 } 84 return 0; 85 } 86 87 static int 88 p_seprint(Msg *m) 89 { 90 Hdr *h; 91 92 if(m->pe - m->ps < sizeof(Hdr)) 93 return 0; 94 h = (Hdr*)m->ps; 95 m->ps += 5; 96 demux(p_mux, NetS(h->et), NetS(h->et), m, &dump); 97 98 m->p = seprint(m->p, m->e, "org=%06x et=%04x", Net3(h->org), NetS(h->et)); 99 return 0; 100 } 101 102 Proto snap = 103 { 104 "snap", 105 p_compile, 106 p_filter, 107 p_seprint, 108 p_mux, 109 nil, 110 nil, 111 defaultframer 112 };