/* * 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*);