]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/snoopy/arp.c
etheriwl: don't break controller on command flush timeout
[plan9front.git] / sys / src / cmd / ip / snoopy / arp.c
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6
7 typedef struct Hdr      Hdr;
8 struct Hdr
9 {
10         uchar   hrd[2];
11         uchar   pro[2];
12         uchar   hln;
13         uchar   pln;
14         uchar   op[2];
15         uchar   sha[6];
16         uchar   spa[4];
17         uchar   tha[6];
18         uchar   tpa[4];
19 };
20
21 enum
22 {
23         ARPLEN= 28,
24 };
25
26 enum
27 {
28         Ospa,
29         Otpa,
30         Ostpa,
31         Osha,
32         Otha,
33         Ostha,
34         Opa,
35 };
36
37 static Field p_fields[] = 
38 {
39         {"spa",         Fv4ip,  Ospa,   "protocol source",      } ,
40         {"tpa",         Fv4ip,  Otpa,   "protocol target",      } ,
41         {"a",           Fv4ip,  Ostpa,  "protocol source/target",       } ,
42         {"sha",         Fba,    Osha,   "hardware source",      } ,
43         {"tha",         Fba,    Otha,   "hardware target",      } ,
44         {"ah",          Fba,    Ostha,  "hardware source/target",       } ,
45         {0}
46 };
47
48 static void
49 p_compile(Filter *f)
50 {
51         if(f->op == '='){
52                 compile_cmp(arp.name, f, p_fields);
53                 return;
54         }
55         sysfatal("unknown arp field: %s", f->s);
56 }
57
58 static int
59 p_filter(Filter *f, Msg *m)
60 {
61         Hdr *h;
62
63         if(m->pe - m->ps < ARPLEN)
64                 return 0;
65
66         h = (Hdr*)m->ps;
67         m->ps += ARPLEN;
68
69         switch(f->subop){
70         case Ospa:
71                 return h->pln == 4 && NetL(h->spa) == f->ulv;
72         case Otpa:
73                 return h->pln == 4 && NetL(h->tpa) == f->ulv;
74         case Ostpa:
75                 return h->pln == 4 && (NetL(h->tpa) == f->ulv ||
76                         NetL(h->spa) == f->ulv);
77         case Osha:
78                 return memcmp(h->sha, f->a, h->hln) == 0;
79         case Otha:
80                 return memcmp(h->tha, f->a, h->hln) == 0;
81         case Ostha:
82                 return memcmp(h->sha, f->a, h->hln)==0
83                         ||memcmp(h->tha, f->a, h->hln)==0;
84         }
85         return 0;
86 }
87
88 static int
89 p_seprint(Msg *m)
90 {
91         Hdr *h;
92
93         if(m->pe - m->ps < ARPLEN)
94                 return -1;
95
96         h = (Hdr*)m->ps;
97         m->ps += ARPLEN;
98
99         /* no next protocol */
100         m->pr = nil;
101
102         m->p = seprint(m->p, m->e, "op=%1d len=%1d/%1d spa=%V sha=%E tpa=%V tha=%E",
103                         NetS(h->op), h->pln, h->hln,
104                         h->spa, h->sha, h->tpa, h->tha);
105         return 0;
106 }
107
108 Proto arp =
109 {
110         "arp",
111         p_compile,
112         p_filter,
113         p_seprint,
114         nil,
115         nil,
116         p_fields,
117         defaultframer,
118 };
119
120 Proto rarp =
121 {
122         "rarp",
123         p_compile,
124         p_filter,
125         p_seprint,
126         nil,
127         nil,
128         p_fields,
129         defaultframer,
130 };