/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#if defined(KERNEL) || defined(_KERNEL)
# undef KERNEL
# undef _KERNEL
# define KERNEL 1
# define _KERNEL 1
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#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 <sys/filio.h>
#else
# include <sys/ioctl.h>
#endif
#if !defined(_AIX51)
# include <sys/fcntl.h>
#endif
#if defined(_KERNEL)
# include <sys/systm.h>
# include <sys/file.h>
#else
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <stddef.h>
# include <sys/file.h>
# define _KERNEL
# ifdef __OpenBSD__
struct file;
# endif
# include <sys/uio.h>
# undef _KERNEL
#endif
#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \
!defined(linux)
# include <sys/mbuf.h>
#else
# if !defined(linux)
# include <sys/byteorder.h>
# endif
# if (SOLARIS2 < 5) && defined(sun)
# include <sys/dditypes.h>
# endif
#endif
#ifdef __hpux
# define _NET_ROUTE_INCLUDED
#endif
#if !defined(linux)
# include <sys/protosw.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#ifdef sun
# include <net/af.h>
#endif
#if !defined(_KERNEL) && defined(__FreeBSD__)
# include "radix_ipf.h"
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#if !defined(linux)
# include <netinet/ip_var.h>
#endif
#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
# include <sys/hashing.h>
# include <netinet/in_var.h>
#endif
#include <netinet/tcp.h>
#if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL)
# include <netinet/udp.h>
# include <netinet/ip_icmp.h>
#endif
#ifdef __hpux
# undef _NET_ROUTE_INCLUDED
#endif
#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
# if !SOLARIS && defined(_KERNEL) && !defined(__osf__) && !defined(__hpux)
# include <netinet6/in6_var.h>
# endif
#endif
#include <netinet/tcpip.h>
#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 <net/bpf.h>
#endif
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
# 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 */