1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/*
* The rule engine, shared by both halves of fw: request filtering (the
* ctl layer) and packet filtering (the wire). One rule language, two enforcement points: a rule says what
* may happen, and the caller decides where it is enforced.
*/
typedef struct Rule Rule;
/*
* Direction, not layer. A "connect" written to a ctl file and an
* egress packet are the same intent seen from two places, so they are
* the same verb and one rule file serves both enforcement points.
*/
enum
{
Vin, /* inbound: announce, or a packet arriving */
Vout, /* outbound: connect, or a packet leaving */
Vany,
};
struct Rule
{
int allow;
int verb;
char *proto; /* nil: any */
int anyip;
uchar ip[IPaddrlen]; /* the peer, whichever end that is */
uchar mask[IPaddrlen];
int port; /* peer port, -1: any */
int lport; /* local port, -1: any */
int log; /* note matches in /sys/log/fw */
long hits; /* how often it has decided something */
int nr;
Rule *next;
};
/*
* Rules are swapped wholesale, never mutated in place, so no packet is
* ever judged against a half-applied rule set. rulechanged, if set, is
* called after a swap - the wire half uses it to re-check live flows.
*/
extern Rule *rules;
extern void (*rulechanged)(void);
void readrules(char*); /* parse and install, fatal on error */
Rule* parserules(char*, char**); /* parse only; nil + reason on error */
void installrules(Rule*); /* swap in, then call rulechanged */
void freerules(Rule*);
long fmtrules(char*, long); /* current set, back in ndb form */
long fmthits(char*, long); /* the same, with hit counts */
void dumprules(void);
void checklogging(void);
char* matchrule(int verb, char *proto, uchar *ip, int anyip, int port, int lport, Rule**);
int protoname2num(char*);
char* protonum2name(int);
void* emalloc(ulong);
char* estrdup(char*);
|