summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_nat.h
blob: c0cab6911851c54faed70c91cd208e1793204932 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/*	$OpenBSD: ip_nat.h,v 1.19 2001/05/08 19:58:02 fgsch Exp $	*/

/*
 * Copyright (C) 1995-2000 by Darren Reed.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and due credit is given
 * to the original author and the contributors.
 *
 * @(#)ip_nat.h	1.5 2/4/96
 * $IPFilter: ip_nat.h,v 2.17.2.15 2001/04/06 13:47:35 darrenr Exp $
 */

#ifndef	__IP_NAT_H__
#define	__IP_NAT_H__

#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif

#if defined(__STDC__) || defined(__GNUC__)
#define	SIOCADNAT	_IOW('r', 60, struct ipnat *)
#define	SIOCRMNAT	_IOW('r', 61, struct ipnat *)
#define	SIOCGNATS	_IOWR('r', 62, struct natstat *)
#define	SIOCGNATL	_IOWR('r', 63, struct natlookup *)
#else
#define	SIOCADNAT	_IOW(r, 60, struct ipnat *)
#define	SIOCRMNAT	_IOW(r, 61, struct ipnat *)
#define	SIOCGNATS	_IOWR(r, 62, struct natstat *)
#define	SIOCGNATL	_IOWR(r, 63, struct natlookup *)
#endif

#undef	LARGE_NAT	/* define this if you're setting up a system to NAT
			 * LARGE numbers of networks/hosts - i.e. in the
			 * hundreds or thousands.  In such a case, you should
			 * also change the RDR_SIZE and NAT_SIZE below to more
			 * appropriate sizes.  The figures below were used for
			 * a setup with 1000-2000 networks to NAT.
			 */
#define	NAT_SIZE	127
#define	RDR_SIZE	127
#define	HOSTMAP_SIZE	127
#define	NAT_TABLE_SZ	127
#ifdef	LARGE_NAT
#undef	NAT_SIZE
#undef	RDR_SIZE
#undef	NAT_TABLE_SZ
#undef	HOSTMAP_SIZE	127
#define	NAT_SIZE	2047
#define	RDR_SIZE	2047
#define	NAT_TABLE_SZ	16383
#define	HOSTMAP_SIZE	8191
#endif
#ifndef	APR_LABELLEN
#define	APR_LABELLEN	16
#endif
#define	NAT_HW_CKSUM	0x80000000

#define	DEF_NAT_AGE	1200     /* 10 minutes (600 seconds) */

struct ap_session;

typedef	struct	nat	{
	u_long	nat_age;
	int	nat_flags;
	u_32_t	nat_sumd[2];
	u_32_t	nat_ipsumd;
	void	*nat_data;
	struct	ap_session	*nat_aps;		/* proxy session */
	struct	frentry	*nat_fr;	/* filter rule ptr if appropriate */
	struct	in_addr	nat_inip;
	struct	in_addr	nat_outip;
	struct	in_addr	nat_oip;	/* other ip */
	U_QUAD_T	nat_pkts;
	U_QUAD_T	nat_bytes;
	u_short	nat_oport;		/* other port */
	u_short	nat_inport;
	u_short	nat_outport;
	u_short	nat_use;
	u_char	nat_tcpstate[2];
	u_char	nat_p;			/* protocol for NAT */
	struct	ipnat	*nat_ptr;	/* pointer back to the rule */
	struct	hostmap	*nat_hm;
	struct	nat	*nat_next;
	struct	nat	*nat_hnext[2];
	struct	nat	**nat_phnext[2];
	void	*nat_ifp;
	int	nat_dir;
	char	nat_ifname[IFNAMSIZ];
#if SOLARIS || defined(__sgi)
	kmutex_t	nat_lock;
#endif
} nat_t;

typedef	struct	ipnat	{
	struct	ipnat	*in_next;
	struct	ipnat	*in_rnext;
	struct	ipnat	**in_prnext;
	struct	ipnat	*in_mnext;
	struct	ipnat	**in_pmnext;
	void	*in_ifp;
	void	*in_apr;
	u_long	in_space;
	u_int	in_use;
	u_int	in_hits;
	struct	in_addr	in_nextip;
	u_short	in_pnext;
	u_short	in_ippip;	/* IP #'s per IP# */
	u_32_t	in_flags;	/* From here to in_dport must be reflected */
	u_short	in_spare;
	u_short	in_ppip;	/* ports per IP */
	u_short	in_port[2];	/* correctly in IPN_CMPSIZ */
	struct	in_addr	in_in[2];
	struct	in_addr	in_out[2];
	struct	in_addr	in_src[2];
	struct	frtuc	in_tuc;
	int	in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
	char	in_ifname[IFNAMSIZ];
	char	in_plabel[APR_LABELLEN];	/* proxy label */
	char	in_p;	/* protocol */
} ipnat_t;

#define	in_pmin		in_port[0]	/* Also holds static redir port */
#define	in_pmax		in_port[1]
#define	in_nip		in_nextip.s_addr
#define	in_inip		in_in[0].s_addr
#define	in_inmsk	in_in[1].s_addr
#define	in_outip	in_out[0].s_addr
#define	in_outmsk	in_out[1].s_addr
#define	in_srcip	in_src[0].s_addr
#define	in_srcmsk	in_src[1].s_addr
#define	in_scmp		in_tuc.ftu_scmp
#define	in_dcmp		in_tuc.ftu_dcmp
#define	in_stop		in_tuc.ftu_stop
#define	in_dtop		in_tuc.ftu_dtop
#define	in_sport	in_tuc.ftu_sport
#define	in_dport	in_tuc.ftu_dport

#define	NAT_OUTBOUND	0
#define	NAT_INBOUND	1

#define	NAT_MAP		0x01
#define	NAT_REDIRECT	0x02
#define	NAT_BIMAP	(NAT_MAP|NAT_REDIRECT)
#define	NAT_MAPBLK	0x04
/* 0x100 reserved for FI_W_SPORT */
/* 0x200 reserved for FI_W_DPORT */
/* 0x400 reserved for FI_W_SADDR */
/* 0x800 reserved for FI_W_DADDR */
/* 0x1000 reserved for FI_W_NEWFR */

#define	MAPBLK_MINPORT	1024	/* don't use reserved ports for src port */
#define	USABLE_PORTS	(65536 - MAPBLK_MINPORT)

#define	IPN_CMPSIZ	(sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))

typedef	struct	natlookup {
	struct	in_addr	nl_inip;
	struct	in_addr	nl_outip;
	struct	in_addr	nl_realip;
	int	nl_flags;
	u_short	nl_inport;
	u_short	nl_outport;
	u_short	nl_realport;
} natlookup_t;


typedef struct  nat_save    {
	void	*ipn_next;
	struct	nat	ipn_nat;
	struct	ipnat	ipn_ipnat;
	struct	frentry ipn_fr;
	int	ipn_dsize;
	char	ipn_data[4];
} nat_save_t;

#define	ipn_rule	ipn_nat.nat_fr

typedef	struct	natget	{
	void	*ng_ptr;
	int	ng_sz;
} natget_t;


typedef	struct	hostmap	{
	struct	hostmap	*hm_next;
	struct	hostmap	**hm_pnext;
	struct	ipnat	*hm_ipnat;
	struct	in_addr	hm_realip;
	struct	in_addr	hm_mapip;
	int	hm_ref;
} hostmap_t;


typedef	struct	natstat	{
	u_long	ns_mapped[2];
	u_long	ns_rules;
	u_long	ns_added;
	u_long	ns_expire;
	u_long	ns_inuse;
	u_long	ns_logged;
	u_long	ns_logfail;
	u_long	ns_memfail;
	u_long	ns_badnat;
	nat_t	**ns_table[2];
	ipnat_t	*ns_list;
	void	*ns_apslist;
	u_int	ns_nattab_sz;
	u_int	ns_rultab_sz;
	u_int	ns_rdrtab_sz;
	nat_t	*ns_instances;
	u_int	ns_wilds;
} natstat_t;

#define	IPN_ANY		0x000
#define	IPN_TCP		0x001
#define	IPN_UDP		0x002
#define	IPN_TCPUDP	(IPN_TCP|IPN_UDP)
#define	IPN_DELETE	0x004
#define	IPN_ICMPERR	0x008
#define	IPN_RF		(IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
#define	IPN_AUTOPORTMAP	0x010
#define	IPN_IPRANGE	0x020
#define	IPN_USERFLAGS	(IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
			 IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST)
#define	IPN_FILTER	0x040
#define	IPN_SPLIT	0x080
#define	IPN_ROUNDR	0x100
#define	IPN_NOTSRC	0x080000
#define	IPN_NOTDST	0x100000
#define	IPN_FRAG	0x200000


typedef	struct	natlog {
	struct	in_addr	nl_origip;
	struct	in_addr	nl_outip;
	struct	in_addr	nl_inip;
	u_short	nl_origport;
	u_short	nl_outport;
	u_short	nl_inport;
	u_short	nl_type;
	int	nl_rule;
	U_QUAD_T	nl_pkts;
	U_QUAD_T	nl_bytes;
	u_char	nl_p;
} natlog_t;


#define	NL_NEWMAP	NAT_MAP
#define	NL_NEWRDR	NAT_REDIRECT
#define	NL_NEWBIMAP	NAT_BIMAP
#define	NL_NEWBLOCK	NAT_MAPBLK
#define	NL_FLUSH	0xfffe
#define	NL_EXPIRE	0xffff

#define	NAT_HASH_FN(k,l,m)	(((k) + ((k) >> 12) + l) % (m))

#define	LONG_SUM(in)	(((in) & 0xffff) + ((in) >> 16))

#define	CALC_SUMD(s1, s2, sd) { \
			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
			    /* Do it twice */ \
			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
			    /* Because ~1 == -2, We really need ~1 == -1 */ \
			    if ((s1) > (s2)) (s2)--; \
			    (sd) = (s2) - (s1); \
			    (sd) = ((sd) & 0xffff) + ((sd) >> 16); }


extern	u_int	ipf_nattable_sz;
extern	u_int	ipf_natrules_sz;
extern	u_int	ipf_rdrrules_sz;
extern	int	fr_nat_lock;
extern	void	ip_natsync __P((void *));
extern	u_long	fr_defnatage;
extern	u_long	fr_defnaticmpage;
extern	nat_t	**nat_table[2];
extern	nat_t	*nat_instances;
extern	ipnat_t	**nat_rules;
extern	ipnat_t	**rdr_rules;
extern	natstat_t	nat_stats;
#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
extern	int	nat_ioctl __P((caddr_t, u_long, int));
#else
extern	int	nat_ioctl __P((caddr_t, int, int));
#endif
extern	int	nat_init __P((void));
extern	nat_t	*nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
extern	nat_t	*nat_outlookup __P((void *, u_int, u_int, struct in_addr,
				 struct in_addr, u_32_t, int));
extern	nat_t	*nat_inlookup __P((void *, u_int, u_int, struct in_addr,
				struct in_addr, u_32_t, int));
extern	nat_t	*nat_maplookup __P((void *, u_int, struct in_addr,
				struct in_addr));
extern	nat_t	*nat_lookupredir __P((natlookup_t *));
extern	nat_t	*nat_icmplookup __P((ip_t *, fr_info_t *, int));
extern	nat_t	*nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
extern	void	nat_insert __P((nat_t *));

extern	int	nat_clearlist __P((void));

extern	int	ip_natout __P((ip_t *, fr_info_t *));
extern	int	ip_natin __P((ip_t *, fr_info_t *));
extern	void	ip_natunload __P((void)), ip_natexpire __P((void));
extern	void	nat_log __P((struct nat *, u_int));
extern	void	fix_incksum __P((u_short *, u_32_t));
extern	void	fix_outcksum __P((u_short *, u_32_t));
extern	void	fix_datacksum __P((u_short *, u_32_t));

#endif /* __IP_NAT_H__ */