arp.c (1909B)
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 { 10 uchar hrd[2]; 11 uchar pro[2]; 12 uchar hln; 13 uchar pln; 14 uchar op[2]; 15 uchar sha[6]; 16 uchar spa[4]; 17 uchar tha[6]; 18 uchar tpa[4]; 19 }; 20 21 enum 22 { 23 ARPLEN= 28 24 }; 25 26 enum 27 { 28 Ospa, 29 Otpa, 30 Ostpa, 31 Osha, 32 Otha, 33 Ostha, 34 Opa 35 }; 36 37 static Field p_fields[] = 38 { 39 {"spa", Fv4ip, Ospa, "protocol source", } , 40 {"tpa", Fv4ip, Otpa, "protocol target", } , 41 {"a", Fv4ip, Ostpa, "protocol source/target", } , 42 {"sha", Fba, Osha, "hardware source", } , 43 {"tha", Fba, Otha, "hardware target", } , 44 {"ah", Fba, Ostha, "hardware source/target", } , 45 {0} 46 }; 47 48 static void 49 p_compile(Filter *f) 50 { 51 if(f->op == '='){ 52 compile_cmp(arp.name, f, p_fields); 53 return; 54 } 55 sysfatal("unknown arp field: %s", f->s); 56 } 57 58 static int 59 p_filter(Filter *f, Msg *m) 60 { 61 Hdr *h; 62 63 if(m->pe - m->ps < ARPLEN) 64 return 0; 65 66 h = (Hdr*)m->ps; 67 m->ps += ARPLEN; 68 69 switch(f->subop){ 70 case Ospa: 71 return h->pln == 4 && NetL(h->spa) == f->ulv; 72 case Otpa: 73 return h->pln == 4 && NetL(h->tpa) == f->ulv; 74 case Ostpa: 75 return h->pln == 4 && (NetL(h->tpa) == f->ulv || 76 NetL(h->spa) == f->ulv); 77 case Osha: 78 return memcmp(h->sha, f->a, h->hln) == 0; 79 case Otha: 80 return memcmp(h->tha, f->a, h->hln) == 0; 81 case Ostha: 82 return memcmp(h->sha, f->a, h->hln)==0 83 ||memcmp(h->tha, f->a, h->hln)==0; 84 } 85 return 0; 86 } 87 88 static int 89 p_seprint(Msg *m) 90 { 91 Hdr *h; 92 93 if(m->pe - m->ps < ARPLEN) 94 return -1; 95 96 h = (Hdr*)m->ps; 97 m->ps += ARPLEN; 98 99 /* no next protocol */ 100 m->pr = nil; 101 102 m->p = seprint(m->p, m->e, "op=%1d len=%1d/%1d spa=%V sha=%E tpa=%V tha=%E", 103 NetS(h->op), h->pln, h->hln, 104 h->spa, h->sha, h->tpa, h->tha); 105 return 0; 106 } 107 108 Proto arp = 109 { 110 "arp", 111 p_compile, 112 p_filter, 113 p_seprint, 114 nil, 115 nil, 116 p_fields, 117 defaultframer 118 }; 119 120 Proto rarp = 121 { 122 "rarp", 123 p_compile, 124 p_filter, 125 p_seprint, 126 nil, 127 nil, 128 p_fields, 129 defaultframer 130 };