From 87a52e0485d3281ebea6bf4b725aa8023690e96f Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 26 Dec 2005 04:48:52 +0000 Subject: new goodies --- src/cmd/ip/snoopy/arp.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 src/cmd/ip/snoopy/arp.c (limited to 'src/cmd/ip/snoopy/arp.c') diff --git a/src/cmd/ip/snoopy/arp.c b/src/cmd/ip/snoopy/arp.c new file mode 100755 index 00000000..3433ebc6 --- /dev/null +++ b/src/cmd/ip/snoopy/arp.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include "dat.h" +#include "protos.h" + +typedef struct Hdr Hdr; +struct Hdr +{ + uchar hrd[2]; + uchar pro[2]; + uchar hln; + uchar pln; + uchar op[2]; + uchar sha[6]; + uchar spa[4]; + uchar tha[6]; + uchar tpa[4]; +}; + +enum +{ + ARPLEN= 28, +}; + +enum +{ + Ospa, + Otpa, + Ostpa, + Osha, + Otha, + Ostha, + Opa, +}; + +static Field p_fields[] = +{ + {"spa", Fv4ip, Ospa, "protocol source", } , + {"tpa", Fv4ip, Otpa, "protocol target", } , + {"a", Fv4ip, Ostpa, "protocol source/target", } , + {"sha", Fba, Osha, "hardware source", } , + {"tha", Fba, Otha, "hardware target", } , + {"ah", Fba, Ostha, "hardware source/target", } , + {0} +}; + +static void +p_compile(Filter *f) +{ + if(f->op == '='){ + compile_cmp(arp.name, f, p_fields); + return; + } + sysfatal("unknown arp field: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe - m->ps < ARPLEN) + return 0; + + h = (Hdr*)m->ps; + m->ps += ARPLEN; + + switch(f->subop){ + case Ospa: + return h->pln == 4 && NetL(h->spa) == f->ulv; + case Otpa: + return h->pln == 4 && NetL(h->tpa) == f->ulv; + case Ostpa: + return h->pln == 4 && (NetL(h->tpa) == f->ulv || + NetL(h->spa) == f->ulv); + case Osha: + return memcmp(h->sha, f->a, h->hln) == 0; + case Otha: + return memcmp(h->tha, f->a, h->hln) == 0; + case Ostha: + return memcmp(h->sha, f->a, h->hln)==0 + ||memcmp(h->tha, f->a, h->hln)==0; + } + return 0; +} + +static int +p_seprint(Msg *m) +{ + Hdr *h; + + if(m->pe - m->ps < ARPLEN) + return -1; + + h = (Hdr*)m->ps; + m->ps += ARPLEN; + + /* no next protocol */ + m->pr = nil; + + m->p = seprint(m->p, m->e, "op=%1d len=%1d/%1d spa=%V sha=%E tpa=%V tha=%E", + NetS(h->op), h->pln, h->hln, + h->spa, h->sha, h->tpa, h->tha); + return 0; +} + +Proto arp = +{ + "arp", + p_compile, + p_filter, + p_seprint, + nil, + p_fields, + defaultframer, +}; + +Proto rarp = +{ + "rarp", + p_compile, + p_filter, + p_seprint, + nil, + p_fields, + defaultframer, +}; -- cgit v1.2.3