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