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 err;
11 uchar cnt;
12 } Hdr;
13
14 enum {
15 Ocmd,
16 Oerr,
17 Ocnt,
18
19 Hsize = 4,
20 };
21
22 static Field p_fields[] =
23 {
24 { "cmd", Fnum, Ocmd, "command", },
25 { "err", Fnum, Oerr, "error", },
26 { "cnt", Fnum, Ocnt, "count", },
27 nil
28 };
29
30 static Mux p_mux[] = {
31 { "aoemd", 0 },
32 { "aoemd", 1 },
33 nil
34 };
35
36 static void
p_compile(Filter * f)37 p_compile(Filter *f)
38 {
39 Mux *m;
40
41 if(f->op == '='){
42 compile_cmp(aoerr.name, f, p_fields);
43 return;
44 }
45 for(m = p_mux; m->name; m++)
46 if(strcmp(f->s, m->name) == 0){
47 f->pr = m->pr;
48 f->ulv = m->val;
49 f->subop = Ocmd;
50 return;
51 }
52 sysfatal("unknown aoemask field: %s", f->s);
53 }
54
55 static int
p_filter(Filter * f,Msg * m)56 p_filter(Filter *f, Msg *m)
57 {
58 Hdr *h;
59
60 if(m->pe - m->ps < Hsize)
61 return 0;
62
63 h = (Hdr*)m->ps;
64 m->ps += Hsize;
65
66 switch(f->subop){
67 case Ocmd:
68 return h->cmd == f->ulv;
69 case Oerr:
70 return h->err == f->ulv;
71 case Ocnt:
72 return h->cnt == f->ulv;
73 }
74 return 0;
75 }
76
77 static char *ctab[] = {
78 "read",
79 "edit",
80 };
81
82 static char *etab[] = {
83 "",
84 "bad",
85 "full",
86 };
87
88 static int
p_seprint(Msg * m)89 p_seprint(Msg *m)
90 {
91 char *s, *t;
92 Hdr *h;
93
94 if(m->pe - m->ps < Hsize)
95 return 0;
96
97 h = (Hdr*)m->ps;
98 m->ps += Hsize;
99
100 demux(p_mux, h->cmd, h->cmd, m, &dump);
101
102 s = "unk";
103 if(h->cmd < nelem(ctab))
104 s = ctab[h->cmd];
105 t = "unk";
106 if(h->err < nelem(etab))
107 s = etab[h->err];
108 m->p = seprint(m->p, m->e, "cmd=%d %s err=%d %s cnt=%d\n",
109 h->cmd, s, h->err, t, h->cnt);
110 return 0;
111 }
112
113 Proto aoemask = {
114 "aoemask",
115 p_compile,
116 p_filter,
117 p_seprint,
118 p_mux,
119 "%lud",
120 p_fields,
121 defaultframer,
122 };
123