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