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