1d6c23f6fSyx160601 /*
2d6c23f6fSyx160601 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3d6c23f6fSyx160601 * Use is subject to license terms.
4d6c23f6fSyx160601 */
5d6c23f6fSyx160601
6d6c23f6fSyx160601 #if defined(KERNEL) || defined(_KERNEL)
7d6c23f6fSyx160601 # undef KERNEL
8d6c23f6fSyx160601 # undef _KERNEL
9d6c23f6fSyx160601 # define KERNEL 1
10d6c23f6fSyx160601 # define _KERNEL 1
11d6c23f6fSyx160601 #endif
12d6c23f6fSyx160601 #include <sys/errno.h>
13d6c23f6fSyx160601 #include <sys/types.h>
14d6c23f6fSyx160601 #include <sys/param.h>
15d6c23f6fSyx160601 #include <sys/time.h>
16d6c23f6fSyx160601 #if defined(__NetBSD__)
17d6c23f6fSyx160601 # if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL)
18d6c23f6fSyx160601 # include "opt_ipfilter_log.h"
19d6c23f6fSyx160601 # endif
20d6c23f6fSyx160601 #endif
21d6c23f6fSyx160601 #if defined(_KERNEL) && defined(__FreeBSD_version) && \
22d6c23f6fSyx160601 (__FreeBSD_version >= 220000)
23d6c23f6fSyx160601 # if (__FreeBSD_version >= 400000)
24d6c23f6fSyx160601 # if !defined(IPFILTER_LKM)
25d6c23f6fSyx160601 # include "opt_inet6.h"
26d6c23f6fSyx160601 # endif
27d6c23f6fSyx160601 # if (__FreeBSD_version == 400019)
28d6c23f6fSyx160601 # define CSUM_DELAY_DATA
29d6c23f6fSyx160601 # endif
30d6c23f6fSyx160601 # endif
31d6c23f6fSyx160601 # include <sys/filio.h>
32d6c23f6fSyx160601 #else
33d6c23f6fSyx160601 # include <sys/ioctl.h>
34d6c23f6fSyx160601 #endif
35d6c23f6fSyx160601 #if !defined(_AIX51)
36d6c23f6fSyx160601 # include <sys/fcntl.h>
37d6c23f6fSyx160601 #endif
38d6c23f6fSyx160601 #if defined(_KERNEL)
39d6c23f6fSyx160601 # include <sys/systm.h>
40d6c23f6fSyx160601 # include <sys/file.h>
41d6c23f6fSyx160601 #else
42d6c23f6fSyx160601 # include <stdio.h>
43d6c23f6fSyx160601 # include <string.h>
44d6c23f6fSyx160601 # include <stdlib.h>
45d6c23f6fSyx160601 # include <stddef.h>
46d6c23f6fSyx160601 # include <sys/file.h>
47d6c23f6fSyx160601 # define _KERNEL
48d6c23f6fSyx160601 # ifdef __OpenBSD__
49d6c23f6fSyx160601 struct file;
50d6c23f6fSyx160601 # endif
51d6c23f6fSyx160601 # include <sys/uio.h>
52d6c23f6fSyx160601 # undef _KERNEL
53d6c23f6fSyx160601 #endif
54d6c23f6fSyx160601 #if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \
55d6c23f6fSyx160601 !defined(linux)
56d6c23f6fSyx160601 # include <sys/mbuf.h>
57d6c23f6fSyx160601 #else
58d6c23f6fSyx160601 # if !defined(linux)
59d6c23f6fSyx160601 # include <sys/byteorder.h>
60d6c23f6fSyx160601 # endif
61d6c23f6fSyx160601 # if (SOLARIS2 < 5) && defined(sun)
62d6c23f6fSyx160601 # include <sys/dditypes.h>
63d6c23f6fSyx160601 # endif
64d6c23f6fSyx160601 #endif
65d6c23f6fSyx160601 #ifdef __hpux
66d6c23f6fSyx160601 # define _NET_ROUTE_INCLUDED
67d6c23f6fSyx160601 #endif
68d6c23f6fSyx160601 #if !defined(linux)
69d6c23f6fSyx160601 # include <sys/protosw.h>
70d6c23f6fSyx160601 #endif
71d6c23f6fSyx160601 #include <sys/socket.h>
72d6c23f6fSyx160601 #include <net/if.h>
73d6c23f6fSyx160601 #ifdef sun
74d6c23f6fSyx160601 # include <net/af.h>
75d6c23f6fSyx160601 #endif
76d6c23f6fSyx160601 #if !defined(_KERNEL) && defined(__FreeBSD__)
77d6c23f6fSyx160601 # include "radix_ipf.h"
78d6c23f6fSyx160601 #endif
79d6c23f6fSyx160601 #include <net/route.h>
80d6c23f6fSyx160601 #include <netinet/in.h>
81d6c23f6fSyx160601 #include <netinet/in_systm.h>
82d6c23f6fSyx160601 #include <netinet/ip.h>
83d6c23f6fSyx160601 #if !defined(linux)
84d6c23f6fSyx160601 # include <netinet/ip_var.h>
85d6c23f6fSyx160601 #endif
86d6c23f6fSyx160601 #if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
87d6c23f6fSyx160601 # include <sys/hashing.h>
88d6c23f6fSyx160601 # include <netinet/in_var.h>
89d6c23f6fSyx160601 #endif
90d6c23f6fSyx160601 #include <netinet/tcp.h>
91d6c23f6fSyx160601 #if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL)
92d6c23f6fSyx160601 # include <netinet/udp.h>
93d6c23f6fSyx160601 # include <netinet/ip_icmp.h>
94d6c23f6fSyx160601 #endif
95d6c23f6fSyx160601 #ifdef __hpux
96d6c23f6fSyx160601 # undef _NET_ROUTE_INCLUDED
97d6c23f6fSyx160601 #endif
98d6c23f6fSyx160601 #include "netinet/ip_compat.h"
99d6c23f6fSyx160601 #ifdef USE_INET6
100d6c23f6fSyx160601 # include <netinet/icmp6.h>
101*fd48ee9dSToomas Soome # if !defined(SOLARIS) && defined(_KERNEL) && !defined(__osf__) && \
102*fd48ee9dSToomas Soome !defined(__hpux)
103d6c23f6fSyx160601 # include <netinet6/in6_var.h>
104d6c23f6fSyx160601 # endif
105d6c23f6fSyx160601 #endif
106d6c23f6fSyx160601 #include <netinet/tcpip.h>
107d6c23f6fSyx160601 #include "netinet/ip_fil.h"
108d6c23f6fSyx160601 #include "netinet/ip_nat.h"
109d6c23f6fSyx160601 #include "netinet/ip_frag.h"
110d6c23f6fSyx160601 #include "netinet/ip_state.h"
111d6c23f6fSyx160601 #include "netinet/ip_proxy.h"
112d6c23f6fSyx160601 #include "netinet/ip_auth.h"
113d6c23f6fSyx160601 #include "netinet/ipf_stack.h"
114d6c23f6fSyx160601 #ifdef IPFILTER_SCAN
115d6c23f6fSyx160601 # include "netinet/ip_scan.h"
116d6c23f6fSyx160601 #endif
117d6c23f6fSyx160601 #ifdef IPFILTER_SYNC
118d6c23f6fSyx160601 # include "netinet/ip_sync.h"
119d6c23f6fSyx160601 #endif
120d6c23f6fSyx160601 #include "netinet/ip_pool.h"
121d6c23f6fSyx160601 #include "netinet/ip_htable.h"
122d6c23f6fSyx160601 #ifdef IPFILTER_COMPILED
123d6c23f6fSyx160601 # include "netinet/ip_rules.h"
124d6c23f6fSyx160601 #endif
125d6c23f6fSyx160601 #if defined(IPFILTER_BPF) && defined(_KERNEL)
126d6c23f6fSyx160601 # include <net/bpf.h>
127d6c23f6fSyx160601 #endif
128d6c23f6fSyx160601 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
129d6c23f6fSyx160601 # include <sys/malloc.h>
130d6c23f6fSyx160601 # if defined(_KERNEL) && !defined(IPFILTER_LKM)
131d6c23f6fSyx160601 # include "opt_ipfilter.h"
132d6c23f6fSyx160601 # endif
133d6c23f6fSyx160601 #endif
134d6c23f6fSyx160601 #include "netinet/ipl.h"
135d6c23f6fSyx160601 /* END OF INCLUDES */
136d6c23f6fSyx160601
137d6c23f6fSyx160601 #ifdef IPFILTER_COMPAT
138d6c23f6fSyx160601
139d6c23f6fSyx160601 # define IPFILTER_VERSION_4010900 4010900
140d6c23f6fSyx160601
141d6c23f6fSyx160601 struct nat_4010900 {
142d6c23f6fSyx160601 ipfmutex_t nat_lock;
143d6c23f6fSyx160601 struct nat *nat_next;
144d6c23f6fSyx160601 struct nat **nat_pnext;
145d6c23f6fSyx160601 struct nat *nat_hnext[2];
146d6c23f6fSyx160601 struct nat **nat_phnext[2];
147d6c23f6fSyx160601 struct hostmap *nat_hm;
148d6c23f6fSyx160601 void *nat_data;
149d6c23f6fSyx160601 struct nat **nat_me;
150d6c23f6fSyx160601 struct ipstate *nat_state;
151d6c23f6fSyx160601 struct ap_session *nat_aps; /* proxy session */
152d6c23f6fSyx160601 frentry_t *nat_fr; /* filter rule ptr if appropriate */
153d6c23f6fSyx160601 struct ipnat *nat_ptr; /* pointer back to the rule */
154d6c23f6fSyx160601 void *nat_ifps[2];
155d6c23f6fSyx160601 void *nat_sync;
156d6c23f6fSyx160601 ipftqent_t nat_tqe;
157d6c23f6fSyx160601 u_32_t nat_flags;
158d6c23f6fSyx160601 u_32_t nat_sumd[2]; /* ip checksum delta for data segment */
159d6c23f6fSyx160601 u_32_t nat_ipsumd; /* ip checksum delta for ip header */
160d6c23f6fSyx160601 u_32_t nat_mssclamp; /* if != zero clamp MSS to this */
161d6c23f6fSyx160601 i6addr_t nat_inip6;
162d6c23f6fSyx160601 i6addr_t nat_outip6;
163d6c23f6fSyx160601 i6addr_t nat_oip6; /* other ip */
164d6c23f6fSyx160601 U_QUAD_T nat_pkts[2];
165d6c23f6fSyx160601 U_QUAD_T nat_bytes[2];
166d6c23f6fSyx160601 union {
167d6c23f6fSyx160601 udpinfo_t nat_unu;
168d6c23f6fSyx160601 tcpinfo_t nat_unt;
169d6c23f6fSyx160601 icmpinfo_t nat_uni;
170d6c23f6fSyx160601 greinfo_t nat_ugre;
171d6c23f6fSyx160601 } nat_un;
172d6c23f6fSyx160601 u_short nat_oport; /* other port */
173d6c23f6fSyx160601 u_short nat_use;
174d6c23f6fSyx160601 u_char nat_p; /* protocol for NAT */
175d6c23f6fSyx160601 int nat_dir;
176d6c23f6fSyx160601 int nat_ref; /* reference count */
177d6c23f6fSyx160601 int nat_hv[2];
178d6c23f6fSyx160601 char nat_ifnames[2][LIFNAMSIZ];
179d6c23f6fSyx160601 int nat_rev; /* 0 = forward, 1 = reverse */
180d6c23f6fSyx160601 int nat_redir;
181d6c23f6fSyx160601 };
182d6c23f6fSyx160601
183d6c23f6fSyx160601 struct nat_save_4010900 {
184d6c23f6fSyx160601 void *ipn_next;
185d6c23f6fSyx160601 struct nat_4010900 ipn_nat;
186d6c23f6fSyx160601 struct ipnat ipn_ipnat;
187d6c23f6fSyx160601 struct frentry ipn_fr;
188d6c23f6fSyx160601 int ipn_dsize;
189d6c23f6fSyx160601 char ipn_data[4];
190d6c23f6fSyx160601 };
191d6c23f6fSyx160601
192d6c23f6fSyx160601 struct natlookup_4010900 {
193d6c23f6fSyx160601 struct in_addr nlc_inip;
194d6c23f6fSyx160601 struct in_addr nlc_outip;
195d6c23f6fSyx160601 struct in_addr nlc_realip;
196d6c23f6fSyx160601 int nlc_flags;
197d6c23f6fSyx160601 u_short nlc_inport;
198d6c23f6fSyx160601 u_short nlc_outport;
199d6c23f6fSyx160601 u_short nlc_realport;
200d6c23f6fSyx160601 };
201d6c23f6fSyx160601
202d6c23f6fSyx160601
203d6c23f6fSyx160601 /* ------------------------------------------------------------------------ */
204d6c23f6fSyx160601 /* Function: fr_incomptrans */
205d6c23f6fSyx160601 /* Returns: int - 0 = success, else failure */
206d6c23f6fSyx160601 /* Parameters: obj(I) - pointer to ioctl data */
207d6c23f6fSyx160601 /* ptr(I) - pointer to store real data in */
208d6c23f6fSyx160601 /* */
209d6c23f6fSyx160601 /* Translate the copied in ipfobj_t to new for backward compatibility at */
210d6c23f6fSyx160601 /* the ABI for user land. */
211d6c23f6fSyx160601 /* ------------------------------------------------------------------------ */
fr_incomptrans(obj,ptr)212d6c23f6fSyx160601 int fr_incomptrans(obj, ptr)
213d6c23f6fSyx160601 ipfobj_t *obj;
214d6c23f6fSyx160601 void *ptr;
215d6c23f6fSyx160601 {
216d6c23f6fSyx160601 int error;
217d6c23f6fSyx160601 natlookup_t *nlp;
218d6c23f6fSyx160601 nat_save_t *nsp;
219d6c23f6fSyx160601 struct nat_save_4010900 nsc;
220d6c23f6fSyx160601 struct natlookup_4010900 nlc;
221d6c23f6fSyx160601
222d6c23f6fSyx160601 switch (obj->ipfo_type)
223d6c23f6fSyx160601 {
224d6c23f6fSyx160601 case IPFOBJ_NATLOOKUP :
225d6c23f6fSyx160601 if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) ||
226d6c23f6fSyx160601 (obj->ipfo_size != sizeof (nlc)))
227d6c23f6fSyx160601 return EINVAL;
228d6c23f6fSyx160601 error = COPYIN((caddr_t)obj->ipfo_ptr, (caddr_t)&nlc,
229d6c23f6fSyx160601 obj->ipfo_size);
230d6c23f6fSyx160601 if (!error) {
231d6c23f6fSyx160601 nlp = (natlookup_t *)ptr;
232d6c23f6fSyx160601 bzero((char *)nlp, sizeof (*nlp));
233d6c23f6fSyx160601 nlp->nl_inip = nlc.nlc_inip;
234d6c23f6fSyx160601 nlp->nl_outip = nlc.nlc_outip;
235d6c23f6fSyx160601 nlp->nl_inport = nlc.nlc_inport;
236d6c23f6fSyx160601 nlp->nl_outport = nlc.nlc_outport;
237d6c23f6fSyx160601 nlp->nl_flags = nlc.nlc_flags;
238d6c23f6fSyx160601 nlp->nl_v = 4;
239d6c23f6fSyx160601 }
240d6c23f6fSyx160601 break;
241d6c23f6fSyx160601 case IPFOBJ_NATSAVE :
242d6c23f6fSyx160601 if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) ||
243d6c23f6fSyx160601 (obj->ipfo_size != sizeof (nsc)))
244d6c23f6fSyx160601 return EINVAL;
245d6c23f6fSyx160601 error = COPYIN((caddr_t)obj->ipfo_ptr, (caddr_t)&nsc,
246d6c23f6fSyx160601 obj->ipfo_size);
247d6c23f6fSyx160601 if (!error) {
248d6c23f6fSyx160601 nsp = (nat_save_t *)ptr;
249d6c23f6fSyx160601 bzero((char *)nsp, sizeof (*nsp));
250d6c23f6fSyx160601 nsp->ipn_next = nsc.ipn_next;
251d6c23f6fSyx160601 nsp->ipn_dsize = nsc.ipn_dsize;
252d6c23f6fSyx160601 nsp->ipn_nat.nat_inip = nsc.ipn_nat.nat_inip;
253d6c23f6fSyx160601 nsp->ipn_nat.nat_outip = nsc.ipn_nat.nat_outip;
254d6c23f6fSyx160601 nsp->ipn_nat.nat_oip = nsc.ipn_nat.nat_oip;
255d6c23f6fSyx160601 nsp->ipn_nat.nat_inport = nsc.ipn_nat.nat_inport;
256d6c23f6fSyx160601 nsp->ipn_nat.nat_outport = nsc.ipn_nat.nat_outport;
257d6c23f6fSyx160601 nsp->ipn_nat.nat_oport = nsc.ipn_nat.nat_oport;
258d6c23f6fSyx160601 nsp->ipn_nat.nat_flags = nsc.ipn_nat.nat_flags;
259d6c23f6fSyx160601 nsp->ipn_nat.nat_v = 4;
260d6c23f6fSyx160601 }
261d6c23f6fSyx160601 break;
262d6c23f6fSyx160601 default :
263d6c23f6fSyx160601 return EINVAL;
264d6c23f6fSyx160601 }
265d6c23f6fSyx160601 return error;
266d6c23f6fSyx160601 }
267d6c23f6fSyx160601
268d6c23f6fSyx160601 /* ------------------------------------------------------------------------ */
269d6c23f6fSyx160601 /* Function: fr_outcomptrans */
270d6c23f6fSyx160601 /* Returns: int - 0 = success, else failure */
271d6c23f6fSyx160601 /* Parameters: obj(I) - pointer to ioctl data */
272d6c23f6fSyx160601 /* ptr(I) - pointer to store real data in */
273d6c23f6fSyx160601 /* */
274d6c23f6fSyx160601 /* Translate the copied out ipfobj_t to new definition for backward */
275d6c23f6fSyx160601 /* compatibility at the ABI for user land. */
276d6c23f6fSyx160601 /* ------------------------------------------------------------------------ */
fr_outcomptrans(obj,ptr)277d6c23f6fSyx160601 int fr_outcomptrans(obj, ptr)
278d6c23f6fSyx160601 ipfobj_t *obj;
279d6c23f6fSyx160601 void *ptr;
280d6c23f6fSyx160601 {
281d6c23f6fSyx160601 int error;
282d6c23f6fSyx160601 natlookup_t *nlp;
283d6c23f6fSyx160601 struct natlookup_4010900 nlc;
284d6c23f6fSyx160601
285d6c23f6fSyx160601 switch (obj->ipfo_type)
286d6c23f6fSyx160601 {
287d6c23f6fSyx160601 case IPFOBJ_NATLOOKUP :
288d6c23f6fSyx160601 if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) ||
289d6c23f6fSyx160601 (obj->ipfo_size != sizeof (nlc)))
290d6c23f6fSyx160601 return EINVAL;
291d6c23f6fSyx160601 bzero((char *)&nlc, sizeof (nlc));
292d6c23f6fSyx160601 nlp = (natlookup_t *)ptr;
293d6c23f6fSyx160601 nlc.nlc_inip = nlp->nl_inip;
294d6c23f6fSyx160601 nlc.nlc_outip = nlp->nl_outip;
295d6c23f6fSyx160601 nlc.nlc_realip = nlp->nl_realip;
296d6c23f6fSyx160601 nlc.nlc_inport = nlp->nl_inport;
297d6c23f6fSyx160601 nlc.nlc_outport = nlp->nl_outport;
298d6c23f6fSyx160601 nlc.nlc_realport = nlp->nl_realport;
299d6c23f6fSyx160601 nlc.nlc_flags = nlp->nl_flags;
300d6c23f6fSyx160601 error = COPYOUT((caddr_t)&nlc, (caddr_t)obj->ipfo_ptr,
301d6c23f6fSyx160601 obj->ipfo_size);
302d6c23f6fSyx160601 break;
303d6c23f6fSyx160601 default :
304d6c23f6fSyx160601 return EINVAL;
305d6c23f6fSyx160601 }
306d6c23f6fSyx160601 return error;
307d6c23f6fSyx160601 }
308d6c23f6fSyx160601
309d6c23f6fSyx160601 #endif /* IPFILTER_COMPAT */
310