| #include <u.h> |
| #include <libc.h> |
| #include <ip.h> |
| #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, |
| nil, |
| p_fields, |
| defaultframer |
| }; |
| |
| Proto rarp = |
| { |
| "rarp", |
| p_compile, |
| p_filter, |
| p_seprint, |
| nil, |
| nil, |
| p_fields, |
| defaultframer |
| }; |