1145522Sdarrenr/*	$FreeBSD$	*/
2145522Sdarrenr
353642Sguido/*
4145522Sdarrenr * Copyright (C) 1995-2001, 2003 by Darren Reed.
553642Sguido *
680482Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
753642Sguido *
853642Sguido * @(#)ip_nat.h	1.5 2/4/96
957126Sguido * $FreeBSD$
10172776Sdarrenr * Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $
1153642Sguido */
1253642Sguido
1353642Sguido#ifndef	__IP_NAT_H__
1453642Sguido#define	__IP_NAT_H__
1553642Sguido
1653642Sguido#ifndef SOLARIS
17145522Sdarrenr#define	SOLARIS	(defined(sun) && (defined(__svr4__) || defined(__SVR4)))
1853642Sguido#endif
1953642Sguido
20153876Sguido#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
21145522Sdarrenr#define	SIOCADNAT	_IOW('r', 60, struct ipfobj)
22145522Sdarrenr#define	SIOCRMNAT	_IOW('r', 61, struct ipfobj)
23145522Sdarrenr#define	SIOCGNATS	_IOWR('r', 62, struct ipfobj)
24145522Sdarrenr#define	SIOCGNATL	_IOWR('r', 63, struct ipfobj)
2553642Sguido#else
26145522Sdarrenr#define	SIOCADNAT	_IOW(r, 60, struct ipfobj)
27145522Sdarrenr#define	SIOCRMNAT	_IOW(r, 61, struct ipfobj)
28145522Sdarrenr#define	SIOCGNATS	_IOWR(r, 62, struct ipfobj)
29145522Sdarrenr#define	SIOCGNATL	_IOWR(r, 63, struct ipfobj)
3053642Sguido#endif
3153642Sguido
32145522Sdarrenr#undef	LARGE_NAT	/* define	this if you're setting up a system to NAT
3353642Sguido			 * LARGE numbers of networks/hosts - i.e. in the
3453642Sguido			 * hundreds or thousands.  In such a case, you should
3553642Sguido			 * also change the RDR_SIZE and NAT_SIZE below to more
3653642Sguido			 * appropriate sizes.  The figures below were used for
3753642Sguido			 * a setup with 1000-2000 networks to NAT.
3853642Sguido			 */
39145522Sdarrenr#ifndef NAT_SIZE
40145522Sdarrenr# ifdef LARGE_NAT
41130886Sdarrenr#  define	NAT_SIZE	2047
42130886Sdarrenr# else
43130886Sdarrenr#  define	NAT_SIZE	127
44130886Sdarrenr# endif
4580482Sdarrenr#endif
46145522Sdarrenr#ifndef RDR_SIZE
47145522Sdarrenr# ifdef LARGE_NAT
48130886Sdarrenr#  define	RDR_SIZE	2047
49130886Sdarrenr# else
50130886Sdarrenr#  define	RDR_SIZE	127
51130886Sdarrenr# endif
5280482Sdarrenr#endif
53145522Sdarrenr#ifndef HOSTMAP_SIZE
54145522Sdarrenr# ifdef LARGE_NAT
55130886Sdarrenr#  define	HOSTMAP_SIZE	8191
56130886Sdarrenr# else
57130886Sdarrenr#  define	HOSTMAP_SIZE	2047
58130886Sdarrenr# endif
5980482Sdarrenr#endif
60130886Sdarrenr#ifndef NAT_TABLE_MAX
61145522Sdarrenr/*
62145522Sdarrenr * This is newly introduced and for the sake of "least surprise", the numbers
63145522Sdarrenr * present aren't what we'd normally use for creating a proper hash table.
64145522Sdarrenr */
65130886Sdarrenr# ifdef	LARGE_NAT
66130886Sdarrenr#  define	NAT_TABLE_MAX	180000
67130886Sdarrenr# else
68130886Sdarrenr#  define	NAT_TABLE_MAX	30000
69130886Sdarrenr# endif
70130886Sdarrenr#endif
71145522Sdarrenr#ifndef NAT_TABLE_SZ
72145522Sdarrenr# ifdef LARGE_NAT
73130886Sdarrenr#  define	NAT_TABLE_SZ	16383
74130886Sdarrenr# else
75130886Sdarrenr#  define	NAT_TABLE_SZ	2047
76130886Sdarrenr# endif
7780482Sdarrenr#endif
7853642Sguido#ifndef	APR_LABELLEN
7953642Sguido#define	APR_LABELLEN	16
8053642Sguido#endif
8155929Sguido#define	NAT_HW_CKSUM	0x80000000
8253642Sguido
8353642Sguido#define	DEF_NAT_AGE	1200     /* 10 minutes (600 seconds) */
8453642Sguido
85145522Sdarrenrstruct ipstate;
8660852Sdarrenrstruct ap_session;
8760852Sdarrenr
8853642Sguidotypedef	struct	nat	{
89145522Sdarrenr	ipfmutex_t	nat_lock;
9053642Sguido	struct	nat	*nat_next;
91145522Sdarrenr	struct	nat	**nat_pnext;
9253642Sguido	struct	nat	*nat_hnext[2];
9367614Sdarrenr	struct	nat	**nat_phnext[2];
94145522Sdarrenr	struct	hostmap	*nat_hm;
95145522Sdarrenr	void		*nat_data;
9692685Sdarrenr	struct	nat	**nat_me;
97145522Sdarrenr	struct	ipstate	*nat_state;
98145522Sdarrenr	struct	ap_session	*nat_aps;		/* proxy session */
99145522Sdarrenr	frentry_t	*nat_fr;	/* filter rule ptr if appropriate */
100145522Sdarrenr	struct	ipnat	*nat_ptr;	/* pointer back to the rule */
101145522Sdarrenr	void		*nat_ifps[2];
102145522Sdarrenr	void		*nat_sync;
103145522Sdarrenr	ipftqent_t	nat_tqe;
104145522Sdarrenr	u_32_t		nat_flags;
105145522Sdarrenr	u_32_t		nat_sumd[2];	/* ip checksum delta for data segment*/
106145522Sdarrenr	u_32_t		nat_ipsumd;	/* ip checksum delta for ip header */
107145522Sdarrenr	u_32_t		nat_mssclamp;	/* if != zero clamp MSS to this */
108145522Sdarrenr	i6addr_t	nat_inip6;
109145522Sdarrenr	i6addr_t	nat_outip6;
110145522Sdarrenr	i6addr_t	nat_oip6;		/* other ip */
111145522Sdarrenr	U_QUAD_T	nat_pkts[2];
112145522Sdarrenr	U_QUAD_T	nat_bytes[2];
113145522Sdarrenr	union	{
114145522Sdarrenr		udpinfo_t	nat_unu;
115145522Sdarrenr		tcpinfo_t	nat_unt;
116145522Sdarrenr		icmpinfo_t	nat_uni;
117145522Sdarrenr		greinfo_t	nat_ugre;
118145522Sdarrenr	} nat_un;
119145522Sdarrenr	u_short		nat_oport;		/* other port */
120145522Sdarrenr	u_short		nat_use;
121145522Sdarrenr	u_char		nat_p;			/* protocol for NAT */
122145522Sdarrenr	int		nat_dir;
123145522Sdarrenr	int		nat_ref;		/* reference count */
124145522Sdarrenr	int		nat_hv[2];
125145522Sdarrenr	char		nat_ifnames[2][LIFNAMSIZ];
126145522Sdarrenr	int		nat_rev;		/* 0 = forward, 1 = reverse */
127170268Sdarrenr	int		nat_redir;		/* copy of in_redir */
128172776Sdarrenr	u_32_t		nat_seqnext[2];
12953642Sguido} nat_t;
13053642Sguido
131145522Sdarrenr#define	nat_inip	nat_inip6.in4
132145522Sdarrenr#define	nat_outip	nat_outip6.in4
133145522Sdarrenr#define	nat_oip		nat_oip6.in4
134145522Sdarrenr#define	nat_age		nat_tqe.tqe_die
135145522Sdarrenr#define	nat_inport	nat_un.nat_unt.ts_sport
136145522Sdarrenr#define	nat_outport	nat_un.nat_unt.ts_dport
137145522Sdarrenr#define	nat_type	nat_un.nat_uni.ici_type
138145522Sdarrenr#define	nat_seq		nat_un.nat_uni.ici_seq
139145522Sdarrenr#define	nat_id		nat_un.nat_uni.ici_id
140145522Sdarrenr#define	nat_tcpstate	nat_tqe.tqe_state
141170268Sdarrenr#define	nat_die		nat_tqe.tqe_die
142170268Sdarrenr#define	nat_touched	nat_tqe.tqe_touched
143145522Sdarrenr
144145522Sdarrenr/*
145145522Sdarrenr * Values for nat_dir
146145522Sdarrenr */
147145522Sdarrenr#define	NAT_INBOUND	0
148145522Sdarrenr#define	NAT_OUTBOUND	1
149145522Sdarrenr
150145522Sdarrenr/*
151145522Sdarrenr * Definitions for nat_flags
152145522Sdarrenr */
153145522Sdarrenr#define	NAT_TCP		0x0001	/* IPN_TCP */
154145522Sdarrenr#define	NAT_UDP		0x0002	/* IPN_UDP */
155145522Sdarrenr#define	NAT_ICMPERR	0x0004	/* IPN_ICMPERR */
156145522Sdarrenr#define	NAT_ICMPQUERY	0x0008	/* IPN_ICMPQUERY */
157145522Sdarrenr#define	NAT_SEARCH	0x0010
158145522Sdarrenr#define	NAT_SLAVE	0x0020	/* Slave connection for a proxy */
159170268Sdarrenr#define	NAT_NOTRULEPORT	0x0040	/* Don't use the port # in the NAT rule */
160145522Sdarrenr
161145522Sdarrenr#define	NAT_TCPUDP	(NAT_TCP|NAT_UDP)
162145522Sdarrenr#define	NAT_TCPUDPICMP	(NAT_TCP|NAT_UDP|NAT_ICMPERR)
163145522Sdarrenr#define	NAT_TCPUDPICMPQ	(NAT_TCP|NAT_UDP|NAT_ICMPQUERY)
164145522Sdarrenr#define	NAT_FROMRULE	(NAT_TCP|NAT_UDP)
165145522Sdarrenr
166145522Sdarrenr/* 0x0100 reserved for FI_W_SPORT */
167145522Sdarrenr/* 0x0200 reserved for FI_W_DPORT */
168145522Sdarrenr/* 0x0400 reserved for FI_W_SADDR */
169145522Sdarrenr/* 0x0800 reserved for FI_W_DADDR */
170145522Sdarrenr/* 0x1000 reserved for FI_W_NEWFR */
171145522Sdarrenr/* 0x2000 reserved for SI_CLONE */
172145522Sdarrenr/* 0x4000 reserved for SI_CLONED */
173145522Sdarrenr/* 0x8000 reserved for SI_IGNOREPKT */
174145522Sdarrenr
175145522Sdarrenr#define	NAT_DEBUG	0x800000
176145522Sdarrenr
17753642Sguidotypedef	struct	ipnat	{
178170268Sdarrenr	ipfmutex_t	in_lock;
179145522Sdarrenr	struct	ipnat	*in_next;		/* NAT rule list next */
180145522Sdarrenr	struct	ipnat	*in_rnext;		/* rdr rule hash next */
181145522Sdarrenr	struct	ipnat	**in_prnext;		/* prior rdr next ptr */
182145522Sdarrenr	struct	ipnat	*in_mnext;		/* map rule hash next */
183145522Sdarrenr	struct	ipnat	**in_pmnext;		/* prior map next ptr */
184145522Sdarrenr	struct	ipftq	*in_tqehead[2];
185145522Sdarrenr	void		*in_ifps[2];
186145522Sdarrenr	void		*in_apr;
187145522Sdarrenr	char		*in_comment;
188145522Sdarrenr	i6addr_t	in_next6;
189145522Sdarrenr	u_long		in_space;
190145522Sdarrenr	u_long		in_hits;
191145522Sdarrenr	u_int		in_use;
192145522Sdarrenr	u_int		in_hv;
193145522Sdarrenr	int		in_flineno;		/* conf. file line number */
194145522Sdarrenr	u_short		in_pnext;
195145522Sdarrenr	u_char		in_v;
196145522Sdarrenr	u_char		in_xxx;
197145522Sdarrenr	/* From here to the end is covered by IPN_CMPSIZ */
198145522Sdarrenr	u_32_t		in_flags;
199145522Sdarrenr	u_32_t		in_mssclamp;		/* if != 0 clamp MSS to this */
200145522Sdarrenr	u_int		in_age[2];
201145522Sdarrenr	int		in_redir;		/* see below for values */
202145522Sdarrenr	int		in_p;			/* protocol. */
203145522Sdarrenr	i6addr_t	in_in[2];
204145522Sdarrenr	i6addr_t	in_out[2];
205145522Sdarrenr	i6addr_t	in_src[2];
206145522Sdarrenr	frtuc_t		in_tuc;
207145522Sdarrenr	u_short		in_port[2];
208145522Sdarrenr	u_short		in_ppip;		/* ports per IP. */
209145522Sdarrenr	u_short		in_ippip;		/* IP #'s per IP# */
210145522Sdarrenr	char		in_ifnames[2][LIFNAMSIZ];
211145522Sdarrenr	char		in_plabel[APR_LABELLEN];	/* proxy label. */
212145522Sdarrenr	ipftag_t	in_tag;
21353642Sguido} ipnat_t;
21453642Sguido
21553642Sguido#define	in_pmin		in_port[0]	/* Also holds static redir port */
21653642Sguido#define	in_pmax		in_port[1]
217145522Sdarrenr#define	in_nextip	in_next6.in4
218145522Sdarrenr#define	in_nip		in_next6.in4.s_addr
219145522Sdarrenr#define	in_inip		in_in[0].in4.s_addr
220145522Sdarrenr#define	in_inmsk	in_in[1].in4.s_addr
221145522Sdarrenr#define	in_outip	in_out[0].in4.s_addr
222145522Sdarrenr#define	in_outmsk	in_out[1].in4.s_addr
223145522Sdarrenr#define	in_srcip	in_src[0].in4.s_addr
224145522Sdarrenr#define	in_srcmsk	in_src[1].in4.s_addr
22560852Sdarrenr#define	in_scmp		in_tuc.ftu_scmp
22660852Sdarrenr#define	in_dcmp		in_tuc.ftu_dcmp
22760852Sdarrenr#define	in_stop		in_tuc.ftu_stop
22860852Sdarrenr#define	in_dtop		in_tuc.ftu_dtop
22960852Sdarrenr#define	in_sport	in_tuc.ftu_sport
23060852Sdarrenr#define	in_dport	in_tuc.ftu_dport
23153642Sguido
232145522Sdarrenr/*
233145522Sdarrenr * Bit definitions for in_flags
234145522Sdarrenr */
235145522Sdarrenr#define	IPN_ANY		0x00000
236145522Sdarrenr#define	IPN_TCP		0x00001
237145522Sdarrenr#define	IPN_UDP		0x00002
238145522Sdarrenr#define	IPN_TCPUDP	(IPN_TCP|IPN_UDP)
239145522Sdarrenr#define	IPN_ICMPERR	0x00004
240145522Sdarrenr#define	IPN_TCPUDPICMP	(IPN_TCP|IPN_UDP|IPN_ICMPERR)
241145522Sdarrenr#define	IPN_ICMPQUERY	0x00008
242145522Sdarrenr#define	IPN_TCPUDPICMPQ	(IPN_TCP|IPN_UDP|IPN_ICMPQUERY)
243145522Sdarrenr#define	IPN_RF		(IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
244145522Sdarrenr#define	IPN_AUTOPORTMAP	0x00010
245145522Sdarrenr#define	IPN_IPRANGE	0x00020
246145522Sdarrenr#define	IPN_FILTER	0x00040
247145522Sdarrenr#define	IPN_SPLIT	0x00080
248145522Sdarrenr#define	IPN_ROUNDR	0x00100
249145522Sdarrenr#define	IPN_NOTSRC	0x04000
250145522Sdarrenr#define	IPN_NOTDST	0x08000
251145522Sdarrenr#define	IPN_DYNSRCIP	0x10000	/* dynamic src IP# */
252145522Sdarrenr#define	IPN_DYNDSTIP	0x20000	/* dynamic dst IP# */
253145522Sdarrenr#define	IPN_DELETE	0x40000
254145522Sdarrenr#define	IPN_STICKY	0x80000
255145522Sdarrenr#define	IPN_FRAG	0x100000
256145522Sdarrenr#define	IPN_FIXEDDPORT	0x200000
257145522Sdarrenr#define	IPN_FINDFORWARD	0x400000
258145522Sdarrenr#define	IPN_IN		0x800000
259180778Sdarrenr#define	IPN_SEQUENTIAL	0x1000000
260145522Sdarrenr#define	IPN_USERFLAGS	(IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
261145522Sdarrenr			 IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
262180778Sdarrenr			 IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\
263180778Sdarrenr			 IPN_SEQUENTIAL)
26453642Sguido
265145522Sdarrenr/*
266145522Sdarrenr * Values for in_redir
267145522Sdarrenr */
26853642Sguido#define	NAT_MAP		0x01
26953642Sguido#define	NAT_REDIRECT	0x02
27053642Sguido#define	NAT_BIMAP	(NAT_MAP|NAT_REDIRECT)
27153642Sguido#define	NAT_MAPBLK	0x04
27253642Sguido
27353642Sguido#define	MAPBLK_MINPORT	1024	/* don't use reserved ports for src port */
27453642Sguido#define	USABLE_PORTS	(65536 - MAPBLK_MINPORT)
27553642Sguido
27653642Sguido#define	IPN_CMPSIZ	(sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
27753642Sguido
27853642Sguidotypedef	struct	natlookup {
27953642Sguido	struct	in_addr	nl_inip;
28053642Sguido	struct	in_addr	nl_outip;
28153642Sguido	struct	in_addr	nl_realip;
28253642Sguido	int	nl_flags;
28353642Sguido	u_short	nl_inport;
28453642Sguido	u_short	nl_outport;
28553642Sguido	u_short	nl_realport;
28653642Sguido} natlookup_t;
28753642Sguido
28860852Sdarrenr
28960852Sdarrenrtypedef struct  nat_save    {
29060852Sdarrenr	void	*ipn_next;
29160852Sdarrenr	struct	nat	ipn_nat;
29260852Sdarrenr	struct	ipnat	ipn_ipnat;
29360852Sdarrenr	struct	frentry ipn_fr;
29460852Sdarrenr	int	ipn_dsize;
29560852Sdarrenr	char	ipn_data[4];
29660852Sdarrenr} nat_save_t;
29760852Sdarrenr
29860852Sdarrenr#define	ipn_rule	ipn_nat.nat_fr
29960852Sdarrenr
30060852Sdarrenrtypedef	struct	natget	{
30160852Sdarrenr	void	*ng_ptr;
30260852Sdarrenr	int	ng_sz;
30360852Sdarrenr} natget_t;
30460852Sdarrenr
30560852Sdarrenr
306145522Sdarrenr/*
307145522Sdarrenr * This structure gets used to help NAT sessions keep the same NAT rule (and
308145522Sdarrenr * thus translation for IP address) when:
309145522Sdarrenr * (a) round-robin redirects are in use
310145522Sdarrenr * (b) different IP add
311145522Sdarrenr */
31260852Sdarrenrtypedef	struct	hostmap	{
313170268Sdarrenr	struct	hostmap	*hm_hnext;
314170268Sdarrenr	struct	hostmap	**hm_phnext;
31560852Sdarrenr	struct	hostmap	*hm_next;
31660852Sdarrenr	struct	hostmap	**hm_pnext;
31760852Sdarrenr	struct	ipnat	*hm_ipnat;
318145522Sdarrenr	struct	in_addr	hm_srcip;
319145522Sdarrenr	struct	in_addr	hm_dstip;
32060852Sdarrenr	struct	in_addr	hm_mapip;
321145522Sdarrenr	u_32_t		hm_port;
322145522Sdarrenr	int		hm_ref;
32360852Sdarrenr} hostmap_t;
32460852Sdarrenr
32560852Sdarrenr
326145522Sdarrenr/*
327145522Sdarrenr * Structure used to pass information in to nat_newmap and nat_newrdr.
328145522Sdarrenr */
329145522Sdarrenrtypedef struct	natinfo	{
330145522Sdarrenr	ipnat_t		*nai_np;
331145522Sdarrenr	u_32_t		nai_sum1;
332145522Sdarrenr	u_32_t		nai_sum2;
333145522Sdarrenr	u_32_t		nai_nflags;
334145522Sdarrenr	u_32_t		nai_flags;
335145522Sdarrenr	struct	in_addr	nai_ip;
336145522Sdarrenr	u_short		nai_port;
337145522Sdarrenr	u_short		nai_nport;
338145522Sdarrenr	u_short		nai_sport;
339145522Sdarrenr	u_short		nai_dport;
340145522Sdarrenr} natinfo_t;
341145522Sdarrenr
342145522Sdarrenr
34353642Sguidotypedef	struct	natstat	{
34453642Sguido	u_long	ns_mapped[2];
34553642Sguido	u_long	ns_rules;
34653642Sguido	u_long	ns_added;
34753642Sguido	u_long	ns_expire;
34853642Sguido	u_long	ns_inuse;
34953642Sguido	u_long	ns_logged;
35053642Sguido	u_long	ns_logfail;
35160852Sdarrenr	u_long	ns_memfail;
35260852Sdarrenr	u_long	ns_badnat;
353145522Sdarrenr	u_long	ns_addtrpnt;
35453642Sguido	nat_t	**ns_table[2];
35580482Sdarrenr	hostmap_t **ns_maptable;
35653642Sguido	ipnat_t	*ns_list;
35753642Sguido	void	*ns_apslist;
358145522Sdarrenr	u_int	ns_wilds;
35953642Sguido	u_int	ns_nattab_sz;
360145522Sdarrenr	u_int	ns_nattab_max;
36153642Sguido	u_int	ns_rultab_sz;
36253642Sguido	u_int	ns_rdrtab_sz;
363145522Sdarrenr	u_int	ns_trpntab_sz;
36480482Sdarrenr	u_int	ns_hostmap_sz;
36553642Sguido	nat_t	*ns_instances;
366170268Sdarrenr	hostmap_t *ns_maplist;
367145522Sdarrenr	u_long	*ns_bucketlen[2];
368170268Sdarrenr	u_long	ns_ticks;
369172776Sdarrenr	u_int	ns_orphans;
37053642Sguido} natstat_t;
37153642Sguido
37253642Sguidotypedef	struct	natlog {
37353642Sguido	struct	in_addr	nl_origip;
37453642Sguido	struct	in_addr	nl_outip;
37553642Sguido	struct	in_addr	nl_inip;
37653642Sguido	u_short	nl_origport;
37753642Sguido	u_short	nl_outport;
37853642Sguido	u_short	nl_inport;
37953642Sguido	u_short	nl_type;
38053642Sguido	int	nl_rule;
381145522Sdarrenr	U_QUAD_T	nl_pkts[2];
382145522Sdarrenr	U_QUAD_T	nl_bytes[2];
38357096Sguido	u_char	nl_p;
38453642Sguido} natlog_t;
38553642Sguido
38653642Sguido
38753642Sguido#define	NL_NEWMAP	NAT_MAP
38853642Sguido#define	NL_NEWRDR	NAT_REDIRECT
38963523Sdarrenr#define	NL_NEWBIMAP	NAT_BIMAP
39063523Sdarrenr#define	NL_NEWBLOCK	NAT_MAPBLK
391172776Sdarrenr#define	NL_DESTROY	0xfffc
392145522Sdarrenr#define	NL_CLONE	0xfffd
39372006Sdarrenr#define	NL_FLUSH	0xfffe
39453642Sguido#define	NL_EXPIRE	0xffff
39553642Sguido
39660852Sdarrenr#define	NAT_HASH_FN(k,l,m)	(((k) + ((k) >> 12) + l) % (m))
39753642Sguido
39853642Sguido#define	LONG_SUM(in)	(((in) & 0xffff) + ((in) >> 16))
39953642Sguido
40053642Sguido#define	CALC_SUMD(s1, s2, sd) { \
40153642Sguido			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
40253642Sguido			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
40353642Sguido			    /* Do it twice */ \
40453642Sguido			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
40553642Sguido			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
40653642Sguido			    /* Because ~1 == -2, We really need ~1 == -1 */ \
40753642Sguido			    if ((s1) > (s2)) (s2)--; \
40853642Sguido			    (sd) = (s2) - (s1); \
40953642Sguido			    (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
41053642Sguido
41195418Sdarrenr#define	NAT_SYSSPACE		0x80000000
41295418Sdarrenr#define	NAT_LOCKHELD		0x40000000
41353642Sguido
414145522Sdarrenr
41553642Sguidoextern	u_int	ipf_nattable_sz;
416145522Sdarrenrextern	u_int	ipf_nattable_max;
41753642Sguidoextern	u_int	ipf_natrules_sz;
41853642Sguidoextern	u_int	ipf_rdrrules_sz;
419145522Sdarrenrextern	u_int	ipf_hostmap_sz;
420145522Sdarrenrextern	u_int	fr_nat_maxbucket;
421145522Sdarrenrextern	u_int	fr_nat_maxbucket_reset;
42260852Sdarrenrextern	int	fr_nat_lock;
423170268Sdarrenrextern	int	fr_nat_doflush;
424145522Sdarrenrextern	void	fr_natsync __P((void *));
42553642Sguidoextern	u_long	fr_defnatage;
42653642Sguidoextern	u_long	fr_defnaticmpage;
427145522Sdarrenrextern	u_long	fr_defnatipage;
428145522Sdarrenr	/* nat_table[0] -> hashed list sorted by inside (ip, port) */
429145522Sdarrenr	/* nat_table[1] -> hashed list sorted by outside (ip, port) */
43053642Sguidoextern	nat_t	**nat_table[2];
43153642Sguidoextern	nat_t	*nat_instances;
432145522Sdarrenrextern	ipnat_t	*nat_list;
43353642Sguidoextern	ipnat_t	**nat_rules;
43453642Sguidoextern	ipnat_t	**rdr_rules;
435145522Sdarrenrextern	ipftq_t	*nat_utqe;
43653642Sguidoextern	natstat_t	nat_stats;
437145522Sdarrenr
43892685Sdarrenr#if defined(__OpenBSD__)
43992685Sdarrenrextern	void	nat_ifdetach __P((void *));
44092685Sdarrenr#endif
441170268Sdarrenrextern	int	fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
442145522Sdarrenrextern	int	fr_natinit __P((void));
443145522Sdarrenrextern	nat_t	*nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int));
44492685Sdarrenrextern	nat_t	*nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
445145522Sdarrenr				 struct in_addr));
446145522Sdarrenrextern	void	fix_datacksum __P((u_short *, u_32_t));
44792685Sdarrenrextern	nat_t	*nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
448145522Sdarrenr				struct in_addr));
449145522Sdarrenrextern	nat_t	*nat_tnlookup __P((fr_info_t *, int));
450145522Sdarrenrextern	nat_t	*nat_maplookup __P((void *, u_int, struct in_addr,
451145522Sdarrenr				struct in_addr));
45253642Sguidoextern	nat_t	*nat_lookupredir __P((natlookup_t *));
453145522Sdarrenrextern	nat_t	*nat_icmperrorlookup __P((fr_info_t *, int));
454145522Sdarrenrextern	nat_t	*nat_icmperror __P((fr_info_t *, u_int *, int));
455172776Sdarrenrextern	void	nat_delete __P((struct nat *, int));
456145522Sdarrenrextern	int	nat_insert __P((nat_t *, int));
45753642Sguido
458145522Sdarrenrextern	int	fr_checknatout __P((fr_info_t *, u_32_t *));
459145522Sdarrenrextern	int	fr_natout __P((fr_info_t *, nat_t *, int, u_32_t));
460145522Sdarrenrextern	int	fr_checknatin __P((fr_info_t *, u_32_t *));
461145522Sdarrenrextern	int	fr_natin __P((fr_info_t *, nat_t *, int, u_32_t));
462145522Sdarrenrextern	void	fr_natunload __P((void));
463145522Sdarrenrextern	void	fr_natexpire __P((void));
46453642Sguidoextern	void	nat_log __P((struct nat *, u_int));
46580482Sdarrenrextern	void	fix_incksum __P((fr_info_t *, u_short *, u_32_t));
46680482Sdarrenrextern	void	fix_outcksum __P((fr_info_t *, u_short *, u_32_t));
467170268Sdarrenrextern	void	fr_ipnatderef __P((ipnat_t **));
468145522Sdarrenrextern	void	fr_natderef __P((nat_t **));
469145522Sdarrenrextern	u_short	*nat_proto __P((fr_info_t *, nat_t *, u_int));
470145522Sdarrenrextern	void	nat_update __P((fr_info_t *, nat_t *, ipnat_t *));
471145522Sdarrenrextern	void	fr_setnatqueue __P((nat_t *, int));
472170268Sdarrenrextern	void	fr_hostmapdel __P((hostmap_t **));
47353642Sguido
47453642Sguido#endif /* __IP_NAT_H__ */
475