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