ip_fw.h revision 112250
13969Sjkh/*
298943Sluigi * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
33969Sjkh *
498943Sluigi * Redistribution and use in source and binary forms, with or without
598943Sluigi * modification, are permitted provided that the following conditions
698943Sluigi * are met:
798943Sluigi * 1. Redistributions of source code must retain the above copyright
898943Sluigi *    notice, this list of conditions and the following disclaimer.
998943Sluigi * 2. Redistributions in binary form must reproduce the above copyright
1098943Sluigi *    notice, this list of conditions and the following disclaimer in the
1198943Sluigi *    documentation and/or other materials provided with the distribution.
123969Sjkh *
1398943Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1498943Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1598943Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1698943Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1798943Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1898943Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1998943Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2098943Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2198943Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2298943Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2398943Sluigi * SUCH DAMAGE.
243969Sjkh *
2550477Speter * $FreeBSD: head/sys/netinet/ip_fw.h 112250 2003-03-15 01:13:00Z cjc $
263969Sjkh */
273969Sjkh
2898943Sluigi#ifndef _IPFW2_H
2998943Sluigi#define _IPFW2_H
30100228Sluigi#define IPFW2  1
313969Sjkh/*
3298943Sluigi * The kernel representation of ipfw rules is made of a list of
3398943Sluigi * 'instructions' (for all practical purposes equivalent to BPF
3498943Sluigi * instructions), which specify which fields of the packet
3598943Sluigi * (or its metatada) should be analysed.
3626359Sjulian *
3798943Sluigi * Each instruction is stored in a structure which begins with
3898943Sluigi * "ipfw_insn", and can contain extra fields depending on the
3998943Sluigi * instruction type (listed below).
4098943Sluigi *
4198943Sluigi * "enum ipfw_opcodes" are the opcodes supported. We can have up
4298943Sluigi * to 256 different opcodes.
4326359Sjulian */
4426359Sjulian
4598943Sluigienum ipfw_opcodes {		/* arguments (4 byte each)	*/
4698943Sluigi	O_NOP,
4798943Sluigi
4898943Sluigi	O_IP_SRC,		/* u32 = IP			*/
4998943Sluigi	O_IP_SRC_MASK,		/* ip = IP/mask			*/
5098943Sluigi	O_IP_SRC_ME,		/* none				*/
5198943Sluigi	O_IP_SRC_SET,		/* u32=base, arg1=len, bitmap	*/
5298943Sluigi
5398943Sluigi	O_IP_DST,		/* u32 = IP			*/
5498943Sluigi	O_IP_DST_MASK,		/* ip = IP/mask			*/
5598943Sluigi	O_IP_DST_ME,		/* none				*/
5698943Sluigi	O_IP_DST_SET,		/* u32=base, arg1=len, bitmap	*/
5798943Sluigi
5898943Sluigi	O_IP_SRCPORT,		/* (n)port list:mask 4 byte ea	*/
5998943Sluigi	O_IP_DSTPORT,		/* (n)port list:mask 4 byte ea	*/
6098943Sluigi	O_PROTO,		/* arg1=protocol		*/
6198943Sluigi
6298943Sluigi	O_MACADDR2,		/* 2 mac addr:mask		*/
6398943Sluigi	O_MAC_TYPE,		/* same as srcport		*/
6498943Sluigi
6598943Sluigi	O_LAYER2,		/* none				*/
6698943Sluigi	O_IN,			/* none				*/
6798943Sluigi	O_FRAG,			/* none				*/
6898943Sluigi
6998943Sluigi	O_RECV,			/* none				*/
7098943Sluigi	O_XMIT,			/* none				*/
7198943Sluigi	O_VIA,			/* none				*/
7298943Sluigi
7398943Sluigi	O_IPOPT,		/* arg1 = 2*u8 bitmap		*/
7498943Sluigi	O_IPLEN,		/* arg1 = len			*/
7598943Sluigi	O_IPID,			/* arg1 = id			*/
7698943Sluigi
7798943Sluigi	O_IPTOS,		/* arg1 = id			*/
7899475Sluigi	O_IPPRECEDENCE,		/* arg1 = precedence << 5	*/
7998943Sluigi	O_IPTTL,		/* arg1 = TTL			*/
8098943Sluigi
8198943Sluigi	O_IPVER,		/* arg1 = version		*/
8298943Sluigi	O_UID,			/* u32 = id			*/
8398943Sluigi	O_GID,			/* u32 = id			*/
8498943Sluigi	O_ESTAB,		/* none (tcp established)	*/
8598943Sluigi	O_TCPFLAGS,		/* arg1 = 2*u8 bitmap		*/
8698943Sluigi	O_TCPWIN,		/* arg1 = desired win		*/
8798943Sluigi	O_TCPSEQ,		/* u32 = desired seq.		*/
8898943Sluigi	O_TCPACK,		/* u32 = desired seq.		*/
8998943Sluigi	O_ICMPTYPE,		/* u32 = icmp bitmap		*/
9098943Sluigi	O_TCPOPTS,		/* arg1 = 2*u8 bitmap		*/
9198943Sluigi
92112250Scjc	O_VERREVPATH,		/* none				*/
93112250Scjc
9498943Sluigi	O_PROBE_STATE,		/* none				*/
9598943Sluigi	O_KEEP_STATE,		/* none				*/
9698943Sluigi	O_LIMIT,		/* ipfw_insn_limit		*/
9798943Sluigi	O_LIMIT_PARENT,		/* dyn_type, not an opcode.	*/
9898943Sluigi	/*
9998943Sluigi	 * these are really 'actions', and must be last in the list.
10098943Sluigi	 */
10198943Sluigi
10298943Sluigi	O_LOG,			/* ipfw_insn_log		*/
10398943Sluigi	O_PROB,			/* u32 = match probability	*/
10498943Sluigi
10598943Sluigi	O_CHECK_STATE,		/* none				*/
10698943Sluigi	O_ACCEPT,		/* none				*/
10798943Sluigi	O_DENY,			/* none 			*/
10898943Sluigi	O_REJECT,		/* arg1=icmp arg (same as deny)	*/
10998943Sluigi	O_COUNT,		/* none				*/
11098943Sluigi	O_SKIPTO,		/* arg1=next rule number	*/
11198943Sluigi	O_PIPE,			/* arg1=pipe number		*/
11298943Sluigi	O_QUEUE,		/* arg1=queue number		*/
11398943Sluigi	O_DIVERT,		/* arg1=port number		*/
11498943Sluigi	O_TEE,			/* arg1=port number		*/
11598943Sluigi	O_FORWARD_IP,		/* fwd sockaddr			*/
11698943Sluigi	O_FORWARD_MAC,		/* fwd mac			*/
11798943Sluigi	O_LAST_OPCODE		/* not an opcode!		*/
11826359Sjulian};
11926359Sjulian
12026359Sjulian/*
12198943Sluigi * Template for instructions.
1223969Sjkh *
12398943Sluigi * ipfw_insn is used for all instructions which require no operands,
12498943Sluigi * a single 16-bit value (arg1), or a couple of 8-bit values.
12598943Sluigi *
12698943Sluigi * For other instructions which require different/larger arguments
12798943Sluigi * we have derived structures, ipfw_insn_*.
12898943Sluigi *
12998943Sluigi * The size of the instruction (in 32-bit words) is in the low
13098943Sluigi * 6 bits of "len". The 2 remaining bits are used to implement
13198943Sluigi * NOT and OR on individual instructions. Given a type, you can
13298943Sluigi * compute the length to be put in "len" using F_INSN_SIZE(t)
13398943Sluigi *
13498943Sluigi * F_NOT	negates the match result of the instruction.
13598943Sluigi *
13698943Sluigi * F_OR		is used to build or blocks. By default, instructions
13798943Sluigi *		are evaluated as part of a logical AND. An "or" block
13898943Sluigi *		{ X or Y or Z } contains F_OR set in all but the last
13998943Sluigi *		instruction of the block. A match will cause the code
14098943Sluigi *		to skip past the last instruction of the block.
14198943Sluigi *
14298943Sluigi * NOTA BENE: in a couple of places we assume that
14398943Sluigi *	sizeof(ipfw_insn) == sizeof(u_int32_t)
14498943Sluigi * this needs to be fixed.
14598943Sluigi *
1463969Sjkh */
14798943Sluigitypedef struct	_ipfw_insn {	/* template for instructions */
14898943Sluigi	enum ipfw_opcodes	opcode:8;
14998943Sluigi	u_int8_t	len;	/* numer of 32-byte words */
15098943Sluigi#define	F_NOT		0x80
15198943Sluigi#define	F_OR		0x40
15298943Sluigi#define	F_LEN_MASK	0x3f
15398943Sluigi#define	F_LEN(cmd)	((cmd)->len & F_LEN_MASK)
1543969Sjkh
15598943Sluigi	u_int16_t	arg1;
15698943Sluigi} ipfw_insn;
15798943Sluigi
15896245Sluigi/*
15998943Sluigi * The F_INSN_SIZE(type) computes the size, in 4-byte words, of
16098943Sluigi * a given type.
16196245Sluigi */
16298943Sluigi#define	F_INSN_SIZE(t)	((sizeof (t))/sizeof(u_int32_t))
16396245Sluigi
16498943Sluigi/*
16598943Sluigi * This is used to store an array of 16-bit entries (ports etc.)
16698943Sluigi */
16798943Sluigitypedef struct	_ipfw_insn_u16 {
16898943Sluigi	ipfw_insn o;
16998943Sluigi	u_int16_t ports[2];	/* there may be more */
17098943Sluigi} ipfw_insn_u16;
17196245Sluigi
17298943Sluigi/*
17398943Sluigi * This is used to store an array of 32-bit entries
17498943Sluigi * (uid, single IPv4 addresses etc.)
17598943Sluigi */
17698943Sluigitypedef struct	_ipfw_insn_u32 {
17798943Sluigi	ipfw_insn o;
17898943Sluigi	u_int32_t d[1];	/* one or more */
17998943Sluigi} ipfw_insn_u32;
18084058Sluigi
18198943Sluigi/*
18298943Sluigi * This is used to store IP addr-mask pairs.
18398943Sluigi */
18498943Sluigitypedef struct	_ipfw_insn_ip {
18598943Sluigi	ipfw_insn o;
18698943Sluigi	struct in_addr	addr;
18798943Sluigi	struct in_addr	mask;
18898943Sluigi} ipfw_insn_ip;
1893969Sjkh
19098943Sluigi/*
19198943Sluigi * This is used to forward to a given address (ip)
19298943Sluigi */
19398943Sluigitypedef struct  _ipfw_insn_sa {
19498943Sluigi	ipfw_insn o;
19598943Sluigi	struct sockaddr_in sa;
19698943Sluigi} ipfw_insn_sa;
19785665Sjoe
19898943Sluigi/*
19998943Sluigi * This is used for MAC addr-mask pairs.
20098943Sluigi */
20198943Sluigitypedef struct	_ipfw_insn_mac {
20298943Sluigi	ipfw_insn o;
20398943Sluigi	u_char addr[12];	/* dst[6] + src[6] */
20498943Sluigi	u_char mask[12];	/* dst[6] + src[6] */
20598943Sluigi} ipfw_insn_mac;
20685665Sjoe
20798943Sluigi/*
20898943Sluigi * This is used for interface match rules (recv xx, xmit xx)
20998943Sluigi */
21098943Sluigitypedef struct	_ipfw_insn_if {
21198943Sluigi	ipfw_insn o;
21298943Sluigi	union {
21398943Sluigi		struct in_addr ip;
21498943Sluigi		int unit;
21598943Sluigi	} p;
21698943Sluigi	char name[IFNAMSIZ];
21798943Sluigi} ipfw_insn_if;
21898943Sluigi
21998943Sluigi/*
22098943Sluigi * This is used for pipe and queue actions, which need to store
22198943Sluigi * a single pointer (which can have different size on different
22298943Sluigi * architectures.
22398943Sluigi */
22498943Sluigitypedef struct	_ipfw_insn_pipe {
22598943Sluigi	ipfw_insn	o;
22698943Sluigi	void		*pipe_ptr;
22798943Sluigi} ipfw_insn_pipe;
22898943Sluigi
22998943Sluigi/*
23098943Sluigi * This is used for limit rules.
23198943Sluigi */
23298943Sluigitypedef struct	_ipfw_insn_limit {
23398943Sluigi	ipfw_insn o;
23498943Sluigi	u_int8_t _pad;
23598943Sluigi	u_int8_t limit_mask;	/* combination of DYN_* below	*/
23684058Sluigi#define	DYN_SRC_ADDR	0x1
23784058Sluigi#define	DYN_SRC_PORT	0x2
23884058Sluigi#define	DYN_DST_ADDR	0x4
23984058Sluigi#define	DYN_DST_PORT	0x8
24085665Sjoe
24198943Sluigi	u_int16_t conn_limit;
24298943Sluigi} ipfw_insn_limit;
24349630Sluigi
24498943Sluigi/*
24598943Sluigi * This is used for log instructions
24698943Sluigi */
24798943Sluigitypedef struct  _ipfw_insn_log {
24898943Sluigi        ipfw_insn o;
24998943Sluigi	u_int32_t max_log;	/* how many do we log -- 0 = all */
25098943Sluigi	u_int32_t log_left;	/* how many left to log 	*/
25198943Sluigi} ipfw_insn_log;
25226359Sjulian
25385689Sjoe/*
25498943Sluigi * Here we have the structure representing an ipfw rule.
25583725Sluigi *
25698943Sluigi * It starts with a general area (with link fields and counters)
25798943Sluigi * followed by an array of one or more instructions, which the code
25898943Sluigi * accesses as an array of 32-bit values.
25983725Sluigi *
26098943Sluigi * Given a rule pointer  r:
26198943Sluigi *
26298943Sluigi *  r->cmd		is the start of the first instruction.
26398943Sluigi *  ACTION_PTR(r)	is the start of the first action (things to do
26498943Sluigi *			once a rule matched).
26598943Sluigi *
26698943Sluigi * When assembling instruction, remember the following:
26798943Sluigi *
26898943Sluigi *  + if a rule has a "keep-state" (or "limit") option, then the
26998943Sluigi *	first instruction (at r->cmd) MUST BE an O_PROBE_STATE
27098943Sluigi *  + if a rule has a "log" option, then the first action
27198943Sluigi *	(at ACTION_PTR(r)) MUST be O_LOG
27298943Sluigi *
27398943Sluigi * NOTE: we use a simple linked list of rules because we never need
27498943Sluigi * 	to delete a rule without scanning the list. We do not use
27598943Sluigi *	queue(3) macros for portability and readability.
27683725Sluigi */
27783725Sluigi
27898943Sluigistruct ip_fw {
279100004Sluigi	struct ip_fw	*next;		/* linked list of rules		*/
280101628Sluigi	struct ip_fw	*next_rule;	/* ptr to next [skipto] rule	*/
281105899Smux	u_int32_t	set_disable;	/* disabled sets (for userland)	*/
28298943Sluigi	u_int16_t	act_ofs;	/* offset of action in 32-bit units */
28398943Sluigi	u_int16_t	cmd_len;	/* # of 32-bit words in cmd	*/
28498943Sluigi	u_int16_t	rulenum;	/* rule number			*/
285101628Sluigi	u_int8_t	set;		/* rule set (0..31)		*/
286101628Sluigi	u_int8_t	_pad;		/* padding			*/
28798943Sluigi
28898943Sluigi	/* These fields are present in all rules.			*/
28998943Sluigi	u_int64_t	pcnt;		/* Packet counter		*/
29098943Sluigi	u_int64_t	bcnt;		/* Byte counter			*/
29198943Sluigi	u_int32_t	timestamp;	/* tv_sec of last match		*/
29298943Sluigi
29398943Sluigi	ipfw_insn	cmd[1];		/* storage for commands		*/
29498943Sluigi};
29598943Sluigi
29698943Sluigi#define ACTION_PTR(rule)				\
29798943Sluigi	(ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) )
29898943Sluigi
29998943Sluigi#define RULESIZE(rule)  (sizeof(struct ip_fw) + \
30098943Sluigi	((struct ip_fw *)(rule))->cmd_len * 4 - 4)
30198943Sluigi
3024277Sjkh/*
30398943Sluigi * This structure is used as a flow mask and a flow id for various
30498943Sluigi * parts of the code.
30557113Sluigi */
30657113Sluigistruct ipfw_flow_id {
30785665Sjoe	u_int32_t	dst_ip;
30885665Sjoe	u_int32_t	src_ip;
30985665Sjoe	u_int16_t	dst_port;
31085665Sjoe	u_int16_t	src_port;
31185665Sjoe	u_int8_t	proto;
31285665Sjoe	u_int8_t	flags;	/* protocol-specific flags */
31385665Sjoe};
31457113Sluigi
31557113Sluigi/*
31657113Sluigi * dynamic ipfw rule
31757113Sluigi */
31898943Sluigitypedef struct _ipfw_dyn_rule ipfw_dyn_rule;
31998943Sluigi
32098943Sluigistruct _ipfw_dyn_rule {
32198943Sluigi	ipfw_dyn_rule	*next;		/* linked list of rules.	*/
32298943Sluigi	struct ipfw_flow_id id;		/* (masked) flow id		*/
32398943Sluigi	struct ip_fw *rule;		/* pointer to rule		*/
32498943Sluigi	ipfw_dyn_rule *parent;		/* pointer to parent rule	*/
32598943Sluigi	u_int32_t	expire;		/* expire time			*/
32698943Sluigi	u_int64_t	pcnt;		/* packet match counter		*/
32798943Sluigi	u_int64_t	bcnt;		/* byte match counter		*/
32898943Sluigi	u_int32_t	bucket;		/* which bucket in hash table	*/
32985665Sjoe	u_int32_t	state;		/* state of this rule (typically a
33085665Sjoe					 * combination of TCP flags)
33185665Sjoe					 */
332100004Sluigi	u_int32_t	ack_fwd;	/* most recent ACKs in forward	*/
333100004Sluigi	u_int32_t	ack_rev;	/* and reverse directions (used	*/
334100004Sluigi					/* to generate keepalives)	*/
33598943Sluigi	u_int16_t	dyn_type;	/* rule type			*/
33698943Sluigi	u_int16_t	count;		/* refcount			*/
337105899Smux	u_int16_t	rulenum;	/* rule number (for userland)	*/
33885665Sjoe};
33957113Sluigi
34057113Sluigi/*
34111119Sugen * Definitions for IP option names.
34211119Sugen */
34385665Sjoe#define	IP_FW_IPOPT_LSRR	0x01
34485665Sjoe#define	IP_FW_IPOPT_SSRR	0x02
34585665Sjoe#define	IP_FW_IPOPT_RR		0x04
34685665Sjoe#define	IP_FW_IPOPT_TS		0x08
34711119Sugen
34811119Sugen/*
34961420Sdan * Definitions for TCP option names.
35061420Sdan */
35185665Sjoe#define	IP_FW_TCPOPT_MSS	0x01
35285665Sjoe#define	IP_FW_TCPOPT_WINDOW	0x02
35385665Sjoe#define	IP_FW_TCPOPT_SACK	0x04
35485665Sjoe#define	IP_FW_TCPOPT_TS		0x08
35585665Sjoe#define	IP_FW_TCPOPT_CC		0x10
35661420Sdan
35798943Sluigi#define	ICMP_REJECT_RST		0x100	/* fake ICMP code (send a TCP RST) */
35898943Sluigi
35961420Sdan/*
3604277Sjkh * Main firewall chains definitions and global var's definitions.
3614277Sjkh */
36255205Speter#ifdef _KERNEL
3635543Sugen
36485665Sjoe#define	IP_FW_PORT_DYNT_FLAG	0x10000
36585665Sjoe#define	IP_FW_PORT_TEE_FLAG	0x20000
36685665Sjoe#define	IP_FW_PORT_DENY_FLAG	0x40000
36754175Sarchie
3685543Sugen/*
36998943Sluigi * arguments for calling ipfw_chk() and dummynet_io(). We put them
37098613Sluigi * all into a structure because this way it is easier and more
37198613Sluigi * efficient to pass variables around and extend the interface.
37298613Sluigi */
37398613Sluigistruct ip_fw_args {
37498613Sluigi	struct mbuf	*m;		/* the mbuf chain		*/
37598613Sluigi	struct ifnet	*oif;		/* output interface		*/
37698613Sluigi	struct sockaddr_in *next_hop;	/* forward address		*/
37798613Sluigi	struct ip_fw	*rule;		/* matching rule		*/
37898613Sluigi	struct ether_header *eh;	/* for bridged packets		*/
37998613Sluigi
38098613Sluigi	struct route	*ro;		/* for dummynet			*/
38198613Sluigi	struct sockaddr_in *dst;	/* for dummynet			*/
38298613Sluigi	int flags;			/* for dummynet			*/
38398613Sluigi
38498613Sluigi	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
38598613Sluigi	u_int16_t	divert_rule;	/* divert cookie		*/
38698613Sluigi	u_int32_t	retval;
38798613Sluigi};
38898613Sluigi
38998613Sluigi/*
3905543Sugen * Function definitions.
3915543Sugen */
3925543Sugen
39338482Swollman/* Firewall hooks */
39438482Swollmanstruct sockopt;
39598943Sluigistruct dn_flow_set;
39698943Sluigi
39798943Sluigivoid flush_pipe_ptrs(struct dn_flow_set *match); /* used by dummynet */
39898943Sluigi
39998613Sluigitypedef int ip_fw_chk_t (struct ip_fw_args *args);
40085665Sjoetypedef int ip_fw_ctl_t (struct sockopt *);
40185665Sjoeextern ip_fw_chk_t *ip_fw_chk_ptr;
40285665Sjoeextern ip_fw_ctl_t *ip_fw_ctl_ptr;
40357113Sluigiextern int fw_one_pass;
40457113Sluigiextern int fw_enable;
40586047Sluigi#define	IPFW_LOADED	(ip_fw_chk_ptr != NULL)
40655205Speter#endif /* _KERNEL */
4073969Sjkh
40898943Sluigi#endif /* _IPFW2_H */
409