xref: /plan9/sys/src/cmd/ip/snoopy/aoemd.c (revision 43751f27fa93b002d5e921851faf5da5cbdcb417)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6 
7 typedef struct {
8 	uchar	res;
9 	uchar	cmd;
10 	uchar	ea[6];
11 } Hdr;
12 
13 enum {
14 	Ocmd,
15 	Oea,
16 
17 	Hsize	= 8,
18 };
19 
20 static Field p_fields[] = {
21 	{"cmd",	Fnum,	Ocmd,	"command",	},
22 	{"ea",	Fnum,	Oea,	"ethernet addr", },
23 	nil
24 };
25 
26 static void
p_compile(Filter * f)27 p_compile(Filter *f)
28 {
29 	if(f->op == '='){
30 		compile_cmp(aoemd.name, f, p_fields);
31 		return;
32 	}
33 	sysfatal("unknown aoemd field: %s", f->s);
34 }
35 
36 static int
p_filter(Filter * f,Msg * m)37 p_filter(Filter *f, Msg *m)
38 {
39 	uchar buf[6];
40 	int i;
41 	Hdr *h;
42 
43 	if(m->pe - m->ps < Hsize)
44 		return 0;
45 
46 	h = (Hdr*)m->ps;
47 	m->ps += Hsize;
48 
49 	switch(f->subop){
50 	case Ocmd:
51 		return h->cmd == f->ulv;
52 	case Oea:
53 		for(i = 0; i < 6; i++)
54 			buf[i] = f->ulv >> ((5 - i)*8);
55 		return memcmp(buf, h->ea, 6) == 0;
56 	}
57 	return 0;
58 }
59 
60 static char *ctab[] = {
61 	"  ",
62 	" +",
63 	" -",
64 };
65 
66 static int
p_seprint(Msg * m)67 p_seprint(Msg *m)
68 {
69 	char *s;
70 	Hdr *h;
71 
72 	if(m->pe - m->ps < Hsize)
73 		return 0;
74 
75 	h = (Hdr*)m->ps;
76 	m->ps += Hsize;
77 
78 	/* no next protocol */
79 	m->pr = nil;
80 
81 	s = "unk";
82 	if(h->cmd < nelem(ctab))
83 		s = ctab[h->cmd];
84 	m->p = seprint(m->p, m->e, "cmd=%d%s ea=%E\n", h->cmd, s, h->ea);
85 	return 0;
86 }
87 
88 Proto aoemd = {
89 	"aoemd",
90 	p_compile,
91 	p_filter,
92 	p_seprint,
93 	nil,
94 	nil,
95 	p_fields,
96 	defaultframer,
97 };
98