plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

arp.c (1909B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <ip.h>
      4 #include "dat.h"
      5 #include "protos.h"
      6 
      7 typedef struct Hdr	Hdr;
      8 struct Hdr
      9 {
     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 };
     20 
     21 enum
     22 {
     23 	ARPLEN=	28
     24 };
     25 
     26 enum
     27 {
     28 	Ospa,
     29 	Otpa,
     30 	Ostpa,
     31 	Osha,
     32 	Otha,
     33 	Ostha,
     34 	Opa
     35 };
     36 
     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 };
     47 
     48 static void
     49 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 }
     57 
     58 static int
     59 p_filter(Filter *f, Msg *m)
     60 {
     61 	Hdr *h;
     62 
     63 	if(m->pe - m->ps < ARPLEN)
     64 		return 0;
     65 
     66 	h = (Hdr*)m->ps;
     67 	m->ps += ARPLEN;
     68 
     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)==0
     83 			||memcmp(h->tha, f->a, h->hln)==0;
     84 	}
     85 	return 0;
     86 }
     87 
     88 static int
     89 p_seprint(Msg *m)
     90 {
     91 	Hdr *h;
     92 
     93 	if(m->pe - m->ps < ARPLEN)
     94 		return -1;
     95 
     96 	h = (Hdr*)m->ps;
     97 	m->ps += ARPLEN;
     98 
     99 	/* no next protocol */
    100 	m->pr = nil;
    101 
    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 }
    107 
    108 Proto arp =
    109 {
    110 	"arp",
    111 	p_compile,
    112 	p_filter,
    113 	p_seprint,
    114 	nil,
    115 	nil,
    116 	p_fields,
    117 	defaultframer
    118 };
    119 
    120 Proto rarp =
    121 {
    122 	"rarp",
    123 	p_compile,
    124 	p_filter,
    125 	p_seprint,
    126 	nil,
    127 	nil,
    128 	p_fields,
    129 	defaultframer
    130 };