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 uchar verstype;
10 uchar code;
11 uchar sessid[2];
12 uchar length[2]; /* of payload */
13 };
14 enum
15 {
16 HDRSIZE = 1+1+2+2
17 };
18
19 static Mux p_mux[] =
20 {
21 {"ppp", 0, } ,
22 {0}
23 };
24
25 enum
26 {
27 Overs,
28 Otype,
29 Ocode,
30 Osess
31 };
32
33 static Field p_fields[] =
34 {
35 {"v", Fnum, Overs, "version", } ,
36 {"t", Fnum, Otype, "type", } ,
37 {"c", Fnum, Ocode, "code" } ,
38 {"s", Fnum, Osess, "sessid" } ,
39 {0}
40 };
41
42 static void
p_compilesess(Filter * f)43 p_compilesess(Filter *f)
44 {
45 /* Mux *m; */
46
47 if(f->op == '='){
48 compile_cmp(pppoe_sess.name, f, p_fields);
49 return;
50 }
51 /*
52 for(m = p_mux; m->name != nil; m++)
53 if(strcmp(f->s, m->name) == 0){
54 f->pr = m->pr;
55 f->ulv = m->val;
56 f->subop = Ot;
57 return;
58 }
59 */
60 sysfatal("unknown pppoe field or protocol: %s", f->s);
61 }
62 static void
p_compiledisc(Filter * f)63 p_compiledisc(Filter *f)
64 {
65 /* Mux *m; */
66
67 if(f->op == '='){
68 compile_cmp(pppoe_disc.name, f, p_fields);
69 return;
70 }
71 /*
72 for(m = p_mux; m->name != nil; m++)
73 if(strcmp(f->s, m->name) == 0){
74 f->pr = m->pr;
75 f->ulv = m->val;
76 f->subop = Ot;
77 return;
78 }
79 */
80 sysfatal("unknown pppoe field or protocol: %s", f->s);
81 }
82
83 static int
p_filter(Filter * f,Msg * m)84 p_filter(Filter *f, Msg *m)
85 {
86 Hdr *h;
87
88 if(m->pe - m->ps < HDRSIZE)
89 return 0;
90
91 h = (Hdr*)m->ps;
92 m->ps += HDRSIZE;
93
94 switch(f->subop){
95 case Overs:
96 return (h->verstype>>4) == f->ulv;
97 case Otype:
98 return (h->verstype&0xF) == f->ulv;
99 case Ocode:
100 return h->code == f->ulv;
101 case Osess:
102 return NetS(h->sessid) == f->ulv;
103 }
104 return 0;
105 }
106
107 /* BUG: print all the discovery types */
108 static int
p_seprintdisc(Msg * m)109 p_seprintdisc(Msg *m)
110 {
111 Hdr *h;
112 int len;
113
114 len = m->pe - m->ps;
115 if(len < HDRSIZE)
116 return -1;
117
118 h = (Hdr*)m->ps;
119 m->ps += HDRSIZE;
120
121 m->pr = nil;
122
123 m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
124 h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
125
126 return 0;
127 }
128
129 static int
p_seprintsess(Msg * m)130 p_seprintsess(Msg *m)
131 {
132 Hdr *h;
133 int len;
134
135 len = m->pe - m->ps;
136 if(len < HDRSIZE)
137 return -1;
138
139 h = (Hdr*)m->ps;
140 m->ps += HDRSIZE;
141
142 /* this will call ppp for me */
143 demux(p_mux, 0, 0, m, &dump);
144
145 m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
146 h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
147
148 return 0;
149 }
150
151 Proto pppoe_disc =
152 {
153 "pppoe_disc",
154 p_compiledisc,
155 p_filter,
156 p_seprintdisc,
157 p_mux,
158 "%lud",
159 p_fields,
160 defaultframer
161 };
162
163 Proto pppoe_sess =
164 {
165 "pppoe_sess",
166 p_compilesess,
167 p_filter,
168 p_seprintsess,
169 p_mux,
170 "%lud",
171 p_fields,
172 defaultframer
173 };
174