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