ip_nat.h revision 72006
1/*
2 * Copyright (C) 1995-2000 by Darren Reed.
3 *
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
7 *
8 * @(#)ip_nat.h	1.5 2/4/96
9 * $Id: ip_nat.h,v 2.17.2.14 2000/11/18 03:58:04 darrenr Exp $
10 * $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.h 72006 2001-02-04 14:26:56Z darrenr $
11 */
12
13#ifndef	__IP_NAT_H__
14#define	__IP_NAT_H__
15
16#ifndef SOLARIS
17#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
18#endif
19
20#if defined(__STDC__) || defined(__GNUC__)
21#define	SIOCADNAT	_IOW('r', 60, struct ipnat *)
22#define	SIOCRMNAT	_IOW('r', 61, struct ipnat *)
23#define	SIOCGNATS	_IOWR('r', 62, struct natstat *)
24#define	SIOCGNATL	_IOWR('r', 63, struct natlookup *)
25#else
26#define	SIOCADNAT	_IOW(r, 60, struct ipnat *)
27#define	SIOCRMNAT	_IOW(r, 61, struct ipnat *)
28#define	SIOCGNATS	_IOWR(r, 62, struct natstat *)
29#define	SIOCGNATL	_IOWR(r, 63, struct natlookup *)
30#endif
31
32#undef	LARGE_NAT	/* define this if you're setting up a system to NAT
33			 * LARGE numbers of networks/hosts - i.e. in the
34			 * hundreds or thousands.  In such a case, you should
35			 * also change the RDR_SIZE and NAT_SIZE below to more
36			 * appropriate sizes.  The figures below were used for
37			 * a setup with 1000-2000 networks to NAT.
38			 */
39#define	NAT_SIZE	127
40#define	RDR_SIZE	127
41#define	HOSTMAP_SIZE	127
42#define	NAT_TABLE_SZ	127
43#ifdef	LARGE_NAT
44#undef	NAT_SIZE
45#undef	RDR_SIZE
46#undef	NAT_TABLE_SZ
47#undef	HOSTMAP_SIZE	127
48#define	NAT_SIZE	2047
49#define	RDR_SIZE	2047
50#define	NAT_TABLE_SZ	16383
51#define	HOSTMAP_SIZE	8191
52#endif
53#ifndef	APR_LABELLEN
54#define	APR_LABELLEN	16
55#endif
56#define	NAT_HW_CKSUM	0x80000000
57
58#define	DEF_NAT_AGE	1200     /* 10 minutes (600 seconds) */
59
60struct ap_session;
61
62typedef	struct	nat	{
63	u_long	nat_age;
64	int	nat_flags;
65	u_32_t	nat_sumd[2];
66	u_32_t	nat_ipsumd;
67	void	*nat_data;
68	struct	ap_session	*nat_aps;		/* proxy session */
69	struct	frentry	*nat_fr;	/* filter rule ptr if appropriate */
70	struct	in_addr	nat_inip;
71	struct	in_addr	nat_outip;
72	struct	in_addr	nat_oip;	/* other ip */
73	U_QUAD_T	nat_pkts;
74	U_QUAD_T	nat_bytes;
75	u_short	nat_oport;		/* other port */
76	u_short	nat_inport;
77	u_short	nat_outport;
78	u_short	nat_use;
79	u_char	nat_tcpstate[2];
80	u_char	nat_p;			/* protocol for NAT */
81	struct	ipnat	*nat_ptr;	/* pointer back to the rule */
82	struct	hostmap	*nat_hm;
83	struct	nat	*nat_next;
84	struct	nat	*nat_hnext[2];
85	struct	nat	**nat_phnext[2];
86	void	*nat_ifp;
87	int	nat_dir;
88	char	nat_ifname[IFNAMSIZ];
89#if SOLARIS || defined(__sgi)
90	kmutex_t	nat_lock;
91#endif
92} nat_t;
93
94typedef	struct	ipnat	{
95	struct	ipnat	*in_next;
96	struct	ipnat	*in_rnext;
97	struct	ipnat	**in_prnext;
98	struct	ipnat	*in_mnext;
99	struct	ipnat	**in_pmnext;
100	void	*in_ifp;
101	void	*in_apr;
102	u_long	in_space;
103	u_int	in_use;
104	u_int	in_hits;
105	struct	in_addr	in_nextip;
106	u_short	in_pnext;
107	u_short	in_ippip;	/* IP #'s per IP# */
108	u_32_t	in_flags;	/* From here to in_dport must be reflected */
109	u_short	in_spare;
110	u_short	in_ppip;	/* ports per IP */
111	u_short	in_port[2];	/* correctly in IPN_CMPSIZ */
112	struct	in_addr	in_in[2];
113	struct	in_addr	in_out[2];
114	struct	in_addr	in_src[2];
115	struct	frtuc	in_tuc;
116	int	in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
117	char	in_ifname[IFNAMSIZ];
118	char	in_plabel[APR_LABELLEN];	/* proxy label */
119	char	in_p;	/* protocol */
120} ipnat_t;
121
122#define	in_pmin		in_port[0]	/* Also holds static redir port */
123#define	in_pmax		in_port[1]
124#define	in_nip		in_nextip.s_addr
125#define	in_inip		in_in[0].s_addr
126#define	in_inmsk	in_in[1].s_addr
127#define	in_outip	in_out[0].s_addr
128#define	in_outmsk	in_out[1].s_addr
129#define	in_srcip	in_src[0].s_addr
130#define	in_srcmsk	in_src[1].s_addr
131#define	in_scmp		in_tuc.ftu_scmp
132#define	in_dcmp		in_tuc.ftu_dcmp
133#define	in_stop		in_tuc.ftu_stop
134#define	in_dtop		in_tuc.ftu_dtop
135#define	in_sport	in_tuc.ftu_sport
136#define	in_dport	in_tuc.ftu_dport
137
138#define	NAT_OUTBOUND	0
139#define	NAT_INBOUND	1
140
141#define	NAT_MAP		0x01
142#define	NAT_REDIRECT	0x02
143#define	NAT_BIMAP	(NAT_MAP|NAT_REDIRECT)
144#define	NAT_MAPBLK	0x04
145/* 0x100 reserved for FI_W_SPORT */
146/* 0x200 reserved for FI_W_DPORT */
147/* 0x400 reserved for FI_W_SADDR */
148/* 0x800 reserved for FI_W_DADDR */
149/* 0x1000 reserved for FI_W_NEWFR */
150
151#define	MAPBLK_MINPORT	1024	/* don't use reserved ports for src port */
152#define	USABLE_PORTS	(65536 - MAPBLK_MINPORT)
153
154#define	IPN_CMPSIZ	(sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
155
156typedef	struct	natlookup {
157	struct	in_addr	nl_inip;
158	struct	in_addr	nl_outip;
159	struct	in_addr	nl_realip;
160	int	nl_flags;
161	u_short	nl_inport;
162	u_short	nl_outport;
163	u_short	nl_realport;
164} natlookup_t;
165
166
167typedef struct  nat_save    {
168	void	*ipn_next;
169	struct	nat	ipn_nat;
170	struct	ipnat	ipn_ipnat;
171	struct	frentry ipn_fr;
172	int	ipn_dsize;
173	char	ipn_data[4];
174} nat_save_t;
175
176#define	ipn_rule	ipn_nat.nat_fr
177
178typedef	struct	natget	{
179	void	*ng_ptr;
180	int	ng_sz;
181} natget_t;
182
183
184typedef	struct	hostmap	{
185	struct	hostmap	*hm_next;
186	struct	hostmap	**hm_pnext;
187	struct	ipnat	*hm_ipnat;
188	struct	in_addr	hm_realip;
189	struct	in_addr	hm_mapip;
190	int	hm_ref;
191} hostmap_t;
192
193
194typedef	struct	natstat	{
195	u_long	ns_mapped[2];
196	u_long	ns_rules;
197	u_long	ns_added;
198	u_long	ns_expire;
199	u_long	ns_inuse;
200	u_long	ns_logged;
201	u_long	ns_logfail;
202	u_long	ns_memfail;
203	u_long	ns_badnat;
204	nat_t	**ns_table[2];
205	ipnat_t	*ns_list;
206	void	*ns_apslist;
207	u_int	ns_nattab_sz;
208	u_int	ns_rultab_sz;
209	u_int	ns_rdrtab_sz;
210	nat_t	*ns_instances;
211	u_int	ns_wilds;
212} natstat_t;
213
214#define	IPN_ANY		0x000
215#define	IPN_TCP		0x001
216#define	IPN_UDP		0x002
217#define	IPN_TCPUDP	(IPN_TCP|IPN_UDP)
218#define	IPN_DELETE	0x004
219#define	IPN_ICMPERR	0x008
220#define	IPN_RF		(IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
221#define	IPN_AUTOPORTMAP	0x010
222#define	IPN_IPRANGE	0x020
223#define	IPN_USERFLAGS	(IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
224			 IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST)
225#define	IPN_FILTER	0x040
226#define	IPN_SPLIT	0x080
227#define	IPN_ROUNDR	0x100
228#define	IPN_NOTSRC	0x080000
229#define	IPN_NOTDST	0x100000
230
231
232typedef	struct	natlog {
233	struct	in_addr	nl_origip;
234	struct	in_addr	nl_outip;
235	struct	in_addr	nl_inip;
236	u_short	nl_origport;
237	u_short	nl_outport;
238	u_short	nl_inport;
239	u_short	nl_type;
240	int	nl_rule;
241	U_QUAD_T	nl_pkts;
242	U_QUAD_T	nl_bytes;
243	u_char	nl_p;
244} natlog_t;
245
246
247#define	NL_NEWMAP	NAT_MAP
248#define	NL_NEWRDR	NAT_REDIRECT
249#define	NL_NEWBIMAP	NAT_BIMAP
250#define	NL_NEWBLOCK	NAT_MAPBLK
251#define	NL_FLUSH	0xfffe
252#define	NL_EXPIRE	0xffff
253
254#define	NAT_HASH_FN(k,l,m)	(((k) + ((k) >> 12) + l) % (m))
255
256#define	LONG_SUM(in)	(((in) & 0xffff) + ((in) >> 16))
257
258#define	CALC_SUMD(s1, s2, sd) { \
259			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
260			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
261			    /* Do it twice */ \
262			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
263			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
264			    /* Because ~1 == -2, We really need ~1 == -1 */ \
265			    if ((s1) > (s2)) (s2)--; \
266			    (sd) = (s2) - (s1); \
267			    (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
268
269
270extern	u_int	ipf_nattable_sz;
271extern	u_int	ipf_natrules_sz;
272extern	u_int	ipf_rdrrules_sz;
273extern	int	fr_nat_lock;
274extern	void	ip_natsync __P((void *));
275extern	u_long	fr_defnatage;
276extern	u_long	fr_defnaticmpage;
277extern	nat_t	**nat_table[2];
278extern	nat_t	*nat_instances;
279extern	ipnat_t	**nat_rules;
280extern	ipnat_t	**rdr_rules;
281extern	natstat_t	nat_stats;
282#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
283extern	int	nat_ioctl __P((caddr_t, u_long, int));
284#else
285extern	int	nat_ioctl __P((caddr_t, int, int));
286#endif
287extern	int	nat_init __P((void));
288extern	nat_t	*nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
289extern	nat_t	*nat_outlookup __P((void *, u_int, u_int, struct in_addr,
290				 struct in_addr, u_32_t, int));
291extern	nat_t	*nat_inlookup __P((void *, u_int, u_int, struct in_addr,
292				struct in_addr, u_32_t, int));
293extern	nat_t	*nat_maplookup __P((void *, u_int, struct in_addr,
294				struct in_addr));
295extern	nat_t	*nat_lookupredir __P((natlookup_t *));
296extern	nat_t	*nat_icmplookup __P((ip_t *, fr_info_t *, int));
297extern	nat_t	*nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
298extern	void	nat_insert __P((nat_t *));
299
300extern	int	ip_natout __P((ip_t *, fr_info_t *));
301extern	int	ip_natin __P((ip_t *, fr_info_t *));
302extern	void	ip_natunload __P((void)), ip_natexpire __P((void));
303extern	void	nat_log __P((struct nat *, u_int));
304extern	void	fix_incksum __P((u_short *, u_32_t));
305extern	void	fix_outcksum __P((u_short *, u_32_t));
306extern	void	fix_datacksum __P((u_short *, u_32_t));
307
308#endif /* __IP_NAT_H__ */
309