Blob
1 #include <u.h>2 #include <libc.h>3 #include <ip.h>4 #include "dat.h"5 #include "protos.h"7 typedef struct Hdr Hdr;8 struct Hdr9 {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 };21 enum22 {23 ARPLEN= 2824 };26 enum27 {28 Ospa,29 Otpa,30 Ostpa,31 Osha,32 Otha,33 Ostha,34 Opa35 };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 };48 static void49 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 }58 static int59 p_filter(Filter *f, Msg *m)60 {61 Hdr *h;63 if(m->pe - m->ps < ARPLEN)64 return 0;66 h = (Hdr*)m->ps;67 m->ps += ARPLEN;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)==083 ||memcmp(h->tha, f->a, h->hln)==0;84 }85 return 0;86 }88 static int89 p_seprint(Msg *m)90 {91 Hdr *h;93 if(m->pe - m->ps < ARPLEN)94 return -1;96 h = (Hdr*)m->ps;97 m->ps += ARPLEN;99 /* no next protocol */100 m->pr = nil;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 }108 Proto arp =109 {110 "arp",111 p_compile,112 p_filter,113 p_seprint,114 nil,115 nil,116 p_fields,117 defaultframer118 };120 Proto rarp =121 {122 "rarp",123 p_compile,124 p_filter,125 p_seprint,126 nil,127 nil,128 p_fields,129 defaultframer130 };