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*f56257d8SToomas Soome # if !defined(SOLARIS) && defined(_KERNEL) && !defined(__osf__) && \ 102*f56257d8SToomas 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 /* ------------------------------------------------------------------------ */ 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 /* ------------------------------------------------------------------------ */ 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