ip_fw.h revision 234834
173006Sjulian/*-
273006Sjulian * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
373006Sjulian *
473006Sjulian * Redistribution and use in source and binary forms, with or without
573006Sjulian * modification, are permitted provided that the following conditions
673006Sjulian * are met:
773006Sjulian * 1. Redistributions of source code must retain the above copyright
873006Sjulian *    notice, this list of conditions and the following disclaimer.
973006Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1073006Sjulian *    notice, this list of conditions and the following disclaimer in the
1173006Sjulian *    documentation and/or other materials provided with the distribution.
1273006Sjulian *
1373006Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1473006Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1573006Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1673006Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1773006Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1873006Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1973006Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2073006Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2173006Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2273006Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2373006Sjulian * SUCH DAMAGE.
2473006Sjulian *
2573006Sjulian * $FreeBSD: head/sys/netinet/ip_fw.h 234834 2012-04-30 10:22:23Z melifaro $
2673006Sjulian */
2773006Sjulian
2873006Sjulian#ifndef _IPFW2_H
2973006Sjulian#define _IPFW2_H
3073006Sjulian
3173006Sjulian/*
3273006Sjulian * The default rule number.  By the design of ip_fw, the default rule
3373006Sjulian * is the last one, so its number can also serve as the highest number
3473006Sjulian * allowed for a rule.  The ip_fw code relies on both meanings of this
3573006Sjulian * constant.
3673006Sjulian */
3773006Sjulian#define	IPFW_DEFAULT_RULE	65535
3873006Sjulian
3973006Sjulian/*
4073006Sjulian * Default number of ipfw tables.
4173006Sjulian */
4273006Sjulian#define	IPFW_TABLES_MAX		65535
4373006Sjulian#define	IPFW_TABLES_DEFAULT	128
4473083Sjulian
4573006Sjulian/*
4673006Sjulian * Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit
4773006Sjulian * argument between 1 and 65534. The value 0 is unused, the value
4873006Sjulian * 65535 (IP_FW_TABLEARG) is used to represent 'tablearg', i.e. the
4973006Sjulian * can be 1..65534, or 65535 to indicate the use of a 'tablearg'
5073006Sjulian * result of the most recent table() lookup.
5173006Sjulian * Note that 16bit is only a historical limit, resulting from
5273006Sjulian * the use of a 16-bit fields for that value. In reality, we can have
5373006Sjulian * 2^32 pipes, queues, tag values and so on, and use 0 as a tablearg.
5473006Sjulian */
5573006Sjulian#define	IPFW_ARG_MIN		1
5673006Sjulian#define	IPFW_ARG_MAX		65534
5773006Sjulian#define IP_FW_TABLEARG		65535	/* XXX should use 0 */
5873006Sjulian
5973006Sjulian/*
6073035Sjulian * Number of entries in the call stack of the call/return commands.
6173035Sjulian * Call stack currently is an uint16_t array with rule numbers.
6273035Sjulian */
6373035Sjulian#define	IPFW_CALLSTACK_SIZE	16
6473035Sjulian
65123601Sru/* IP_FW3 header/opcodes */
6673035Sjuliantypedef struct _ip_fw3_opheader {
6773035Sjulian	uint16_t opcode;	/* Operation opcode */
6873035Sjulian	uint16_t reserved[3];	/* Align to 64-bit boundary */
6973035Sjulian} ip_fw3_opheader;
7073035Sjulian
7173035Sjulian
7273006Sjulian/* IPFW extented tables support */
7373006Sjulian#define	IP_FW_TABLE_XADD	86	/* add entry */
74123549Sru#define	IP_FW_TABLE_XDEL	87	/* delete entry */
7573006Sjulian#define	IP_FW_TABLE_XGETSIZE	88	/* get table size */
7673006Sjulian#define	IP_FW_TABLE_XLIST	89	/* list table contents */
7773006Sjulian
7873006Sjulian/*
7973006Sjulian * The kernel representation of ipfw rules is made of a list of
8073006Sjulian * 'instructions' (for all practical purposes equivalent to BPF
8173006Sjulian * instructions), which specify which fields of the packet
8273006Sjulian * (or its metadata) should be analysed.
8373006Sjulian *
8473006Sjulian * Each instruction is stored in a structure which begins with
8573006Sjulian * "ipfw_insn", and can contain extra fields depending on the
8673006Sjulian * instruction type (listed below).
8773006Sjulian * Note that the code is written so that individual instructions
8873006Sjulian * have a size which is a multiple of 32 bits. This means that, if
8973006Sjulian * such structures contain pointers or other 64-bit entities,
9073006Sjulian * (there is just one instance now) they may end up unaligned on
9173006Sjulian * 64-bit architectures, so the must be handled with care.
9273006Sjulian *
9373006Sjulian * "enum ipfw_opcodes" are the opcodes supported. We can have up
9473006Sjulian * to 256 different opcodes. When adding new opcodes, they should
9573006Sjulian * be appended to the end of the opcode list before O_LAST_OPCODE,
9673006Sjulian * this will prevent the ABI from being broken, otherwise users
9773006Sjulian * will have to recompile ipfw(8) when they update the kernel.
9873006Sjulian */
9973006Sjulian
10073006Sjulianenum ipfw_opcodes {		/* arguments (4 byte each)	*/
10173035Sjulian	O_NOP,
10273006Sjulian
10373006Sjulian	O_IP_SRC,		/* u32 = IP			*/
10473006Sjulian	O_IP_SRC_MASK,		/* ip = IP/mask			*/
10573006Sjulian	O_IP_SRC_ME,		/* none				*/
10673006Sjulian	O_IP_SRC_SET,		/* u32=base, arg1=len, bitmap	*/
10773006Sjulian
10873006Sjulian	O_IP_DST,		/* u32 = IP			*/
10973006Sjulian	O_IP_DST_MASK,		/* ip = IP/mask			*/
11073006Sjulian	O_IP_DST_ME,		/* none				*/
11173006Sjulian	O_IP_DST_SET,		/* u32=base, arg1=len, bitmap	*/
11273006Sjulian
11373006Sjulian	O_IP_SRCPORT,		/* (n)port list:mask 4 byte ea	*/
11473006Sjulian	O_IP_DSTPORT,		/* (n)port list:mask 4 byte ea	*/
11573006Sjulian	O_PROTO,		/* arg1=protocol		*/
11673006Sjulian
11773006Sjulian	O_MACADDR2,		/* 2 mac addr:mask		*/
11873006Sjulian	O_MAC_TYPE,		/* same as srcport		*/
11973006Sjulian
12073006Sjulian	O_LAYER2,		/* none				*/
12173006Sjulian	O_IN,			/* none				*/
12273006Sjulian	O_FRAG,			/* none				*/
12373006Sjulian
12473006Sjulian	O_RECV,			/* none				*/
12573006Sjulian	O_XMIT,			/* none				*/
12673006Sjulian	O_VIA,			/* none				*/
12773006Sjulian
12873006Sjulian	O_IPOPT,		/* arg1 = 2*u8 bitmap		*/
12973006Sjulian	O_IPLEN,		/* arg1 = len			*/
13073006Sjulian	O_IPID,			/* arg1 = id			*/
13173006Sjulian
13273006Sjulian	O_IPTOS,		/* arg1 = id			*/
13373006Sjulian	O_IPPRECEDENCE,		/* arg1 = precedence << 5	*/
13473006Sjulian	O_IPTTL,		/* arg1 = TTL			*/
13573006Sjulian
13673006Sjulian	O_IPVER,		/* arg1 = version		*/
13773006Sjulian	O_UID,			/* u32 = id			*/
13873006Sjulian	O_GID,			/* u32 = id			*/
13973006Sjulian	O_ESTAB,		/* none (tcp established)	*/
14073006Sjulian	O_TCPFLAGS,		/* arg1 = 2*u8 bitmap		*/
14173006Sjulian	O_TCPWIN,		/* arg1 = desired win		*/
14273006Sjulian	O_TCPSEQ,		/* u32 = desired seq.		*/
14373006Sjulian	O_TCPACK,		/* u32 = desired seq.		*/
14473006Sjulian	O_ICMPTYPE,		/* u32 = icmp bitmap		*/
14573006Sjulian	O_TCPOPTS,		/* arg1 = 2*u8 bitmap		*/
14673006Sjulian
14773006Sjulian	O_VERREVPATH,		/* none				*/
14873006Sjulian	O_VERSRCREACH,		/* none				*/
14973006Sjulian
15073006Sjulian	O_PROBE_STATE,		/* none				*/
15173006Sjulian	O_KEEP_STATE,		/* none				*/
15273006Sjulian	O_LIMIT,		/* ipfw_insn_limit		*/
15373006Sjulian	O_LIMIT_PARENT,		/* dyn_type, not an opcode.	*/
15473006Sjulian
15573006Sjulian	/*
15673006Sjulian	 * These are really 'actions'.
15773006Sjulian	 */
15887599Sobrien
15973006Sjulian	O_LOG,			/* ipfw_insn_log		*/
16073006Sjulian	O_PROB,			/* u32 = match probability	*/
16173006Sjulian
16273006Sjulian	O_CHECK_STATE,		/* none				*/
16373006Sjulian	O_ACCEPT,		/* none				*/
16473006Sjulian	O_DENY,			/* none 			*/
16573006Sjulian	O_REJECT,		/* arg1=icmp arg (same as deny)	*/
16673006Sjulian	O_COUNT,		/* none				*/
16773006Sjulian	O_SKIPTO,		/* arg1=next rule number	*/
16873006Sjulian	O_PIPE,			/* arg1=pipe number		*/
16973006Sjulian	O_QUEUE,		/* arg1=queue number		*/
17073006Sjulian	O_DIVERT,		/* arg1=port number		*/
17173006Sjulian	O_TEE,			/* arg1=port number		*/
17273006Sjulian	O_FORWARD_IP,		/* fwd sockaddr			*/
17373006Sjulian	O_FORWARD_MAC,		/* fwd mac			*/
17473006Sjulian	O_NAT,                  /* nope                         */
17573006Sjulian	O_REASS,                /* none                         */
17687599Sobrien
17773006Sjulian	/*
17887599Sobrien	 * More opcodes.
17973006Sjulian	 */
18073006Sjulian	O_IPSEC,		/* has ipsec history 		*/
18173006Sjulian	O_IP_SRC_LOOKUP,	/* arg1=table number, u32=value	*/
18273006Sjulian	O_IP_DST_LOOKUP,	/* arg1=table number, u32=value	*/
18373006Sjulian	O_ANTISPOOF,		/* none				*/
18473006Sjulian	O_JAIL,			/* u32 = id			*/
18573006Sjulian	O_ALTQ,			/* u32 = altq classif. qid	*/
18673006Sjulian	O_DIVERTED,		/* arg1=bitmap (1:loop, 2:out)	*/
18773006Sjulian	O_TCPDATALEN,		/* arg1 = tcp data len		*/
18873006Sjulian	O_IP6_SRC,		/* address without mask		*/
18973006Sjulian	O_IP6_SRC_ME,		/* my addresses			*/
19073006Sjulian	O_IP6_SRC_MASK,		/* address with the mask	*/
19173006Sjulian	O_IP6_DST,
19273006Sjulian	O_IP6_DST_ME,
19373006Sjulian	O_IP6_DST_MASK,
19473006Sjulian	O_FLOW6ID,		/* for flow id tag in the ipv6 pkt */
19573006Sjulian	O_ICMP6TYPE,		/* icmp6 packet type filtering	*/
19673006Sjulian	O_EXT_HDR,		/* filtering for ipv6 extension header */
19773006Sjulian	O_IP6,
19873006Sjulian
19973006Sjulian	/*
20073006Sjulian	 * actions for ng_ipfw
20173006Sjulian	 */
20273006Sjulian	O_NETGRAPH,		/* send to ng_ipfw		*/
20373006Sjulian	O_NGTEE,		/* copy to ng_ipfw		*/
20473006Sjulian
20573006Sjulian	O_IP4,
20673006Sjulian
20773006Sjulian	O_UNREACH6,		/* arg1=icmpv6 code arg (deny)  */
20873006Sjulian
20973006Sjulian	O_TAG,   		/* arg1=tag number */
21073006Sjulian	O_TAGGED,		/* arg1=tag number */
21173006Sjulian
21273006Sjulian	O_SETFIB,		/* arg1=FIB number */
21373006Sjulian	O_FIB,			/* arg1=FIB desired fib number */
21473006Sjulian
21573006Sjulian	O_SOCKARG,		/* socket argument */
21673006Sjulian
21773006Sjulian	O_CALLRETURN,		/* arg1=called rule number */
21873006Sjulian
21973006Sjulian	O_FORWARD_IP6,		/* fwd sockaddr_in6             */
22073006Sjulian
22173006Sjulian	O_LAST_OPCODE		/* not an opcode!		*/
22273006Sjulian};
22373006Sjulian
22473006Sjulian
22573006Sjulian/*
22673006Sjulian * The extension header are filtered only for presence using a bit
22773006Sjulian * vector with a flag for each header.
22873006Sjulian */
22973006Sjulian#define EXT_FRAGMENT	0x1
23073006Sjulian#define EXT_HOPOPTS	0x2
23173006Sjulian#define EXT_ROUTING	0x4
23273006Sjulian#define EXT_AH		0x8
23373006Sjulian#define EXT_ESP		0x10
23473006Sjulian#define EXT_DSTOPTS	0x20
23573006Sjulian#define EXT_RTHDR0		0x40
23673006Sjulian#define EXT_RTHDR2		0x80
23773006Sjulian
23873006Sjulian/*
23973006Sjulian * Template for instructions.
24073006Sjulian *
24173006Sjulian * ipfw_insn is used for all instructions which require no operands,
24273006Sjulian * a single 16-bit value (arg1), or a couple of 8-bit values.
24373006Sjulian *
24473006Sjulian * For other instructions which require different/larger arguments
24573006Sjulian * we have derived structures, ipfw_insn_*.
24673006Sjulian *
24773006Sjulian * The size of the instruction (in 32-bit words) is in the low
24873006Sjulian * 6 bits of "len". The 2 remaining bits are used to implement
24973006Sjulian * NOT and OR on individual instructions. Given a type, you can
25073006Sjulian * compute the length to be put in "len" using F_INSN_SIZE(t)
25173006Sjulian *
25273006Sjulian * F_NOT	negates the match result of the instruction.
25373006Sjulian *
25473006Sjulian * F_OR		is used to build or blocks. By default, instructions
25573006Sjulian *		are evaluated as part of a logical AND. An "or" block
25673006Sjulian *		{ X or Y or Z } contains F_OR set in all but the last
25773006Sjulian *		instruction of the block. A match will cause the code
25873006Sjulian *		to skip past the last instruction of the block.
25973006Sjulian *
26073006Sjulian * NOTA BENE: in a couple of places we assume that
26173006Sjulian *	sizeof(ipfw_insn) == sizeof(u_int32_t)
26273006Sjulian * this needs to be fixed.
26373006Sjulian *
26473006Sjulian */
26573006Sjuliantypedef struct	_ipfw_insn {	/* template for instructions */
26673006Sjulian	u_int8_t 	opcode;
26773006Sjulian	u_int8_t	len;	/* number of 32-bit words */
26873006Sjulian#define	F_NOT		0x80
26973006Sjulian#define	F_OR		0x40
27073006Sjulian#define	F_LEN_MASK	0x3f
27173006Sjulian#define	F_LEN(cmd)	((cmd)->len & F_LEN_MASK)
27273006Sjulian
27373006Sjulian	u_int16_t	arg1;
27473006Sjulian} ipfw_insn;
27573006Sjulian
27673006Sjulian/*
27773006Sjulian * The F_INSN_SIZE(type) computes the size, in 4-byte words, of
27873006Sjulian * a given type.
27973006Sjulian */
28073006Sjulian#define	F_INSN_SIZE(t)	((sizeof (t))/sizeof(u_int32_t))
28173035Sjulian
28273035Sjulian/*
28373035Sjulian * This is used to store an array of 16-bit entries (ports etc.)
28473006Sjulian */
28573006Sjuliantypedef struct	_ipfw_insn_u16 {
28673035Sjulian	ipfw_insn o;
28773006Sjulian	u_int16_t ports[2];	/* there may be more */
28873035Sjulian} ipfw_insn_u16;
28973006Sjulian
29073006Sjulian/*
29173006Sjulian * This is used to store an array of 32-bit entries
29273006Sjulian * (uid, single IPv4 addresses etc.)
29373006Sjulian */
29473006Sjuliantypedef struct	_ipfw_insn_u32 {
29573006Sjulian	ipfw_insn o;
29673006Sjulian	u_int32_t d[1];	/* one or more */
29773006Sjulian} ipfw_insn_u32;
29873006Sjulian
29973006Sjulian/*
30073006Sjulian * This is used to store IP addr-mask pairs.
30173006Sjulian */
30273006Sjuliantypedef struct	_ipfw_insn_ip {
30373006Sjulian	ipfw_insn o;
30473006Sjulian	struct in_addr	addr;
30573006Sjulian	struct in_addr	mask;
30673006Sjulian} ipfw_insn_ip;
30773006Sjulian
30873006Sjulian/*
30973006Sjulian * This is used to forward to a given address (ip).
31073006Sjulian */
31173006Sjuliantypedef struct  _ipfw_insn_sa {
31273006Sjulian	ipfw_insn o;
31373006Sjulian	struct sockaddr_in sa;
31473006Sjulian} ipfw_insn_sa;
31573006Sjulian
31673035Sjulian/*
31773006Sjulian * This is used to forward to a given address (ipv6).
318106933Ssam */
31973006Sjuliantypedef struct _ipfw_insn_sa6 {
32073006Sjulian	ipfw_insn o;
32173006Sjulian	struct sockaddr_in6 sa;
32273006Sjulian} ipfw_insn_sa6;
32373006Sjulian
32473006Sjulian/*
32573006Sjulian * This is used for MAC addr-mask pairs.
32673006Sjulian */
32773006Sjuliantypedef struct	_ipfw_insn_mac {
32873006Sjulian	ipfw_insn o;
32973006Sjulian	u_char addr[12];	/* dst[6] + src[6] */
33073006Sjulian	u_char mask[12];	/* dst[6] + src[6] */
33173006Sjulian} ipfw_insn_mac;
33273006Sjulian
33373006Sjulian/*
33473006Sjulian * This is used for interface match rules (recv xx, xmit xx).
33573006Sjulian */
33673006Sjuliantypedef struct	_ipfw_insn_if {
33773006Sjulian	ipfw_insn o;
33873035Sjulian	union {
33973035Sjulian		struct in_addr ip;
34073035Sjulian		int glob;
34173035Sjulian	} p;
34273035Sjulian	char name[IFNAMSIZ];
34373035Sjulian} ipfw_insn_if;
34473035Sjulian
34573035Sjulian/*
34673035Sjulian * This is used for storing an altq queue id number.
34773035Sjulian */
34873035Sjuliantypedef struct _ipfw_insn_altq {
34973035Sjulian	ipfw_insn	o;
35073035Sjulian	u_int32_t	qid;
35173035Sjulian} ipfw_insn_altq;
35273035Sjulian
35373035Sjulian/*
35473035Sjulian * This is used for limit rules.
35573035Sjulian */
35673035Sjuliantypedef struct	_ipfw_insn_limit {
35773035Sjulian	ipfw_insn o;
35873035Sjulian	u_int8_t _pad;
35973035Sjulian	u_int8_t limit_mask;	/* combination of DYN_* below	*/
36073006Sjulian#define	DYN_SRC_ADDR	0x1
36173006Sjulian#define	DYN_SRC_PORT	0x2
36273006Sjulian#define	DYN_DST_ADDR	0x4
36373006Sjulian#define	DYN_DST_PORT	0x8
36473006Sjulian
36573006Sjulian	u_int16_t conn_limit;
36673006Sjulian} ipfw_insn_limit;
36773006Sjulian
36873006Sjulian/*
36973006Sjulian * This is used for log instructions.
37073006Sjulian */
37173006Sjuliantypedef struct  _ipfw_insn_log {
37273006Sjulian        ipfw_insn o;
37373006Sjulian	u_int32_t max_log;	/* how many do we log -- 0 = all */
37473006Sjulian	u_int32_t log_left;	/* how many left to log 	*/
37573006Sjulian} ipfw_insn_log;
37673006Sjulian
37773006Sjulian/*
37873006Sjulian * Data structures required by both ipfw(8) and ipfw(4) but not part of the
37973006Sjulian * management API are protected by IPFW_INTERNAL.
38073006Sjulian */
38173006Sjulian#ifdef IPFW_INTERNAL
38273006Sjulian/* Server pool support (LSNAT). */
38373006Sjulianstruct cfg_spool {
38473006Sjulian	LIST_ENTRY(cfg_spool)   _next;          /* chain of spool instances */
38573006Sjulian	struct in_addr          addr;
386121816Sbrooks	u_short                 port;
387121816Sbrooks};
38873006Sjulian#endif
38973006Sjulian
39073006Sjulian/* Redirect modes id. */
39173006Sjulian#define REDIR_ADDR      0x01
39273006Sjulian#define REDIR_PORT      0x02
39373006Sjulian#define REDIR_PROTO     0x04
39473006Sjulian
39573006Sjulian#ifdef IPFW_INTERNAL
39673006Sjulian/* Nat redirect configuration. */
39773006Sjulianstruct cfg_redir {
39873006Sjulian	LIST_ENTRY(cfg_redir)   _next;          /* chain of redir instances */
39973006Sjulian	u_int16_t               mode;           /* type of redirect mode */
40073006Sjulian	struct in_addr	        laddr;          /* local ip address */
40173006Sjulian	struct in_addr	        paddr;          /* public ip address */
40273006Sjulian	struct in_addr	        raddr;          /* remote ip address */
40373006Sjulian	u_short                 lport;          /* local port */
40473006Sjulian	u_short                 pport;          /* public port */
40573006Sjulian	u_short                 rport;          /* remote port  */
40673006Sjulian	u_short                 pport_cnt;      /* number of public ports */
40773006Sjulian	u_short                 rport_cnt;      /* number of remote ports */
40873006Sjulian	int                     proto;          /* protocol: tcp/udp */
40973006Sjulian	struct alias_link       **alink;
410111119Simp	/* num of entry in spool chain */
41173006Sjulian	u_int16_t               spool_cnt;
41273006Sjulian	/* chain of spool instances */
41373006Sjulian	LIST_HEAD(spool_chain, cfg_spool) spool_chain;
41473006Sjulian};
41573006Sjulian#endif
41673006Sjulian
41773006Sjulian#ifdef IPFW_INTERNAL
41873006Sjulian/* Nat configuration data struct. */
41973006Sjulianstruct cfg_nat {
42073006Sjulian	/* chain of nat instances */
42173006Sjulian	LIST_ENTRY(cfg_nat)     _next;
42273006Sjulian	int                     id;                     /* nat id */
42373006Sjulian	struct in_addr          ip;                     /* nat ip address */
42473006Sjulian	char                    if_name[IF_NAMESIZE];   /* interface name */
42573006Sjulian	int                     mode;                   /* aliasing mode */
42673006Sjulian	struct libalias	        *lib;                   /* libalias instance */
42773006Sjulian	/* number of entry in spool chain */
42873006Sjulian	int                     redir_cnt;
42973006Sjulian	/* chain of redir instances */
43073006Sjulian	LIST_HEAD(redir_chain, cfg_redir) redir_chain;
43173006Sjulian};
43273006Sjulian#endif
433121816Sbrooks
43473006Sjulian#define SOF_NAT         sizeof(struct cfg_nat)
43573006Sjulian#define SOF_REDIR       sizeof(struct cfg_redir)
43673006Sjulian#define SOF_SPOOL       sizeof(struct cfg_spool)
43773006Sjulian
43873006Sjulian/* Nat command. */
43973006Sjuliantypedef struct	_ipfw_insn_nat {
44073006Sjulian 	ipfw_insn	o;
44173006Sjulian 	struct cfg_nat *nat;
44273006Sjulian} ipfw_insn_nat;
44373006Sjulian
444121816Sbrooks/* Apply ipv6 mask on ipv6 addr */
44573006Sjulian#define APPLY_MASK(addr,mask)                          \
44673006Sjulian    (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \
44773006Sjulian    (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \
44873006Sjulian    (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \
449106933Ssam    (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3];
45073006Sjulian
45173006Sjulian/* Structure for ipv6 */
45273006Sjuliantypedef struct _ipfw_insn_ip6 {
45373006Sjulian       ipfw_insn o;
45473006Sjulian       struct in6_addr addr6;
45573006Sjulian       struct in6_addr mask6;
45673006Sjulian} ipfw_insn_ip6;
45773006Sjulian
45873006Sjulian/* Used to support icmp6 types */
45973006Sjuliantypedef struct _ipfw_insn_icmp6 {
46073006Sjulian       ipfw_insn o;
46173006Sjulian       uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h
46273006Sjulian                       *     define ICMP6_MAXTYPE
46373006Sjulian                       *     as follows: n = ICMP6_MAXTYPE/32 + 1
46473006Sjulian                        *     Actually is 203
46573006Sjulian                       */
46673006Sjulian} ipfw_insn_icmp6;
46773006Sjulian
46873006Sjulian/*
46973006Sjulian * Here we have the structure representing an ipfw rule.
47073006Sjulian *
47173006Sjulian * It starts with a general area (with link fields and counters)
47273006Sjulian * followed by an array of one or more instructions, which the code
47373006Sjulian * accesses as an array of 32-bit values.
47473006Sjulian *
47573006Sjulian * Given a rule pointer  r:
47673006Sjulian *
47773006Sjulian *  r->cmd		is the start of the first instruction.
47873006Sjulian *  ACTION_PTR(r)	is the start of the first action (things to do
47973006Sjulian *			once a rule matched).
48073006Sjulian *
48173006Sjulian * When assembling instruction, remember the following:
48273006Sjulian *
48373006Sjulian *  + if a rule has a "keep-state" (or "limit") option, then the
48473006Sjulian *	first instruction (at r->cmd) MUST BE an O_PROBE_STATE
48573006Sjulian *  + if a rule has a "log" option, then the first action
48673006Sjulian *	(at ACTION_PTR(r)) MUST be O_LOG
48773006Sjulian *  + if a rule has an "altq" option, it comes after "log"
48873006Sjulian *  + if a rule has an O_TAG option, it comes after "log" and "altq"
48973006Sjulian *
49073006Sjulian * NOTE: we use a simple linked list of rules because we never need
491123601Sru * 	to delete a rule without scanning the list. We do not use
49273083Sjulian *	queue(3) macros for portability and readability.
49373083Sjulian */
49473006Sjulian
495123601Srustruct ip_fw {
49673006Sjulian	struct ip_fw	*x_next;	/* linked list of rules		*/
49773006Sjulian	struct ip_fw	*next_rule;	/* ptr to next [skipto] rule	*/
49873006Sjulian	/* 'next_rule' is used to pass up 'set_disable' status		*/
499123601Sru
500123601Sru	uint16_t	act_ofs;	/* offset of action in 32-bit units */
50173006Sjulian	uint16_t	cmd_len;	/* # of 32-bit words in cmd	*/
50273083Sjulian	uint16_t	rulenum;	/* rule number			*/
50373083Sjulian	uint8_t	set;		/* rule set (0..31)		*/
50473083Sjulian#define	RESVD_SET	31	/* set for default and persistent rules */
50573083Sjulian	uint8_t		_pad;		/* padding			*/
50673083Sjulian	uint32_t	id;		/* rule id */
50773083Sjulian
50873083Sjulian	/* These fields are present in all rules.			*/
50973083Sjulian	uint64_t	pcnt;		/* Packet counter		*/
51073083Sjulian	uint64_t	bcnt;		/* Byte counter			*/
51173083Sjulian	uint32_t	timestamp;	/* tv_sec of last match		*/
51273006Sjulian
51373006Sjulian	ipfw_insn	cmd[1];		/* storage for commands		*/
51473006Sjulian};
51573006Sjulian
51673006Sjulian#define ACTION_PTR(rule)				\
51773006Sjulian	(ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) )
51873006Sjulian
51973006Sjulian#define RULESIZE(rule)  (sizeof(struct ip_fw) + \
52073006Sjulian	((struct ip_fw *)(rule))->cmd_len * 4 - 4)
52173006Sjulian
52273006Sjulian#if 1 // should be moved to in.h
52373006Sjulian/*
52473006Sjulian * This structure is used as a flow mask and a flow id for various
525121816Sbrooks * parts of the code.
526121816Sbrooks * addr_type is used in userland and kernel to mark the address type.
52773006Sjulian * fib is used in the kernel to record the fib in use.
52873006Sjulian * _flags is used in the kernel to store tcp flags for dynamic rules.
52973006Sjulian */
53073006Sjulianstruct ipfw_flow_id {
53173006Sjulian	uint32_t	dst_ip;
53273006Sjulian	uint32_t	src_ip;
53373006Sjulian	uint16_t	dst_port;
53473006Sjulian	uint16_t	src_port;
53573006Sjulian	uint8_t		fib;
53673006Sjulian	uint8_t		proto;
53773006Sjulian	uint8_t		_flags;	/* protocol-specific flags */
53873006Sjulian	uint8_t		addr_type; /* 4=ip4, 6=ip6, 1=ether ? */
53973006Sjulian	struct in6_addr dst_ip6;
54073006Sjulian	struct in6_addr src_ip6;
54173006Sjulian	uint32_t	flow_id6;
54273006Sjulian	uint32_t	extra; /* queue/pipe or frag_id */
54373006Sjulian};
54473006Sjulian#endif
54573006Sjulian
54673006Sjulian#define IS_IP6_FLOW_ID(id)	((id)->addr_type == 6)
54773006Sjulian
54873006Sjulian#ifdef _KERNEL
54973006Sjulian/* Return values from ipfw_[ether_]chk() */
55073006Sjulianenum {
55173006Sjulian	IP_FW_PASS = 0,
55273006Sjulian	IP_FW_DENY,
553121816Sbrooks	IP_FW_DIVERT,
554121816Sbrooks	IP_FW_TEE,
55573006Sjulian	IP_FW_DUMMYNET,
55673006Sjulian	IP_FW_NETGRAPH,
55773006Sjulian	IP_FW_NGTEE,
55873006Sjulian	IP_FW_NAT,
55973006Sjulian	IP_FW_REASS,
56073006Sjulian};
56173006Sjulian
56273006Sjulian/*
56373006Sjulian * Hooks sometime need to know the direction of the packet
56473006Sjulian * (divert, dummynet, netgraph, ...)
56573006Sjulian * We use a generic definition here, with bit0-1 indicating the
56673006Sjulian * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
56773006Sjulian * specific protocol (if necessary)
56873006Sjulian */
56973006Sjulianenum {
57073006Sjulian	DIR_MASK =	0x3,
57173006Sjulian	DIR_OUT =	0,
57273006Sjulian	DIR_IN =	1,
57373006Sjulian	DIR_FWD =	2,
57473006Sjulian	DIR_DROP =	3,
57573006Sjulian	PROTO_LAYER2 =	0x4, /* set for layer 2 */
57673006Sjulian	/* PROTO_DEFAULT = 0, */
57773006Sjulian	PROTO_IPV4 =	0x08,
57873006Sjulian	PROTO_IPV6 =	0x10,
57973006Sjulian	PROTO_IFB =	0x0c, /* layer2 + ifbridge */
58073006Sjulian   /*	PROTO_OLDBDG =	0x14, unused, old bridge */
58173006Sjulian};
58273006Sjulian
58373006Sjulian/*
58473006Sjulian * Structure for collecting parameters to dummynet for ip6_output forwarding
58573006Sjulian */
58673006Sjulianstruct _ip6dn_args {
58773006Sjulian       struct ip6_pktopts *opt_or;
58873006Sjulian       struct route_in6 ro_or;
58973006Sjulian       int flags_or;
59073006Sjulian       struct ip6_moptions *im6o_or;
59173006Sjulian       struct ifnet *origifp_or;
59273006Sjulian       struct ifnet *ifp_or;
59373006Sjulian       struct sockaddr_in6 dst_or;
59473006Sjulian       u_long mtu_or;
59573006Sjulian       struct route_in6 ro_pmtu_or;
59673006Sjulian};
59773006Sjulian
598122864Sru/*
599122864Sru * Arguments for calling ipfw_chk() and dummynet_io(). We put them
60073006Sjulian * all into a structure because this way it is easier and more
60173006Sjulian * efficient to pass variables around and extend the interface.
60273006Sjulian */
60373006Sjulianstruct ip_fw_args {
60473006Sjulian	struct mbuf	*m;		/* the mbuf chain		*/
60573006Sjulian	struct ifnet	*oif;		/* output interface		*/
60673006Sjulian	struct sockaddr_in *next_hop;	/* forward address		*/
60773006Sjulian	struct sockaddr_in6 *next_hop6; /* ipv6 forward address		*/
60873006Sjulian
609106933Ssam	/*
61073006Sjulian	 * On return, it points to the matching rule.
61173006Sjulian	 * On entry, rule.slot > 0 means the info is valid and
612106933Ssam	 * contains the starting rule for an ipfw search.
61373006Sjulian	 * If chain_id == chain->id && slot >0 then jump to that slot.
61473006Sjulian	 * Otherwise, we locate the first rule >= rulenum:rule_id
61573006Sjulian	 */
61673006Sjulian	struct ipfw_rule_ref rule;	/* match/restart info		*/
61773006Sjulian
61873006Sjulian	struct ether_header *eh;	/* for bridged packets		*/
61973006Sjulian
62073006Sjulian	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
62173006Sjulian	//uint32_t	cookie;		/* a cookie depending on rule action */
62273006Sjulian	struct inpcb	*inp;
62373006Sjulian
624106933Ssam	struct _ip6dn_args	dummypar; /* dummynet->ip6_output */
62573006Sjulian	struct sockaddr_in hopstore;	/* store here if cannot use a pointer */
62673006Sjulian};
62773006Sjulian
62873006Sjulian#endif	/* _KERNEL */
62973006Sjulian
63073006Sjulian/*
63173006Sjulian * Dynamic ipfw rule.
63273006Sjulian */
63373006Sjuliantypedef struct _ipfw_dyn_rule ipfw_dyn_rule;
63473006Sjulian
63573006Sjulianstruct _ipfw_dyn_rule {
63673006Sjulian	ipfw_dyn_rule	*next;		/* linked list of rules.	*/
63773006Sjulian	struct ip_fw *rule;		/* pointer to rule		*/
63873006Sjulian	/* 'rule' is used to pass up the rule number (from the parent)	*/
63973006Sjulian
64073006Sjulian	ipfw_dyn_rule *parent;		/* pointer to parent rule	*/
64173006Sjulian	u_int64_t	pcnt;		/* packet match counter		*/
64273006Sjulian	u_int64_t	bcnt;		/* byte match counter		*/
64373006Sjulian	struct ipfw_flow_id id;		/* (masked) flow id		*/
64473006Sjulian	u_int32_t	expire;		/* expire time			*/
64573006Sjulian	u_int32_t	bucket;		/* which bucket in hash table	*/
64673006Sjulian	u_int32_t	state;		/* state of this rule (typically a
64773006Sjulian					 * combination of TCP flags)
64873006Sjulian					 */
64973006Sjulian	u_int32_t	ack_fwd;	/* most recent ACKs in forward	*/
65073006Sjulian	u_int32_t	ack_rev;	/* and reverse directions (used	*/
65173006Sjulian					/* to generate keepalives)	*/
65273006Sjulian	u_int16_t	dyn_type;	/* rule type			*/
65373006Sjulian	u_int16_t	count;		/* refcount			*/
65473006Sjulian};
655
656/*
657 * Definitions for IP option names.
658 */
659#define	IP_FW_IPOPT_LSRR	0x01
660#define	IP_FW_IPOPT_SSRR	0x02
661#define	IP_FW_IPOPT_RR		0x04
662#define	IP_FW_IPOPT_TS		0x08
663
664/*
665 * Definitions for TCP option names.
666 */
667#define	IP_FW_TCPOPT_MSS	0x01
668#define	IP_FW_TCPOPT_WINDOW	0x02
669#define	IP_FW_TCPOPT_SACK	0x04
670#define	IP_FW_TCPOPT_TS		0x08
671#define	IP_FW_TCPOPT_CC		0x10
672
673#define	ICMP_REJECT_RST		0x100	/* fake ICMP code (send a TCP RST) */
674#define	ICMP6_UNREACH_RST	0x100	/* fake ICMPv6 code (send a TCP RST) */
675
676/*
677 * These are used for lookup tables.
678 */
679
680#define	IPFW_TABLE_CIDR		1	/* Table for holding IPv4/IPv6 prefixes */
681#define	IPFW_TABLE_INTERFACE	2	/* Table for holding interface names */
682#define	IPFW_TABLE_MAXTYPE	2	/* Maximum valid number */
683
684typedef struct	_ipfw_table_entry {
685	in_addr_t	addr;		/* network address		*/
686	u_int32_t	value;		/* value			*/
687	u_int16_t	tbl;		/* table number			*/
688	u_int8_t	masklen;	/* mask length			*/
689} ipfw_table_entry;
690
691typedef struct	_ipfw_table_xentry {
692	uint16_t	len;		/* Total entry length		*/
693	uint8_t		type;		/* entry type			*/
694	uint8_t		masklen;	/* mask length			*/
695	uint16_t	tbl;		/* table number			*/
696	uint32_t	value;		/* value			*/
697	union {
698		/* Longest field needs to be aligned by 4-byte boundary	*/
699		struct in6_addr	addr6;	/* IPv6 address 		*/
700		char	iface[IF_NAMESIZE];	/* interface name	*/
701	} k;
702} ipfw_table_xentry;
703
704typedef struct	_ipfw_table {
705	u_int32_t	size;		/* size of entries in bytes	*/
706	u_int32_t	cnt;		/* # of entries			*/
707	u_int16_t	tbl;		/* table number			*/
708	ipfw_table_entry ent[0];	/* entries			*/
709} ipfw_table;
710
711typedef struct	_ipfw_xtable {
712	ip_fw3_opheader	opheader;	/* eXtended tables are controlled via IP_FW3 */
713	uint32_t	size;		/* size of entries in bytes	*/
714	uint32_t	cnt;		/* # of entries			*/
715	uint16_t	tbl;		/* table number			*/
716	uint8_t		type;		/* table type			*/
717	ipfw_table_xentry xent[0];	/* entries			*/
718} ipfw_xtable;
719
720#endif /* _IPFW2_H */
721