Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <ip.h>
4
#include "dat.h"
5
#include "protos.h"
6
 
7
/*
8
 GRE version 0 is specified in rfc1701.
9
 GRE version 0 has been respecified in rfc2784 as a subset of rfc1701.
10
 GRE version 1, as used by pptp, has been specified in rfc2637.
11
*/
12
 
13
 
14
/* GRE flag bits */
15
enum {
16
	GRE_chksum	= (1<<15),
17
	GRE_routing	= (1<<14),
18
	GRE_key		= (1<<13),
19
	GRE_seq		= (1<<12),
20
	GRE_srcrt		= (1<<11),
21
	GRE_recur	= (7<<8),
22
	GRE_ack		= (1<<7),
23
	GRE_version	= 0x7,
24
};
25
 
26
 
27
typedef struct Hdr	Hdr;
28
struct Hdr
29
{
30
	ushort flags;
31
	ushort proto;
32
	uchar version;
33
	ushort chksum;
34
	ushort offset;
35
	ulong key;
36
	ulong seq;
37
	ulong route;
38
	ulong ack;
39
};
40
 
41
enum
42
{
43
	Oproto,
44
};
45
 
46
static Field p_fields[] = 
47
{
48
	{"proto",		Fnum,	Oproto,	"encapsulated protocol",	} ,
49
	{0}
50
};
51
 
52
static Mux p_mux[] =
53
{
54
	{"pup",	0x0200, },
55
	{"xns",	0x0600, },
56
	{"ip",		0x0800, },
57
	{"chaos",	0x0804, },
58
	{"arp",	0x0806, },
59
	{"frarp",	0x0808, },
60
	{"vines",	0x0bad, },
61
	{"vinesecho",	0x0bae, },
62
	{"vinesloop",	0x0baf, },
63
	{"ppp",	0x880b, },
64
	{"llc",	0x007a, },
65
	{"dot1q",	0x8100, },
66
	{"eapol",	0x888e, },
67
	{0},
68
};
69
 
70
int
71
parthdrlen(ushort flags)
72
{
73
	return 4 + 
74
		(flags&GRE_chksum || flags&GRE_routing) ? 4 : 0 +
75
		flags&GRE_key ? 4 : 0 +
76
		flags&GRE_seq ? 4 : 0 +
77
		flags&GRE_ack ? 4 : 0;
78
}
79
 
80
int
81
parsehdr(Hdr *h, uchar *s, uchar *e)
82
{
83
	uchar *p;
84
	uchar n;
85
 
86
	if(e - s < 4)
87
		return -1;
88
 
89
	p = s;
90
 
91
	h->flags = NetS(p);
92
	p += 2;
93
	h->proto = NetS(p);
94
	p += 2;
95
	h->version = h->flags&GRE_version;
96
 
97
	if(parthdrlen(h->flags) > e - s)
98
		return -1;
99
 
100
	if(h->flags&(GRE_chksum|GRE_routing)){
101
		h->chksum = NetS(p);
102
		p += 2;
103
		h->offset = NetS(p);
104
		p += 2;
105
	}
106
	if(h->flags&GRE_key){
107
		h->key = NetL(p);
108
		p += 4;
109
	}
110
	if(h->flags&GRE_seq){
111
		h->seq = NetL(p);
112
		p += 4;
113
	}
114
	if(h->flags&GRE_ack){
115
		h->ack = NetL(p);
116
		p += 4;
117
	}
118
	if(h->flags&GRE_routing){
119
		for(;;){
120
			if(e - p < 4)
121
				return -1;
122
			if((n = p[3]) == 0)
123
				break;
124
			p += n;
125
		}
126
	}
127
 
128
	return p - s;
129
}
130
 
131
static void
132
p_compile(Filter *f)
133
{
134
	Mux *m;
135
 
136
	if(f->op == '='){
137
		compile_cmp(gre.name, f, p_fields);
138
		return;
139
	}
140
	for(m = p_mux; m->name != nil; m++)
141
		if(strcmp(f->s, m->name) == 0){
142
			f->pr = m->pr;
143
			f->ulv = m->val;
144
			f->subop = Oproto;
145
			return;
146
		}
147
	sysfatal("unknown gre field or protocol: %s", f->s);
148
}
149
 
150
static int
151
p_filter(Filter *f, Msg *m)
152
{
153
	Hdr h;
154
	int len;
155
 
156
	len = parsehdr(&h, m->ps, m->pe);
157
	if(len < 0)
158
		return -1;
159
	m->ps += len;
160
 
161
	switch(f->subop){
162
	case Oproto:
163
		return h.proto == f->ulv;
164
	}
165
	return 0;
166
}
167
 
168
static int
169
p_seprint(Msg *m)
170
{
171
	Hdr h;
172
	int len;
173
 
174
	len = parsehdr(&h, m->ps, m->pe);
175
	if(len < 0)
176
		return -1;
177
	m->ps += len;
178
 
179
	demux(p_mux, h.proto, h.proto, m, &dump);
180
 
181
	m->p = seprint(m->p, m->e, "version=%d proto=%#ux flags=%#.4ux", h.version, h.proto, h.flags);
182
	if(h.flags&GRE_chksum)
183
		m->p = seprint(m->p, m->e, " checksum=%#.4ux", h.chksum);
184
	if(h.flags&GRE_key)
185
		m->p = seprint(m->p, m->e, " key=%#.8ulx", h.key);
186
	if(h.flags&GRE_seq)
187
		m->p = seprint(m->p, m->e, " seq=%#.8ulx", h.seq);
188
	if(h.flags&GRE_ack)
189
		m->p = seprint(m->p, m->e, " ack=%#.8ulx", h.ack);
190
	if(h.flags&GRE_routing)
191
		m->p = seprint(m->p, m->e, " offset=%#ux haverouting", h.offset);
192
	if(h.version == 0)
193
		m->p = seprint(m->p, m->e, " recursion=%ud", (h.flags&GRE_recur)>>8);
194
 
195
	return 0;
196
}
197
 
198
Proto gre =
199
{
200
	"gre",
201
	p_compile,
202
	p_filter,
203
	p_seprint,
204
	p_mux,
205
	"%#.4ux",
206
	p_fields,
207
	defaultframer,
208
};