ip_fw.h revision 85689
13969Sjkh/*
23969Sjkh * Copyright (c) 1993 Daniel Boulet
33969Sjkh * Copyright (c) 1994 Ugen J.S.Antsilevich
43969Sjkh *
53969Sjkh * Redistribution and use in source forms, with and without modification,
63969Sjkh * are permitted provided that this entire comment appears intact.
73969Sjkh *
83969Sjkh * Redistribution in binary form may occur without any restrictions.
93969Sjkh * Obviously, it would be nice if you gave credit where credit is due
103969Sjkh * but requiring it would be too onerous.
113969Sjkh *
123969Sjkh * This software is provided ``AS IS'' without any warranties of any kind.
139661Sdg *
1450477Speter * $FreeBSD: head/sys/netinet/ip_fw.h 85689 2001-10-29 15:09:07Z joe $
153969Sjkh */
163969Sjkh
1726359Sjulian#ifndef _IP_FW_H
1826359Sjulian#define _IP_FW_H
1926359Sjulian
2033058Sbde#include <sys/queue.h>
2133058Sbde
223969Sjkh/*
2326359Sjulian * This union structure identifies an interface, either explicitly
2426359Sjulian * by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
2526359Sjulian * and IP_FW_F_OIFNAME say how to interpret this structure. An
2626359Sjulian * interface unit number of -1 matches any unit number, while an
2726359Sjulian * IP address of 0.0.0.0 indicates matches any interface.
2826359Sjulian *
2926359Sjulian * The receive and transmit interfaces are only compared against the
3026359Sjulian * the packet if the corresponding bit (IP_FW_F_IIFACE or IP_FW_F_OIFACE)
3126359Sjulian * is set. Note some packets lack a receive or transmit interface
3226359Sjulian * (in which case the missing "interface" never matches).
3326359Sjulian */
3426359Sjulian
3526359Sjulianunion ip_fw_if {
3685665Sjoe	struct in_addr	fu_via_ip;	/* Specified by IP address */
3785665Sjoe	struct {			/* Specified by interface name */
3885665Sjoe#define FW_IFNLEN	10		/* need room ! was IFNAMSIZ */
3985665Sjoe		char	name[FW_IFNLEN];
4085665Sjoe		short	unit;		/* -1 means match any unit */
4185665Sjoe	} fu_via_if;
4226359Sjulian};
4326359Sjulian
4426359Sjulian/*
453969Sjkh * Format of an IP firewall descriptor
463969Sjkh *
475089Sugen * fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
485089Sugen * fw_flg and fw_n*p are stored in host byte order (of course).
493969Sjkh * Port numbers are stored in HOST byte order.
503969Sjkh */
513969Sjkh
524277Sjkhstruct ip_fw {
5385665Sjoe	LIST_ENTRY(ip_fw) next;		/* bidirectional list of rules */
5485665Sjoe	u_int		fw_flg;		/* Operational Flags word */
5585665Sjoe	u_int64_t	fw_pcnt;	/* Packet counters */
5685665Sjoe	u_int64_t	fw_bcnt;	/* Byte counters */
5785665Sjoe	struct in_addr	fw_src;		/* Source IP address */
5885665Sjoe	struct in_addr	fw_dst;		/* Destination IP address */
5985665Sjoe	struct in_addr	fw_smsk;	/* Mask for source IP address */
6085665Sjoe	struct in_addr	fw_dmsk;	/* Mask for destination address */
6185665Sjoe	u_short		fw_number;	/* Rule number */
6285665Sjoe	u_char		fw_prot;	/* IP protocol */
6384058Sluigi#if 1
6485665Sjoe	u_char		fw_nports;	/* # of src/dst port in array */
6585665Sjoe#define	IP_FW_GETNSRCP(rule)		((rule)->fw_nports & 0x0f)
6685665Sjoe#define	IP_FW_SETNSRCP(rule, n)		do {				\
6784058Sluigi					    (rule)->fw_nports &= ~0x0f;	\
6884058Sluigi					    (rule)->fw_nports |= (n);	\
6984058Sluigi					} while (0)
7085665Sjoe#define	IP_FW_GETNDSTP(rule)		((rule)->fw_nports >> 4)
7185665Sjoe#define	IP_FW_SETNDSTP(rule, n)		do {				  \
7285665Sjoe					    (rule)->fw_nports &= ~0xf0;	  \
7384058Sluigi					    (rule)->fw_nports |= (n) << 4;\
7484058Sluigi					} while (0)
7585665Sjoe#define	IP_FW_HAVEPORTS(rule)		((rule)->fw_nports != 0)
7684058Sluigi#else
7785665Sjoe	u_char		__pad[1];
7885665Sjoe	u_int		_nsrcp;
7985665Sjoe	u_int		_ndstp;
8085665Sjoe#define	IP_FW_GETNSRCP(rule)		(rule)->_nsrcp
8185665Sjoe#define	IP_FW_SETNSRCP(rule,n)		(rule)->_nsrcp = n
8285665Sjoe#define	IP_FW_GETNDSTP(rule)		(rule)->_ndstp
8385665Sjoe#define	IP_FW_SETNDSTP(rule,n)		(rule)->_ndstp = n
8485665Sjoe#define	IP_FW_HAVEPORTS(rule)		((rule)->_ndstp + (rule)->_nsrcp != 0)
8584058Sluigi#endif
8685665Sjoe#define	IP_FW_MAX_PORTS	10		/* A reasonable maximum */
8784058Sluigi    union {
8885665Sjoe	u_short		fw_pts[IP_FW_MAX_PORTS]; /* port numbers to match */
8985665Sjoe#define	IP_FW_ICMPTYPES_MAX	128
9085665Sjoe#define	IP_FW_ICMPTYPES_DIM	(IP_FW_ICMPTYPES_MAX / (sizeof(unsigned) * 8))
9185665Sjoe	unsigned	fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /*ICMP types bitmap*/
9284058Sluigi    } fw_uar;
9384058Sluigi
9485665Sjoe	u_int		fw_ipflg;	/* IP flags word */
9585665Sjoe	u_short		fw_iplen;	/* IP length */
9685665Sjoe	u_short		fw_ipid;	/* Identification */
9785665Sjoe	u_char		fw_ipopt;	/* IP options set */
9885665Sjoe	u_char		fw_ipnopt;	/* IP options unset */
9985665Sjoe	u_char		fw_iptos;	/* IP type of service set */
10085665Sjoe	u_char		fw_ipntos;	/* IP type of service unset */
10185665Sjoe	u_char		fw_ipttl;	/* IP time to live */
10285665Sjoe	u_int		fw_ipver:4;	/* IP version */
10385665Sjoe	u_char		fw_tcpopt;	/* TCP options set */
10485665Sjoe	u_char		fw_tcpnopt;	/* TCP options unset */
10585665Sjoe	u_char		fw_tcpf;	/* TCP flags set */
10685665Sjoe	u_char		fw_tcpnf;	/* TCP flags unset */
10785665Sjoe	u_short		fw_tcpwin;	/* TCP window size */
10885665Sjoe	u_int32_t	fw_tcpseq;	/* TCP sequence */
10985665Sjoe	u_int32_t	fw_tcpack;	/* TCP acknowledgement */
11085665Sjoe	long		timestamp;	/* timestamp (tv_sec) of last match */
11185665Sjoe	union ip_fw_if	fw_in_if;	/* Incoming interfaces */
11285665Sjoe	union ip_fw_if	fw_out_if;	/* Outgoing interfaces */
11326359Sjulian    union {
11485665Sjoe	u_short		fu_divert_port;	/* Divert/tee port (options IPDIVERT) */
11585665Sjoe	u_short		fu_pipe_nr;	/* queue number (option DUMMYNET) */
11685665Sjoe	u_short		fu_skipto_rule;	/* SKIPTO command rule number */
11785665Sjoe	u_short		fu_reject_code;	/* REJECT response code */
11837409Sjulian	struct sockaddr_in fu_fwd_ip;
11926359Sjulian    } fw_un;
12085665Sjoe	void		*pipe_ptr;	/* flow_set ptr for dummynet pipe */
12185665Sjoe	void		*next_rule_ptr;	/* next rule in case of match */
12285665Sjoe	uid_t		fw_uid;		/* uid to match */
12385665Sjoe	gid_t		fw_gid;		/* gid to match */
12485665Sjoe	int		fw_logamount;	/* amount to log */
12585665Sjoe	u_int64_t	fw_loghighest;	/* highest number packet to log */
1263969Sjkh
12785665Sjoe	long		dont_match_prob; /* 0x7fffffff means 1.0, always fail */
12885665Sjoe	u_char		dyn_type;	/* type for dynamic rule */
12985665Sjoe
13084058Sluigi#define	DYN_KEEP_STATE	0	/* type for keep-state rules	*/
13184058Sluigi#define	DYN_LIMIT	1	/* type for limit connection rules */
13284058Sluigi#define	DYN_LIMIT_PARENT 2	/* parent entry for limit connection rules */
13385665Sjoe
13485665Sjoe	/* following two fields are used to limit number of connections
13585665Sjoe	 * basing on either src, srcport, dst, dstport.
13685665Sjoe	 */
13785665Sjoe	u_char		limit_mask;	/* mask type for limit rule, can
13885665Sjoe					 * have many.
13985665Sjoe					 */
14084058Sluigi#define	DYN_SRC_ADDR	0x1
14184058Sluigi#define	DYN_SRC_PORT	0x2
14284058Sluigi#define	DYN_DST_ADDR	0x4
14384058Sluigi#define	DYN_DST_PORT	0x8
14485665Sjoe
14585665Sjoe	u_short		conn_limit;	/* # of connections for limit rule */
14649630Sluigi};
14749630Sluigi
14885665Sjoe#define	fw_divert_port	fw_un.fu_divert_port
14985665Sjoe#define	fw_skipto_rule	fw_un.fu_skipto_rule
15085665Sjoe#define	fw_reject_code	fw_un.fu_reject_code
15185665Sjoe#define	fw_pipe_nr	fw_un.fu_pipe_nr
15285665Sjoe#define	fw_fwd_ip	fw_un.fu_fwd_ip
15326359Sjulian
15485689Sjoe/*
15583725Sluigi *
15684058Sluigi *   rule_ptr  -------------+
15783725Sluigi *                          V
15883725Sluigi *     [ next.le_next ]---->[ next.le_next ]---- [ next.le_next ]--->
15983725Sluigi *     [ next.le_prev ]<----[ next.le_prev ]<----[ next.le_prev ]<---
16084058Sluigi *     [ <ip_fw> body ]     [ <ip_fw> body ]     [ <ip_fw> body ]
16183725Sluigi *
16283725Sluigi */
16383725Sluigi
1644277Sjkh/*
16557113Sluigi * Flow mask/flow id for each queue.
16657113Sluigi */
16757113Sluigistruct ipfw_flow_id {
16885665Sjoe	u_int32_t	dst_ip;
16985665Sjoe	u_int32_t	src_ip;
17085665Sjoe	u_int16_t	dst_port;
17185665Sjoe	u_int16_t	src_port;
17285665Sjoe	u_int8_t	proto;
17385665Sjoe	u_int8_t	flags;	/* protocol-specific flags */
17485665Sjoe};
17557113Sluigi
17657113Sluigi/*
17757113Sluigi * dynamic ipfw rule
17857113Sluigi */
17957113Sluigistruct ipfw_dyn_rule {
18085665Sjoe	struct ipfw_dyn_rule *next;
18185665Sjoe	struct ipfw_flow_id id;		/* (masked) flow id */
18285665Sjoe	struct ip_fw	*rule;		/* pointer to rule */
18385665Sjoe	struct ipfw_dyn_rule *parent;	/* pointer to parent rule */
18485665Sjoe	u_int32_t	expire;		/* expire time */
18585665Sjoe	u_int64_t	pcnt;		/* packet match counters */
18685665Sjoe	u_int64_t	bcnt;		/* byte match counters */
18785665Sjoe	u_int32_t	bucket;		/* which bucket in hash table */
18885665Sjoe	u_int32_t	state;		/* state of this rule (typically a
18985665Sjoe					 * combination of TCP flags)
19085665Sjoe					 */
19185687Sjoe	u_int16_t	dyn_type;	/* rule type */
19285665Sjoe	u_int16_t	count;		/* refcount */
19385665Sjoe};
19457113Sluigi
19557113Sluigi/*
1964277Sjkh * Values for "flags" field .
1974277Sjkh */
19885665Sjoe#define	IP_FW_F_COMMAND	0x000000ff	/* Mask for type of chain entry: */
19985665Sjoe#define	IP_FW_F_DENY	0x00000000	/* This is a deny rule */
20085665Sjoe#define	IP_FW_F_REJECT	0x00000001	/* Deny and send a response packet */
20185665Sjoe#define	IP_FW_F_ACCEPT	0x00000002	/* This is an accept rule */
20285665Sjoe#define	IP_FW_F_COUNT	0x00000003	/* This is a count rule */
20385687Sjoe#define	IP_FW_F_DIVERT	0x00000004	/* This is a divert rule */
20485665Sjoe#define	IP_FW_F_TEE	0x00000005	/* This is a tee rule */
20585665Sjoe#define	IP_FW_F_SKIPTO	0x00000006	/* This is a skipto rule */
20685665Sjoe#define	IP_FW_F_FWD	0x00000007	/* This is a "change forwarding
20785687Sjoe					 * address" rule
20885687Sjoe					 */
20985665Sjoe#define	IP_FW_F_PIPE	0x00000008	/* This is a dummynet rule */
21085665Sjoe#define	IP_FW_F_QUEUE	0x00000009	/* This is a dummynet queue */
21114230Sphk
21285665Sjoe#define	IP_FW_F_IN	0x00000100	/* Check inbound packets */
21385665Sjoe#define	IP_FW_F_OUT	0x00000200	/* Check outbound packets */
21485665Sjoe#define	IP_FW_F_IIFACE	0x00000400	/* Apply inbound interface test */
21585665Sjoe#define	IP_FW_F_OIFACE	0x00000800	/* Apply outbound interface test */
21685665Sjoe#define	IP_FW_F_PRN	0x00001000	/* Print if this rule matches */
21785665Sjoe#define	IP_FW_F_SRNG	0x00002000	/* The first two src ports are a min
21885665Sjoe					 * and max range (stored in host byte
21985665Sjoe					 * order).
22085665Sjoe					 */
22185665Sjoe#define	IP_FW_F_DRNG	0x00004000	/* The first two dst ports are a min
22285665Sjoe					 * and max range (stored in host byte
22385665Sjoe					 * order).
22485665Sjoe					 */
22585665Sjoe#define	IP_FW_F_FRAG	0x00008000	/* Fragment */
22685665Sjoe#define	IP_FW_F_IIFNAME	0x00010000	/* In interface by name/unit (not IP) */
22785665Sjoe#define	IP_FW_F_OIFNAME	0x00020000	/* Out interface by name/unit (not IP)*/
22885665Sjoe#define	IP_FW_F_INVSRC	0x00040000	/* Invert sense of src check */
22985665Sjoe#define	IP_FW_F_INVDST	0x00080000	/* Invert sense of dst check */
23085665Sjoe#define	IP_FW_F_ICMPBIT	0x00100000	/* ICMP type bitmap is valid */
23185665Sjoe#define	IP_FW_F_UID	0x00200000	/* filter by uid */
23285665Sjoe#define	IP_FW_F_GID	0x00400000	/* filter by gid */
23385665Sjoe#define	IP_FW_F_RND_MATCH 0x00800000	/* probabilistic rule match */
23485665Sjoe#define	IP_FW_F_SMSK	0x01000000	/* src-port + mask */
23585665Sjoe#define	IP_FW_F_DMSK	0x02000000	/* dst-port + mask */
23685665Sjoe#define	IP_FW_BRIDGED	0x04000000	/* only match bridged packets */
23785665Sjoe#define	IP_FW_F_KEEP_S	0x08000000	/* keep state */
23885665Sjoe#define	IP_FW_F_CHECK_S	0x10000000	/* check state */
23985665Sjoe#define	IP_FW_F_SME	0x20000000	/* source = me */
24085665Sjoe#define	IP_FW_F_DME	0x40000000	/* destination = me */
24117072Sjulian
24285665Sjoe#define	IP_FW_F_MASK	0x7FFFFFFF	/* All possible flag bits mask */
24317072Sjulian
24485689Sjoe/*
24585665Sjoe * Flags for the 'fw_ipflg' field, for comparing values
24685665Sjoe * of ip and its protocols.
24766521Sbillf */
24885665Sjoe#define	IP_FW_IF_TCPOPT	0x00000001	/* tcp options */
24985665Sjoe#define	IP_FW_IF_TCPFLG	0x00000002	/* tcp flags */
25085665Sjoe#define	IP_FW_IF_TCPSEQ	0x00000004	/* tcp sequence number */
25185665Sjoe#define	IP_FW_IF_TCPACK	0x00000008	/* tcp acknowledgement number */
25285665Sjoe#define	IP_FW_IF_TCPWIN	0x00000010	/* tcp window size */
25385665Sjoe#define	IP_FW_IF_TCPEST	0x00000020	/* established TCP connection */
25485665Sjoe#define	IP_FW_IF_TCPMSK	0x0000003f	/* mask of all tcp values */
25585665Sjoe#define	IP_FW_IF_IPOPT	0x00000100	/* ip options */
25685665Sjoe#define	IP_FW_IF_IPLEN	0x00000200	/* ip length */
25785665Sjoe#define	IP_FW_IF_IPID	0x00000400	/* ip identification */
25885665Sjoe#define	IP_FW_IF_IPTOS	0x00000800	/* ip type of service */
25985665Sjoe#define	IP_FW_IF_IPTTL	0x00001000	/* ip time to live */
26085665Sjoe#define	IP_FW_IF_IPVER	0x00002000	/* ip version */
26185665Sjoe#define	IP_FW_IF_IPMSK	0x00003f00	/* mask of all ip values */
26285665Sjoe#define	IP_FW_IF_MSK	0x0000ffff	/* All possible bits mask */
26366521Sbillf
2648876Srgrimes/*
26526359Sjulian * For backwards compatibility with rules specifying "via iface" but
26626359Sjulian * not restricted to only "in" or "out" packets, we define this combination
26726359Sjulian * of bits to represent this configuration.
26826359Sjulian */
26926359Sjulian
27085665Sjoe#define	IF_FW_F_VIAHACK	(IP_FW_F_IN|IP_FW_F_OUT|IP_FW_F_IIFACE|IP_FW_F_OIFACE)
27126359Sjulian
27226359Sjulian/*
27326359Sjulian * Definitions for REJECT response codes.
27426359Sjulian * Values less than 256 correspond to ICMP unreachable codes.
27526359Sjulian */
27685665Sjoe#define	IP_FW_REJECT_RST	0x0100	/* TCP packets: send RST */
27726359Sjulian
27826359Sjulian/*
27911119Sugen * Definitions for IP option names.
28011119Sugen */
28185665Sjoe#define	IP_FW_IPOPT_LSRR	0x01
28285665Sjoe#define	IP_FW_IPOPT_SSRR	0x02
28385665Sjoe#define	IP_FW_IPOPT_RR		0x04
28485665Sjoe#define	IP_FW_IPOPT_TS		0x08
28511119Sugen
28611119Sugen/*
28761420Sdan * Definitions for TCP option names.
28861420Sdan */
28985665Sjoe#define	IP_FW_TCPOPT_MSS	0x01
29085665Sjoe#define	IP_FW_TCPOPT_WINDOW	0x02
29185665Sjoe#define	IP_FW_TCPOPT_SACK	0x04
29285665Sjoe#define	IP_FW_TCPOPT_TS		0x08
29385665Sjoe#define	IP_FW_TCPOPT_CC		0x10
29461420Sdan
29561420Sdan/*
29611119Sugen * Definitions for TCP flags.
29711119Sugen */
29885665Sjoe#define	IP_FW_TCPF_FIN		TH_FIN
29985665Sjoe#define	IP_FW_TCPF_SYN		TH_SYN
30085665Sjoe#define	IP_FW_TCPF_RST		TH_RST
30185665Sjoe#define	IP_FW_TCPF_PSH		TH_PUSH
30285665Sjoe#define	IP_FW_TCPF_ACK		TH_ACK
30385665Sjoe#define	IP_FW_TCPF_URG		TH_URG
30411119Sugen
30511119Sugen/*
3064277Sjkh * Main firewall chains definitions and global var's definitions.
3074277Sjkh */
30855205Speter#ifdef _KERNEL
3095543Sugen
31085665Sjoe#define	IP_FW_PORT_DYNT_FLAG	0x10000
31185665Sjoe#define	IP_FW_PORT_TEE_FLAG	0x20000
31285665Sjoe#define	IP_FW_PORT_DENY_FLAG	0x40000
31354175Sarchie
3145543Sugen/*
3155543Sugen * Function definitions.
3165543Sugen */
31729506Sbdevoid ip_fw_init __P((void));
3185543Sugen
31938482Swollman/* Firewall hooks */
32038482Swollmanstruct ip;
32138482Swollmanstruct sockopt;
32285665Sjoetypedef int ip_fw_chk_t (struct ip **, int, struct ifnet *, u_int16_t *,
32385665Sjoe    struct mbuf **, struct ip_fw **, struct sockaddr_in **);
32485665Sjoetypedef int ip_fw_ctl_t (struct sockopt *);
32585665Sjoeextern ip_fw_chk_t *ip_fw_chk_ptr;
32685665Sjoeextern ip_fw_ctl_t *ip_fw_ctl_ptr;
32757113Sluigiextern int fw_one_pass;
32857113Sluigiextern int fw_enable;
32985665Sjoeextern struct ipfw_flow_id last_pkt;
33055205Speter#endif /* _KERNEL */
3313969Sjkh
3324523Sjkh#endif /* _IP_FW_H */
333