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 vi; /* version */
11 uchar type;
12 uchar len[2]; /* length of data following this header */
13 };
14
15 enum
16 {
17 EAPOLHDR= 4, /* sizeof(Hdr) */
18
19 /* eapol types */
20 Eap = 0,
21 Start,
22 Logoff,
23 Key,
24 AsfAlert,
25 };
26
27 enum
28 {
29 Ot, /* type */
30 };
31
32 static Mux p_mux[] =
33 {
34 { "eap", Eap, },
35 { "eapol_start", Start, },
36 { "eapol_logoff", Logoff, },
37 { "eapol_key", Key, },
38 { "asf_alert", AsfAlert, },
39 { 0 }
40 };
41
42 static void
p_compile(Filter * f)43 p_compile(Filter *f)
44 {
45 Mux *m;
46
47 for(m = p_mux; m->name != nil; m++)
48 if(strcmp(f->s, m->name) == 0){
49 f->pr = m->pr;
50 f->ulv = m->val;
51 f->subop = Ot;
52 return;
53 }
54 sysfatal("unknown eapol field or type: %s", f->s);
55 }
56
57 static int
p_filter(Filter * f,Msg * m)58 p_filter(Filter *f, Msg *m)
59 {
60 Hdr *h;
61
62 if(m->pe - m->ps < EAPOLHDR)
63 return 0;
64
65 h = (Hdr*)m->ps;
66
67 /* len does not include header */
68 m->ps += EAPOLHDR;
69
70 switch(f->subop){
71 case Ot:
72 return h->type == f->ulv;
73 }
74 return 0;
75 }
76
77 static char*
op(int i)78 op(int i)
79 {
80 static char x[20];
81
82 switch(i){
83 case Eap:
84 return "Eap";
85 case Start:
86 return "Start";
87 case Logoff:
88 return "Logoff";
89 case Key:
90 return "Key";
91 case AsfAlert:
92 return "AsfAlert";
93 default:
94 sprint(x, "%1d", i);
95 return x;
96 }
97 }
98
99 static int
p_seprint(Msg * m)100 p_seprint(Msg *m)
101 {
102 Hdr *h;
103 int len;
104
105 if(m->pe - m->ps < EAPOLHDR)
106 return -1;
107
108 h = (Hdr*)m->ps;
109
110 /* len does not include header */
111 m->ps += EAPOLHDR;
112
113 /* truncate the message if there's extra */
114 len = NetS(h->len);
115 if(m->ps + len < m->pe)
116 m->pe = m->ps + len;
117 else if(m->ps+len > m->pe)
118 return -1;
119
120 /* next protocol depending on type*/
121 demux(p_mux, h->type, h->type, m, &dump);
122
123 m->p = seprint(m->p, m->e, "type=%s version=%1d datalen=%1d",
124 op(h->type), h->vi, len);
125 return 0;
126 }
127
128 Proto eapol =
129 {
130 "eapol",
131 p_compile,
132 p_filter,
133 p_seprint,
134 p_mux,
135 "%lud",
136 nil,
137 defaultframer,
138 };
139