ip_nat.h revision 60857
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.1.2.3 2000/01/24 12:44:24 darrenr Exp $
10 * $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.h 60857 2000-05-24 04:40:17Z 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_hstart[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_ppip;	/* ports per IP */
108	u_short	in_ippip;	/* IP #'s per IP# */
109	u_short	in_flags;	/* From here to in_dport must be reflected */
110	u_short	in_port[2];	/* correctly in IPN_CMPSIZ */
111	struct	in_addr	in_in[2];
112	struct	in_addr	in_out[2];
113	struct	in_addr	in_src[2];
114	struct	frtuc	in_tuc;
115	int	in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
116	char	in_ifname[IFNAMSIZ];
117	char	in_plabel[APR_LABELLEN];	/* proxy label */
118	char	in_p;	/* protocol */
119} ipnat_t;
120
121#define	in_pmin		in_port[0]	/* Also holds static redir port */
122#define	in_pmax		in_port[1]
123#define	in_nip		in_nextip.s_addr
124#define	in_inip		in_in[0].s_addr
125#define	in_inmsk	in_in[1].s_addr
126#define	in_outip	in_out[0].s_addr
127#define	in_outmsk	in_out[1].s_addr
128#define	in_srcip	in_src[0].s_addr
129#define	in_srcmsk	in_src[1].s_addr
130#define	in_scmp		in_tuc.ftu_scmp
131#define	in_dcmp		in_tuc.ftu_dcmp
132#define	in_stop		in_tuc.ftu_stop
133#define	in_dtop		in_tuc.ftu_dtop
134#define	in_sport	in_tuc.ftu_sport
135#define	in_dport	in_tuc.ftu_dport
136
137#define	NAT_OUTBOUND	0
138#define	NAT_INBOUND	1
139
140#define	NAT_MAP		0x01
141#define	NAT_REDIRECT	0x02
142#define	NAT_BIMAP	(NAT_MAP|NAT_REDIRECT)
143#define	NAT_MAPBLK	0x04
144
145#define	MAPBLK_MINPORT	1024	/* don't use reserved ports for src port */
146#define	USABLE_PORTS	(65536 - MAPBLK_MINPORT)
147
148#define	IPN_CMPSIZ	(sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
149
150typedef	struct	natlookup {
151	struct	in_addr	nl_inip;
152	struct	in_addr	nl_outip;
153	struct	in_addr	nl_realip;
154	int	nl_flags;
155	u_short	nl_inport;
156	u_short	nl_outport;
157	u_short	nl_realport;
158} natlookup_t;
159
160
161typedef struct  nat_save    {
162	void	*ipn_next;
163	struct	nat	ipn_nat;
164	struct	ipnat	ipn_ipnat;
165	struct	frentry ipn_fr;
166	int	ipn_dsize;
167	char	ipn_data[4];
168} nat_save_t;
169
170#define	ipn_rule	ipn_nat.nat_fr
171
172typedef	struct	natget	{
173	void	*ng_ptr;
174	int	ng_sz;
175} natget_t;
176
177
178typedef	struct	hostmap	{
179	struct	hostmap	*hm_next;
180	struct	hostmap	**hm_pnext;
181	struct	ipnat	*hm_ipnat;
182	struct	in_addr	hm_realip;
183	struct	in_addr	hm_mapip;
184	int	hm_ref;
185} hostmap_t;
186
187
188typedef	struct	natstat	{
189	u_long	ns_mapped[2];
190	u_long	ns_rules;
191	u_long	ns_added;
192	u_long	ns_expire;
193	u_long	ns_inuse;
194	u_long	ns_logged;
195	u_long	ns_logfail;
196	u_long	ns_memfail;
197	u_long	ns_badnat;
198	nat_t	**ns_table[2];
199	ipnat_t	*ns_list;
200	void	*ns_apslist;
201	u_int	ns_nattab_sz;
202	u_int	ns_rultab_sz;
203	u_int	ns_rdrtab_sz;
204	nat_t	*ns_instances;
205} natstat_t;
206
207#define	IPN_ANY		0x000
208#define	IPN_TCP		0x001
209#define	IPN_UDP		0x002
210#define	IPN_TCPUDP	(IPN_TCP|IPN_UDP)
211#define	IPN_DELETE	0x004
212#define	IPN_ICMPERR	0x008
213#define	IPN_RF		(IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
214#define	IPN_AUTOPORTMAP	0x010
215#define	IPN_IPRANGE	0x020
216#define	IPN_USERFLAGS	(IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|\
217			 IPN_SPLIT|IPN_ROUNDR|IPN_FILTER)
218#define	IPN_FILTER	0x040
219#define	IPN_SPLIT	0x080
220#define	IPN_ROUNDR	0x100
221
222
223typedef	struct	natlog {
224	struct	in_addr	nl_origip;
225	struct	in_addr	nl_outip;
226	struct	in_addr	nl_inip;
227	u_short	nl_origport;
228	u_short	nl_outport;
229	u_short	nl_inport;
230	u_short	nl_type;
231	int	nl_rule;
232	U_QUAD_T	nl_pkts;
233	U_QUAD_T	nl_bytes;
234	u_char	nl_p;
235} natlog_t;
236
237
238#define	NL_NEWMAP	NAT_MAP
239#define	NL_NEWRDR	NAT_REDIRECT
240#define	NL_EXPIRE	0xffff
241
242#define	NAT_HASH_FN(k,l,m)	(((k) + ((k) >> 12) + l) % (m))
243
244#define	LONG_SUM(in)	(((in) & 0xffff) + ((in) >> 16))
245
246#define	CALC_SUMD(s1, s2, sd) { \
247			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
248			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
249			    /* Do it twice */ \
250			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
251			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
252			    /* Because ~1 == -2, We really need ~1 == -1 */ \
253			    if ((s1) > (s2)) (s2)--; \
254			    (sd) = (s2) - (s1); \
255			    (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
256
257
258extern	u_int	ipf_nattable_sz;
259extern	u_int	ipf_natrules_sz;
260extern	u_int	ipf_rdrrules_sz;
261extern	int	fr_nat_lock;
262extern	void	ip_natsync __P((void *));
263extern	u_long	fr_defnatage;
264extern	u_long	fr_defnaticmpage;
265extern	nat_t	**nat_table[2];
266extern	nat_t	*nat_instances;
267extern	ipnat_t	**nat_rules;
268extern	ipnat_t	**rdr_rules;
269extern	natstat_t	nat_stats;
270#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
271extern	int	nat_ioctl __P((caddr_t, u_long, int));
272#else
273extern	int	nat_ioctl __P((caddr_t, int, int));
274#endif
275extern	int	nat_init __P((void));
276extern	nat_t	*nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
277extern	nat_t	*nat_outlookup __P((void *, u_int, u_int, struct in_addr,
278				 struct in_addr, u_32_t));
279extern	nat_t	*nat_inlookup __P((void *, u_int, u_int, struct in_addr,
280				struct in_addr, u_32_t));
281extern	nat_t	*nat_maplookup __P((void *, u_int, struct in_addr,
282				struct in_addr));
283extern	nat_t	*nat_lookupredir __P((natlookup_t *));
284extern	nat_t	*nat_icmplookup __P((ip_t *, fr_info_t *, int));
285extern	nat_t	*nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
286extern	void	nat_insert __P((nat_t *));
287
288extern	int	ip_natout __P((ip_t *, fr_info_t *));
289extern	int	ip_natin __P((ip_t *, fr_info_t *));
290extern	void	ip_natunload __P((void)), ip_natexpire __P((void));
291extern	void	nat_log __P((struct nat *, u_int));
292extern	void	fix_incksum __P((u_short *, u_32_t, int));
293extern	void	fix_outcksum __P((u_short *, u_32_t, int));
294
295#endif /* __IP_NAT_H__ */
296