1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include "dat.h" 5 #include "protos.h" 6 7 typedef struct Hdr Hdr; 8 struct Hdr { 9 uchar d[6]; 10 uchar s[6]; 11 uchar type[2]; 12 char data[1500]; 13 }; 14 15 #define ETHERMINTU 60 /* minimum transmit size */ 16 #define ETHERMAXTU 1514 /* maximum transmit size */ 17 #define ETHERHDRSIZE 14 /* size of an ethernet header */ 18 19 static Mux p_mux[] = 20 { 21 {"ip", 0x0800, } , 22 {"arp", 0x0806, } , 23 {"rarp", 0x0806, } , 24 {"ip6", 0x86dd, } , 25 {"pppoe_disc", 0x8863, }, 26 {"pppoe_sess", 0x8864, }, 27 {"eapol", 0x888e, }, 28 {"aoe", 0x88a2, } , 29 {"cec", 0xbcbc, } , 30 {0} 31 }; 32 33 enum 34 { 35 Os, /* source */ 36 Od, /* destination */ 37 Oa, /* source or destination */ 38 Ot, /* type */ 39 }; 40 41 static Field p_fields[] = 42 { 43 {"s", Fether, Os, "source address", } , 44 {"d", Fether, Od, "destination address", } , 45 {"a", Fether, Oa, "source|destination address" } , 46 {"sd", Fether, Oa, "source|destination address" } , 47 {"t", Fnum, Ot, "type" } , 48 {0} 49 }; 50 51 static void 52 p_compile(Filter *f) 53 { 54 Mux *m; 55 56 if(f->op == '='){ 57 compile_cmp(ether.name, f, p_fields); 58 return; 59 } 60 for(m = p_mux; m->name != nil; m++) 61 if(strcmp(f->s, m->name) == 0){ 62 f->pr = m->pr; 63 f->ulv = m->val; 64 f->subop = Ot; 65 return; 66 } 67 sysfatal("unknown ethernet field or protocol: %s", f->s); 68 } 69 70 static int 71 p_filter(Filter *f, Msg *m) 72 { 73 Hdr *h; 74 75 if(m->pe - m->ps < ETHERHDRSIZE) 76 return 0; 77 78 h = (Hdr*)m->ps; 79 m->ps += ETHERHDRSIZE; 80 81 switch(f->subop){ 82 case Os: 83 return memcmp(h->s, f->a, 6) == 0; 84 case Od: 85 return memcmp(h->d, f->a, 6) == 0; 86 case Oa: 87 return memcmp(h->s, f->a, 6) == 0 || memcmp(h->d, f->a, 6) == 0; 88 case Ot: 89 return NetS(h->type) == f->ulv; 90 } 91 return 0; 92 } 93 94 static int 95 p_seprint(Msg *m) 96 { 97 int len; 98 uint t; 99 Hdr *h; 100 101 len = m->pe - m->ps; 102 if(len < ETHERHDRSIZE) 103 return -1; 104 105 h = (Hdr*)m->ps; 106 m->ps += ETHERHDRSIZE; 107 108 t = NetS(h->type); 109 demux(p_mux, t, t, m, &dump); 110 111 m->p = seprint(m->p, m->e, "s=%E d=%E pr=%4.4ux ln=%d", h->s, h->d, 112 t, len); 113 return 0; 114 } 115 116 Proto ether = 117 { 118 "ether", 119 p_compile, 120 p_filter, 121 p_seprint, 122 p_mux, 123 "%#.4lux", 124 p_fields, 125 defaultframer 126 }; 127