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
typedef struct Hdr	Hdr;
8
struct Hdr {
9
	uchar	d[6];
10
	uchar	s[6];
11
	uchar	type[2];
12
	char	data[1500];
13
};
14
 
15
#define	ETHERMINTU	60	/* minimum transmit size */
16
#define	ETHERMAXTU	1514	/* maximum transmit size */
17
#define ETHERHDRSIZE	14	/* size of an ethernet header */
18
 
19
static Mux p_mux[] =
20
{
21
	{"ip",		0x0800,	} ,
22
	{"arp",		0x0806,	} ,
23
	{"rarp",	0x0806,	} ,
24
	{"ip6", 	0x86dd, } ,
25
	{"pppoe_disc",	0x8863, },
26
	{"pppoe_sess",	0x8864, },
27
	{"eapol",	0x888e, },
28
	{"aoe",		0x88a2, } ,
29
	{"cec",		0xbcbc, } ,
30
	{0}
31
};
32
 
33
enum
34
{
35
	Os,	/* source */
36
	Od,	/* destination */
37
	Oa,	/* source or destination */
38
	Ot,	/* type */
39
};
40
 
41
static Field p_fields[] =
42
{
43
	{"s",	Fether,	Os,	"source address",	} ,
44
	{"d",	Fether,	Od,	"destination address",	} ,
45
	{"a",	Fether,	Oa,	"source|destination address" } ,
46
	{"sd",	Fether,	Oa,	"source|destination address" } ,
47
	{"t",	Fnum,	Ot,	"type" } ,
48
	{0}
49
};
50
 
51
static void
52
p_compile(Filter *f)
53
{
54
	Mux *m;
55
 
56
	if(f->op == '='){
57
		compile_cmp(ether.name, f, p_fields);
58
		return;
59
	}
60
	for(m = p_mux; m->name != nil; m++)
61
		if(strcmp(f->s, m->name) == 0){
62
			f->pr = m->pr;
63
			f->ulv = m->val;
64
			f->subop = Ot;
65
			return;
66
		}
67
	sysfatal("unknown ethernet field or protocol: %s", f->s);
68
}
69
 
70
static int
71
p_filter(Filter *f, Msg *m)
72
{
73
	Hdr *h;
74
 
75
	if(m->pe - m->ps < ETHERHDRSIZE)
76
		return 0;
77
 
78
	h = (Hdr*)m->ps;
79
	m->ps += ETHERHDRSIZE;
80
 
81
	switch(f->subop){
82
	case Os:
83
		return memcmp(h->s, f->a, 6) == 0;
84
	case Od:
85
		return memcmp(h->d, f->a, 6) == 0;
86
	case Oa:
87
		return memcmp(h->s, f->a, 6) == 0 || memcmp(h->d, f->a, 6) == 0;
88
	case Ot:
89
		return NetS(h->type) == f->ulv;
90
	}
91
	return 0;
92
}
93
 
94
static int
95
p_seprint(Msg *m)
96
{
97
	int len;
98
	uint t;
99
	Hdr *h;
100
 
101
	len = m->pe - m->ps;
102
	if(len < ETHERHDRSIZE)
103
		return -1;
104
 
105
	h = (Hdr*)m->ps;
106
	m->ps += ETHERHDRSIZE;
107
 
108
	t = NetS(h->type);
109
	demux(p_mux, t, t, m, &dump);
110
 
111
	m->p = seprint(m->p, m->e, "s=%E d=%E pr=%4.4ux ln=%d", h->s, h->d,
112
		t, len);
113
	return 0;
114
}
115
 
116
Proto ether =
117
{
118
	"ether",
119
	p_compile,
120
	p_filter,
121
	p_seprint,
122
	p_mux,
123
	"%#.4lux",
124
	p_fields,
125
	defaultframer
126
};