xref: /plan9/sys/src/cmd/ip/snoopy/arp.c (revision ed397113cdcf7aafea372b730bbcd17b05ee3f60)
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