19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include "dat.h"
59a747e4fSDavid du Colombier #include "protos.h"
69a747e4fSDavid du Colombier
79a747e4fSDavid du Colombier typedef struct Hdr Hdr;
89a747e4fSDavid du Colombier struct Hdr
99a747e4fSDavid du Colombier {
109a747e4fSDavid du Colombier uchar hrd[2];
119a747e4fSDavid du Colombier uchar pro[2];
129a747e4fSDavid du Colombier uchar hln;
139a747e4fSDavid du Colombier uchar pln;
149a747e4fSDavid du Colombier uchar op[2];
159a747e4fSDavid du Colombier uchar sha[6];
169a747e4fSDavid du Colombier uchar spa[4];
179a747e4fSDavid du Colombier uchar tha[6];
189a747e4fSDavid du Colombier uchar tpa[4];
199a747e4fSDavid du Colombier };
209a747e4fSDavid du Colombier
219a747e4fSDavid du Colombier enum
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier ARPLEN= 28,
249a747e4fSDavid du Colombier };
259a747e4fSDavid du Colombier
269a747e4fSDavid du Colombier enum
279a747e4fSDavid du Colombier {
289a747e4fSDavid du Colombier Ospa,
299a747e4fSDavid du Colombier Otpa,
309a747e4fSDavid du Colombier Ostpa,
319a747e4fSDavid du Colombier Osha,
329a747e4fSDavid du Colombier Otha,
339a747e4fSDavid du Colombier Ostha,
349a747e4fSDavid du Colombier Opa,
359a747e4fSDavid du Colombier };
369a747e4fSDavid du Colombier
379a747e4fSDavid du Colombier static Field p_fields[] =
389a747e4fSDavid du Colombier {
399a747e4fSDavid du Colombier {"spa", Fv4ip, Ospa, "protocol source", } ,
409a747e4fSDavid du Colombier {"tpa", Fv4ip, Otpa, "protocol target", } ,
419a747e4fSDavid du Colombier {"a", Fv4ip, Ostpa, "protocol source/target", } ,
429a747e4fSDavid du Colombier {"sha", Fba, Osha, "hardware source", } ,
439a747e4fSDavid du Colombier {"tha", Fba, Otha, "hardware target", } ,
449a747e4fSDavid du Colombier {"ah", Fba, Ostha, "hardware source/target", } ,
459a747e4fSDavid du Colombier {0}
469a747e4fSDavid du Colombier };
479a747e4fSDavid du Colombier
489a747e4fSDavid du Colombier static void
p_compile(Filter * f)499a747e4fSDavid du Colombier p_compile(Filter *f)
509a747e4fSDavid du Colombier {
519a747e4fSDavid du Colombier if(f->op == '='){
529a747e4fSDavid du Colombier compile_cmp(arp.name, f, p_fields);
539a747e4fSDavid du Colombier return;
549a747e4fSDavid du Colombier }
559a747e4fSDavid du Colombier sysfatal("unknown arp field: %s", f->s);
569a747e4fSDavid du Colombier }
579a747e4fSDavid du Colombier
589a747e4fSDavid du Colombier static int
p_filter(Filter * f,Msg * m)599a747e4fSDavid du Colombier p_filter(Filter *f, Msg *m)
609a747e4fSDavid du Colombier {
619a747e4fSDavid du Colombier Hdr *h;
629a747e4fSDavid du Colombier
639a747e4fSDavid du Colombier if(m->pe - m->ps < ARPLEN)
649a747e4fSDavid du Colombier return 0;
659a747e4fSDavid du Colombier
669a747e4fSDavid du Colombier h = (Hdr*)m->ps;
679a747e4fSDavid du Colombier m->ps += ARPLEN;
689a747e4fSDavid du Colombier
699a747e4fSDavid du Colombier switch(f->subop){
709a747e4fSDavid du Colombier case Ospa:
719a747e4fSDavid du Colombier return h->pln == 4 && NetL(h->spa) == f->ulv;
729a747e4fSDavid du Colombier case Otpa:
739a747e4fSDavid du Colombier return h->pln == 4 && NetL(h->tpa) == f->ulv;
749a747e4fSDavid du Colombier case Ostpa:
759a747e4fSDavid du Colombier return h->pln == 4 && (NetL(h->tpa) == f->ulv ||
769a747e4fSDavid du Colombier NetL(h->spa) == f->ulv);
779a747e4fSDavid du Colombier case Osha:
789a747e4fSDavid du Colombier return memcmp(h->sha, f->a, h->hln) == 0;
799a747e4fSDavid du Colombier case Otha:
809a747e4fSDavid du Colombier return memcmp(h->tha, f->a, h->hln) == 0;
819a747e4fSDavid du Colombier case Ostha:
829a747e4fSDavid du Colombier return memcmp(h->sha, f->a, h->hln)==0
839a747e4fSDavid du Colombier ||memcmp(h->tha, f->a, h->hln)==0;
849a747e4fSDavid du Colombier }
859a747e4fSDavid du Colombier return 0;
869a747e4fSDavid du Colombier }
879a747e4fSDavid du Colombier
889a747e4fSDavid du Colombier static int
p_seprint(Msg * m)899a747e4fSDavid du Colombier p_seprint(Msg *m)
909a747e4fSDavid du Colombier {
919a747e4fSDavid du Colombier Hdr *h;
929a747e4fSDavid du Colombier
939a747e4fSDavid du Colombier if(m->pe - m->ps < ARPLEN)
949a747e4fSDavid du Colombier return -1;
959a747e4fSDavid du Colombier
969a747e4fSDavid du Colombier h = (Hdr*)m->ps;
979a747e4fSDavid du Colombier m->ps += ARPLEN;
989a747e4fSDavid du Colombier
999a747e4fSDavid du Colombier /* no next protocol */
1009a747e4fSDavid du Colombier m->pr = nil;
1019a747e4fSDavid du Colombier
1029a747e4fSDavid du Colombier m->p = seprint(m->p, m->e, "op=%1d len=%1d/%1d spa=%V sha=%E tpa=%V tha=%E",
1039a747e4fSDavid du Colombier NetS(h->op), h->pln, h->hln,
1049a747e4fSDavid du Colombier h->spa, h->sha, h->tpa, h->tha);
1059a747e4fSDavid du Colombier return 0;
1069a747e4fSDavid du Colombier }
1079a747e4fSDavid du Colombier
1089a747e4fSDavid du Colombier Proto arp =
1099a747e4fSDavid du Colombier {
1109a747e4fSDavid du Colombier "arp",
1119a747e4fSDavid du Colombier p_compile,
1129a747e4fSDavid du Colombier p_filter,
1139a747e4fSDavid du Colombier p_seprint,
1149a747e4fSDavid du Colombier nil,
115*ed397113SDavid du Colombier nil,
1169a747e4fSDavid du Colombier p_fields,
1173ff48bf5SDavid du Colombier defaultframer,
1189a747e4fSDavid du Colombier };
1199a747e4fSDavid du Colombier
1209a747e4fSDavid du Colombier Proto rarp =
1219a747e4fSDavid du Colombier {
1229a747e4fSDavid du Colombier "rarp",
1239a747e4fSDavid du Colombier p_compile,
1249a747e4fSDavid du Colombier p_filter,
1259a747e4fSDavid du Colombier p_seprint,
1269a747e4fSDavid du Colombier nil,
127*ed397113SDavid du Colombier nil,
1289a747e4fSDavid du Colombier p_fields,
1293ff48bf5SDavid du Colombier defaultframer,
1309a747e4fSDavid du Colombier };
131