/* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #if defined(KERNEL) || defined(_KERNEL) # undef KERNEL # undef _KERNEL # define KERNEL 1 # define _KERNEL 1 #endif #include #include #include #include #if defined(__NetBSD__) # if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL) # include "opt_ipfilter_log.h" # endif #endif #if defined(_KERNEL) && defined(__FreeBSD_version) && \ (__FreeBSD_version >= 220000) # if (__FreeBSD_version >= 400000) # if !defined(IPFILTER_LKM) # include "opt_inet6.h" # endif # if (__FreeBSD_version == 400019) # define CSUM_DELAY_DATA # endif # endif # include #else # include #endif #if !defined(_AIX51) # include #endif #if defined(_KERNEL) # include # include #else # include # include # include # include # include # define _KERNEL # ifdef __OpenBSD__ struct file; # endif # include # undef _KERNEL #endif #if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \ !defined(linux) # include #else # if !defined(linux) # include # endif # if (SOLARIS2 < 5) && defined(sun) # include # endif #endif #ifdef __hpux # define _NET_ROUTE_INCLUDED #endif #if !defined(linux) # include #endif #include #include #ifdef sun # include #endif #if !defined(_KERNEL) && defined(__FreeBSD__) # include "radix_ipf.h" #endif #include #include #include #include #if !defined(linux) # include #endif #if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */ # include # include #endif #include #if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL) # include # include #endif #ifdef __hpux # undef _NET_ROUTE_INCLUDED #endif #include "netinet/ip_compat.h" #ifdef USE_INET6 # include # if !defined(SOLARIS) && defined(_KERNEL) && !defined(__osf__) && \ !defined(__hpux) # include # endif #endif #include #include "netinet/ip_fil.h" #include "netinet/ip_nat.h" #include "netinet/ip_frag.h" #include "netinet/ip_state.h" #include "netinet/ip_proxy.h" #include "netinet/ip_auth.h" #include "netinet/ipf_stack.h" #ifdef IPFILTER_SCAN # include "netinet/ip_scan.h" #endif #ifdef IPFILTER_SYNC # include "netinet/ip_sync.h" #endif #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" #ifdef IPFILTER_COMPILED # include "netinet/ip_rules.h" #endif #if defined(IPFILTER_BPF) && defined(_KERNEL) # include #endif #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) # include # if defined(_KERNEL) && !defined(IPFILTER_LKM) # include "opt_ipfilter.h" # endif #endif #include "netinet/ipl.h" /* END OF INCLUDES */ #ifdef IPFILTER_COMPAT # define IPFILTER_VERSION_4010900 4010900 struct nat_4010900 { ipfmutex_t nat_lock; struct nat *nat_next; struct nat **nat_pnext; struct nat *nat_hnext[2]; struct nat **nat_phnext[2]; struct hostmap *nat_hm; void *nat_data; struct nat **nat_me; struct ipstate *nat_state; struct ap_session *nat_aps; /* proxy session */ frentry_t *nat_fr; /* filter rule ptr if appropriate */ struct ipnat *nat_ptr; /* pointer back to the rule */ void *nat_ifps[2]; void *nat_sync; ipftqent_t nat_tqe; u_32_t nat_flags; u_32_t nat_sumd[2]; /* ip checksum delta for data segment */ u_32_t nat_ipsumd; /* ip checksum delta for ip header */ u_32_t nat_mssclamp; /* if != zero clamp MSS to this */ i6addr_t nat_inip6; i6addr_t nat_outip6; i6addr_t nat_oip6; /* other ip */ U_QUAD_T nat_pkts[2]; U_QUAD_T nat_bytes[2]; union { udpinfo_t nat_unu; tcpinfo_t nat_unt; icmpinfo_t nat_uni; greinfo_t nat_ugre; } nat_un; u_short nat_oport; /* other port */ u_short nat_use; u_char nat_p; /* protocol for NAT */ int nat_dir; int nat_ref; /* reference count */ int nat_hv[2]; char nat_ifnames[2][LIFNAMSIZ]; int nat_rev; /* 0 = forward, 1 = reverse */ int nat_redir; }; struct nat_save_4010900 { void *ipn_next; struct nat_4010900 ipn_nat; struct ipnat ipn_ipnat; struct frentry ipn_fr; int ipn_dsize; char ipn_data[4]; }; struct natlookup_4010900 { struct in_addr nlc_inip; struct in_addr nlc_outip; struct in_addr nlc_realip; int nlc_flags; u_short nlc_inport; u_short nlc_outport; u_short nlc_realport; }; /* ------------------------------------------------------------------------ */ /* Function: fr_incomptrans */ /* Returns: int - 0 = success, else failure */ /* Parameters: obj(I) - pointer to ioctl data */ /* ptr(I) - pointer to store real data in */ /* */ /* Translate the copied in ipfobj_t to new for backward compatibility at */ /* the ABI for user land. */ /* ------------------------------------------------------------------------ */ int fr_incomptrans(obj, ptr) ipfobj_t *obj; void *ptr; { int error; natlookup_t *nlp; nat_save_t *nsp; struct nat_save_4010900 nsc; struct natlookup_4010900 nlc; switch (obj->ipfo_type) { case IPFOBJ_NATLOOKUP : if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) || (obj->ipfo_size != sizeof (nlc))) return EINVAL; error = COPYIN((caddr_t)obj->ipfo_ptr, (caddr_t)&nlc, obj->ipfo_size); if (!error) { nlp = (natlookup_t *)ptr; bzero((char *)nlp, sizeof (*nlp)); nlp->nl_inip = nlc.nlc_inip; nlp->nl_outip = nlc.nlc_outip; nlp->nl_inport = nlc.nlc_inport; nlp->nl_outport = nlc.nlc_outport; nlp->nl_flags = nlc.nlc_flags; nlp->nl_v = 4; } break; case IPFOBJ_NATSAVE : if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) || (obj->ipfo_size != sizeof (nsc))) return EINVAL; error = COPYIN((caddr_t)obj->ipfo_ptr, (caddr_t)&nsc, obj->ipfo_size); if (!error) { nsp = (nat_save_t *)ptr; bzero((char *)nsp, sizeof (*nsp)); nsp->ipn_next = nsc.ipn_next; nsp->ipn_dsize = nsc.ipn_dsize; nsp->ipn_nat.nat_inip = nsc.ipn_nat.nat_inip; nsp->ipn_nat.nat_outip = nsc.ipn_nat.nat_outip; nsp->ipn_nat.nat_oip = nsc.ipn_nat.nat_oip; nsp->ipn_nat.nat_inport = nsc.ipn_nat.nat_inport; nsp->ipn_nat.nat_outport = nsc.ipn_nat.nat_outport; nsp->ipn_nat.nat_oport = nsc.ipn_nat.nat_oport; nsp->ipn_nat.nat_flags = nsc.ipn_nat.nat_flags; nsp->ipn_nat.nat_v = 4; } break; default : return EINVAL; } return error; } /* ------------------------------------------------------------------------ */ /* Function: fr_outcomptrans */ /* Returns: int - 0 = success, else failure */ /* Parameters: obj(I) - pointer to ioctl data */ /* ptr(I) - pointer to store real data in */ /* */ /* Translate the copied out ipfobj_t to new definition for backward */ /* compatibility at the ABI for user land. */ /* ------------------------------------------------------------------------ */ int fr_outcomptrans(obj, ptr) ipfobj_t *obj; void *ptr; { int error; natlookup_t *nlp; struct natlookup_4010900 nlc; switch (obj->ipfo_type) { case IPFOBJ_NATLOOKUP : if ((obj->ipfo_rev != IPFILTER_VERSION_4010900) || (obj->ipfo_size != sizeof (nlc))) return EINVAL; bzero((char *)&nlc, sizeof (nlc)); nlp = (natlookup_t *)ptr; nlc.nlc_inip = nlp->nl_inip; nlc.nlc_outip = nlp->nl_outip; nlc.nlc_realip = nlp->nl_realip; nlc.nlc_inport = nlp->nl_inport; nlc.nlc_outport = nlp->nl_outport; nlc.nlc_realport = nlp->nl_realport; nlc.nlc_flags = nlp->nl_flags; error = COPYOUT((caddr_t)&nlc, (caddr_t)obj->ipfo_ptr, obj->ipfo_size); break; default : return EINVAL; } return error; } #endif /* IPFILTER_COMPAT */