Import IPFilter 3.4.26 kernel sources, including H.323 proxy.
Include the licence file for both IPFilter and the H.323 proxy (from QNX), for convienence.
This commit is contained in:
parent
76531d9f8d
commit
13114a18ac
@ -1,6 +1,4 @@
|
||||
Copyright (C) 1993-2001 by Darren Reed.
|
||||
|
||||
$FreeBSD$
|
||||
Copyright (C) 1993-2002 by Darren Reed.
|
||||
|
||||
The author accepts no responsibility for the use of this software and
|
||||
provides it on an ``as is'' basis without express or implied warranty.
|
||||
@ -27,3 +25,4 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
I hate legalese, don't you ?
|
||||
|
||||
|
@ -97,7 +97,7 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.59 2002/03/25 11:07:37 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#ifndef _KERNEL
|
||||
@ -211,9 +211,7 @@ fr_info_t *fin;
|
||||
fin->fin_data[1] = 0;
|
||||
fin->fin_rule = -1;
|
||||
fin->fin_group = -1;
|
||||
#ifdef _KERNEL
|
||||
fin->fin_icode = ipl_unreach;
|
||||
#endif
|
||||
v = fin->fin_v;
|
||||
fi->fi_v = v;
|
||||
fin->fin_hlen = hlen;
|
||||
@ -263,6 +261,7 @@ fr_info_t *fin;
|
||||
fin->fin_off = off;
|
||||
fin->fin_plen = plen;
|
||||
fin->fin_dp = (char *)tcp;
|
||||
fin->fin_misc = 0;
|
||||
off <<= 3;
|
||||
|
||||
switch (p)
|
||||
@ -295,7 +294,7 @@ fr_info_t *fin;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(plen >= hlen + minicmpsz))
|
||||
if (!(plen >= minicmpsz))
|
||||
fi->fi_fl |= FI_SHORT;
|
||||
|
||||
break;
|
||||
@ -1496,7 +1495,7 @@ nodata:
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id: fil.c,v 2.35.2.58 2002/03/13 02:23:13 darrenr Exp $
|
||||
* $Id: fil.c,v 2.35.2.59 2002/03/25 11:07:37 darrenr Exp $
|
||||
*/
|
||||
/*
|
||||
* Copy data from an mbuf chain starting "off" bytes from the beginning,
|
||||
|
@ -104,7 +104,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
|
||||
#endif
|
||||
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.17 2002/03/06 09:44:10 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.19 2002/04/23 14:57:27 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
@ -405,6 +405,7 @@ fr_authioctlloop:
|
||||
RWLOCK_EXIT(&ipf_auth);
|
||||
return 0;
|
||||
}
|
||||
RWLOCK_EXIT(&ipf_auth);
|
||||
#ifdef _KERNEL
|
||||
# if SOLARIS
|
||||
mutex_enter(&ipf_authmx);
|
||||
@ -417,7 +418,6 @@ fr_authioctlloop:
|
||||
error = SLEEP(&fr_authnext, "fr_authnext");
|
||||
# endif
|
||||
#endif
|
||||
RWLOCK_EXIT(&ipf_auth);
|
||||
if (!error)
|
||||
goto fr_authioctlloop;
|
||||
break;
|
||||
@ -447,7 +447,7 @@ fr_authioctlloop:
|
||||
#ifdef _KERNEL
|
||||
if (m && au->fra_info.fin_out) {
|
||||
# if SOLARIS
|
||||
error = fr_qout(fra->fra_q, m);
|
||||
error = (fr_qout(fra->fra_q, m) == 0) ? EINVAL : 0;
|
||||
# else /* SOLARIS */
|
||||
struct route ro;
|
||||
|
||||
@ -469,7 +469,7 @@ fr_authioctlloop:
|
||||
fr_authstats.fas_sendok++;
|
||||
} else if (m) {
|
||||
# if SOLARIS
|
||||
error = fr_qin(fra->fra_q, m);
|
||||
error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
|
||||
# else /* SOLARIS */
|
||||
ifq = &ipintrq;
|
||||
if (IF_QFULL(ifq)) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* @(#)ip_compat.h 1.8 1/14/96
|
||||
* $Id: ip_compat.h,v 2.26.2.39 2002/03/13 03:54:34 darrenr Exp $
|
||||
* $Id: ip_compat.h,v 2.26.2.43 2002/04/23 16:08:50 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_COMPAT_H__
|
||||
@ -103,7 +103,6 @@ struct ether_addr {
|
||||
# include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This is a workaround for <sys/uio.h> troubles on FreeBSD and OpenBSD.
|
||||
*/
|
||||
@ -197,10 +196,6 @@ typedef int minor_t;
|
||||
#endif /* SOLARIS */
|
||||
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
|
||||
|
||||
#if defined(__FreeBSD__) && (__FreeBSD__ >= 5) && defined(_KERNEL)
|
||||
# include <machine/in_cksum.h>
|
||||
#endif
|
||||
|
||||
#ifndef IP_OFFMASK
|
||||
#define IP_OFFMASK 0x1fff
|
||||
#endif
|
||||
@ -215,6 +210,30 @@ typedef int minor_t;
|
||||
#endif /* BSD > 199306 */
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
|
||||
# include <sys/param.h>
|
||||
# ifndef __FreeBSD_version
|
||||
# include <sys/osreldate.h>
|
||||
# endif
|
||||
# ifdef IPFILTER_LKM
|
||||
# define ACTUALLY_LKM_NOT_KERNEL
|
||||
# endif
|
||||
# if defined(__FreeBSD_version) && (__FreeBSD_version < 300000)
|
||||
# include <machine/spl.h>
|
||||
# else
|
||||
# if (__FreeBSD_version >= 300000) && (__FreeBSD_version < 400000)
|
||||
# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
|
||||
# define ACTUALLY_LKM_NOT_KERNEL
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif /* __FreeBSD__ && KERNEL */
|
||||
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) && \
|
||||
defined(_KERNEL)
|
||||
# include <machine/in_cksum.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These operating systems already take care of the problem for us.
|
||||
*/
|
||||
@ -230,6 +249,13 @@ typedef u_int32_t u_32_t;
|
||||
# include "opt_inet6.h"
|
||||
# endif
|
||||
# ifdef INET6
|
||||
# define USE_INET6
|
||||
# endif
|
||||
# endif
|
||||
# if !defined(_KERNEL) && !defined(IPFILTER_LKM)
|
||||
# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 400000)) || \
|
||||
(defined(OpenBSD) && (OpenBSD >= 200111)) || \
|
||||
(defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000))
|
||||
# define USE_INET6
|
||||
# endif
|
||||
# endif
|
||||
@ -341,40 +367,9 @@ union i6addr {
|
||||
#define IPOPT_EIP 145 /* EIP */
|
||||
#define IPOPT_FINN 205 /* FINN */
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
|
||||
# ifdef IPFILTER_LKM
|
||||
# ifndef __FreeBSD_cc_version
|
||||
# include <osreldate.h>
|
||||
# else
|
||||
# if __FreeBSD_cc_version < 430000
|
||||
# include <osreldate.h>
|
||||
# else
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# endif
|
||||
# define ACTUALLY_LKM_NOT_KERNEL
|
||||
# else
|
||||
# ifndef __FreeBSD_cc_version
|
||||
# include <sys/osreldate.h>
|
||||
# else
|
||||
# if __FreeBSD_cc_version < 430000
|
||||
# include <sys/osreldate.h>
|
||||
# else
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# if __FreeBSD__ < 3
|
||||
# include <machine/spl.h>
|
||||
# else
|
||||
# if __FreeBSD__ == 3
|
||||
# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
|
||||
# define ACTUALLY_LKM_NOT_KERNEL
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif /* __FreeBSD__ && KERNEL */
|
||||
#ifndef TCPOPT_WSCALE
|
||||
# define TCPOPT_WSCALE 3
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Build some macros and #defines to enable the same code to compile anywhere
|
||||
@ -580,7 +575,8 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
|
||||
defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_BSDI_VERSION)
|
||||
# include <vm/vm.h>
|
||||
# endif
|
||||
# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
|
||||
# if !defined(__FreeBSD__) || (defined (__FreeBSD_version) && \
|
||||
(__FreeBSD_version >= 300000))
|
||||
# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \
|
||||
(defined(OpenBSD) && (OpenBSD >= 200111))
|
||||
# include <uvm/uvm_extern.h>
|
||||
@ -589,9 +585,9 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
|
||||
extern vm_map_t kmem_map;
|
||||
# endif
|
||||
# include <sys/proc.h>
|
||||
# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
|
||||
# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */
|
||||
# include <vm/vm_kern.h>
|
||||
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
|
||||
# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */
|
||||
# ifdef M_PFIL
|
||||
# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFIL, M_NOWAIT)
|
||||
# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
|
||||
|
@ -25,6 +25,7 @@
|
||||
# endif
|
||||
#endif
|
||||
#ifdef __sgi
|
||||
# define _KMEMUSER
|
||||
# include <sys/ptimers.h>
|
||||
#endif
|
||||
#ifndef _KERNEL
|
||||
@ -119,7 +120,7 @@ extern int ip_optcopy __P((struct ip *, struct ip *));
|
||||
|
||||
#if !defined(lint)
|
||||
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.53 2002/03/13 02:29:08 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.55 2002/03/26 15:54:39 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
@ -359,7 +360,7 @@ int iplattach()
|
||||
}
|
||||
|
||||
# ifdef NETBSD_PF
|
||||
# if __NetBSD_Version__ >= 104200000
|
||||
# if (__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011)
|
||||
# if __NetBSD_Version__ >= 105110000
|
||||
if (
|
||||
!(ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET))
|
||||
@ -526,7 +527,7 @@ int ipldetach()
|
||||
fr_running = 0;
|
||||
|
||||
# ifdef NETBSD_PF
|
||||
# if __NetBSD_Version__ >= 104200000
|
||||
# if ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011))
|
||||
# if __NetBSD_Version__ >= 105110000
|
||||
if (ph_inet != NULL)
|
||||
error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
|
||||
@ -2136,8 +2137,8 @@ struct uio *uio;
|
||||
num = io->iov_len;
|
||||
if (num > left)
|
||||
num = left;
|
||||
start = io->iov_base + offset;
|
||||
if (start > io->iov_base + io->iov_len) {
|
||||
start = (char *)io->iov_base + offset;
|
||||
if (start > (char *)io->iov_base + io->iov_len) {
|
||||
offset -= io->iov_len;
|
||||
ioc++;
|
||||
continue;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* @(#)ip_fil.h 1.35 6/5/96
|
||||
* $Id: ip_fil.h,v 2.29.2.29 2002/03/13 03:56:46 darrenr Exp $
|
||||
* $Id: ip_fil.h,v 2.29.2.32 2002/04/10 04:57:14 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_FIL_H__
|
||||
@ -55,8 +55,8 @@
|
||||
# define SIOCFRSYN _IOW('r', 73, u_int)
|
||||
# define SIOCFRZST _IOWR('r', 74, struct friostat *)
|
||||
# define SIOCZRLST _IOWR('r', 75, struct frentry *)
|
||||
# define SIOCAUTHW _IOWR('r', 76, struct frauth_t *)
|
||||
# define SIOCAUTHR _IOWR('r', 77, struct frauth_t *)
|
||||
# define SIOCAUTHW _IOWR('r', 76, struct frauth *)
|
||||
# define SIOCAUTHR _IOWR('r', 77, struct frauth *)
|
||||
# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
|
||||
# define SIOCSTLCK _IOWR('r', 79, u_int)
|
||||
# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
|
||||
@ -80,8 +80,8 @@
|
||||
# define SIOCFRSYN _IOW(r, 73, u_int)
|
||||
# define SIOCFRZST _IOWR(r, 74, struct friostat *)
|
||||
# define SIOCZRLST _IOWR(r, 75, struct frentry *)
|
||||
# define SIOCAUTHW _IOWR(r, 76, struct frauth_t *)
|
||||
# define SIOCAUTHR _IOWR(r, 77, struct frauth_t *)
|
||||
# define SIOCAUTHW _IOWR(r, 76, struct frauth *)
|
||||
# define SIOCAUTHR _IOWR(r, 77, struct frauth *)
|
||||
# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
|
||||
# define SIOCSTLCK _IOWR(r, 79, u_int)
|
||||
# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
|
||||
@ -135,12 +135,11 @@ typedef struct fr_info {
|
||||
void *fin_ifp; /* interface packet is `on' */
|
||||
struct fr_ip fin_fi; /* IP Packet summary */
|
||||
u_short fin_data[2]; /* TCP/UDP ports, ICMP code/type */
|
||||
u_char fin_out; /* in or out ? 1 == out, 0 == in */
|
||||
u_char fin_rev; /* state only: 1 = reverse */
|
||||
u_int fin_out; /* in or out ? 1 == out, 0 == in */
|
||||
u_short fin_hlen; /* length of IP header in bytes */
|
||||
u_char fin_rev; /* state only: 1 = reverse */
|
||||
u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
|
||||
/* From here on is packet specific */
|
||||
u_char fin_icode; /* ICMP error to return */
|
||||
u_int fin_icode; /* ICMP error to return */
|
||||
u_32_t fin_rule; /* rule # last matched */
|
||||
u_32_t fin_group; /* group number, -1 for none */
|
||||
struct frentry *fin_fr; /* last matching rule */
|
||||
@ -149,6 +148,7 @@ typedef struct fr_info {
|
||||
u_short fin_off;
|
||||
u_short fin_dlen; /* length of data portion of packet */
|
||||
u_short fin_id; /* IP packet id field */
|
||||
u_int fin_misc;
|
||||
void *fin_mp; /* pointer to pointer to mbuf */
|
||||
#if SOLARIS
|
||||
void *fin_qfm; /* pointer to mblk where pkt starts */
|
||||
@ -170,6 +170,11 @@ typedef struct fr_info {
|
||||
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
|
||||
#define FI_LCSIZE offsetof(fr_info_t, fin_dp)
|
||||
|
||||
/*
|
||||
* For fin_misc
|
||||
*/
|
||||
#define FM_BADSTATE 0x00000001
|
||||
|
||||
/*
|
||||
* Size for copying cache fr_info structure
|
||||
*/
|
||||
@ -421,10 +426,10 @@ typedef struct iplog {
|
||||
typedef struct ipflog {
|
||||
#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
|
||||
(defined(OpenBSD) && (OpenBSD >= 199603))
|
||||
u_char fl_ifname[LIFNAMSIZ];
|
||||
char fl_ifname[LIFNAMSIZ];
|
||||
#else
|
||||
u_int fl_unit;
|
||||
u_char fl_ifname[LIFNAMSIZ];
|
||||
char fl_ifname[LIFNAMSIZ];
|
||||
#endif
|
||||
u_char fl_plen; /* extra data after hlen */
|
||||
u_char fl_hlen; /* length of IP headers saved */
|
||||
|
@ -90,7 +90,7 @@ extern struct timeout ipfr_slowtimer_ch;
|
||||
|
||||
#if !defined(lint)
|
||||
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.20 2002/03/06 09:44:11 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.21 2002/04/10 04:56:10 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
@ -584,9 +584,9 @@ void ipfr_slowtimer()
|
||||
|
||||
if (fr_running <= 0)
|
||||
return;
|
||||
READ_ENTER(&ipf_solaris);
|
||||
#endif
|
||||
|
||||
READ_ENTER(&ipf_solaris);
|
||||
#if defined(__sgi) && defined(_KERNEL)
|
||||
ipfilter_sgi_intfsync();
|
||||
#endif
|
||||
|
@ -52,18 +52,27 @@ unsigned char *data;
|
||||
int datlen, *off;
|
||||
unsigned short *port;
|
||||
{
|
||||
u_32_t addr;
|
||||
u_char *dp;
|
||||
int offset;
|
||||
|
||||
if (datlen < 6)
|
||||
return -1;
|
||||
|
||||
*port = 0;
|
||||
for (*off = 0; *off <= datlen - 6; *off = *off + 1) {
|
||||
if (ipaddr == *(int *)(data + *off))
|
||||
offset = *off;
|
||||
dp = (u_char *)data;
|
||||
|
||||
for (offset = 0; offset <= datlen - 6; offset++, dp++) {
|
||||
addr = (dp[0] << 24) | (dp[1] << 16) | (dp[2] << 8) | dp[3];
|
||||
if (ipaddr == addr)
|
||||
{
|
||||
*port = (*(data + *off + 4) << 8) + *(data + *off +5);
|
||||
*port = (*(dp + 4) << 8) | *(dp + 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (*off > datlen - 6) ? -1 : 0;
|
||||
*off = offset;
|
||||
return (offset > datlen - 6) ? -1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -109,11 +118,15 @@ ap_session_t *aps;
|
||||
* We are lucky here because this function is not
|
||||
* called with ipf_nat locked.
|
||||
*/
|
||||
if (nat_ioctl((caddr_t)ipn, SIOCRMNAT, FWRITE) == -1) {
|
||||
if (nat_ioctl((caddr_t)ipn, SIOCRMNAT, NAT_SYSSPACE|
|
||||
NAT_LOCKHELD|FWRITE) == -1) {
|
||||
/* log the error */
|
||||
}
|
||||
}
|
||||
KFREES(aps->aps_data, aps->aps_psiz);
|
||||
/* avoid double free */
|
||||
aps->aps_data = NULL;
|
||||
aps->aps_psiz = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -144,7 +157,7 @@ nat_t *nat;
|
||||
ipaddr = ip->ip_src.s_addr;
|
||||
|
||||
data = (unsigned char *)tcp + (tcp->th_off << 2);
|
||||
datlen = ip->ip_len - (ip->ip_hl << 2) - (tcp->th_off << 2);
|
||||
datlen = fin->fin_dlen - (tcp->th_off << 2);
|
||||
if (find_port(ipaddr, data, datlen, &off, &port) == 0) {
|
||||
ipnat_t *ipn;
|
||||
char *newarray;
|
||||
@ -177,13 +190,16 @@ nat_t *nat;
|
||||
* of calling nat_ioctl(), we add the nat rule ourself.
|
||||
*/
|
||||
RWLOCK_EXIT(&ipf_nat);
|
||||
if (nat_ioctl((caddr_t)ipn, SIOCADNAT, FWRITE) == -1) {
|
||||
if (nat_ioctl((caddr_t)ipn, SIOCADNAT,
|
||||
NAT_SYSSPACE|FWRITE) == -1) {
|
||||
READ_ENTER(&ipf_nat);
|
||||
return -1;
|
||||
}
|
||||
READ_ENTER(&ipf_nat);
|
||||
bcopy(aps->aps_data, newarray, aps->aps_psiz);
|
||||
KFREES(aps->aps_data, aps->aps_psiz);
|
||||
if (aps->aps_data != NULL && aps->aps_psiz > 0) {
|
||||
bcopy(aps->aps_data, newarray, aps->aps_psiz);
|
||||
KFREES(aps->aps_data, aps->aps_psiz);
|
||||
}
|
||||
aps->aps_data = newarray;
|
||||
aps->aps_psiz += sizeof(*ipn);
|
||||
}
|
||||
@ -256,8 +272,10 @@ nat_t *nat;
|
||||
#ifdef IPFILTER_LOG
|
||||
nat_log(ipn, (u_int)(nat->nat_ptr->in_redir));
|
||||
#endif
|
||||
*(int *)(data + off) = ip->ip_src.s_addr;
|
||||
*(short *)(data + off + 4) = ipn->nat_outport;
|
||||
bcopy((u_char*)&ip->ip_src.s_addr,
|
||||
data + off, 4);
|
||||
bcopy((u_char*)&ipn->nat_outport,
|
||||
data + off + 4, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* $Id: ip_log.c,v 2.5.2.17 2002/03/13 03:57:05 darrenr Exp $
|
||||
* $Id: ip_log.c,v 2.5.2.18 2002/03/26 15:54:40 darrenr Exp $
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#if defined(KERNEL) && !defined(_KERNEL)
|
||||
@ -84,6 +84,7 @@
|
||||
# include <net/route.h>
|
||||
# include <netinet/in.h>
|
||||
# ifdef __sgi
|
||||
# define _KMEMUSER
|
||||
# include <sys/ddi.h>
|
||||
# ifdef IFF_DRVRLOCK /* IRIX6 */
|
||||
# include <sys/hashing.h>
|
||||
|
@ -109,7 +109,7 @@ extern struct ifnet vpnif;
|
||||
|
||||
#if !defined(lint)
|
||||
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
|
||||
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.63 2002/03/06 09:44:11 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.66 2002/04/23 14:58:27 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
nat_t **nat_table[2] = { NULL, NULL },
|
||||
@ -425,7 +425,7 @@ caddr_t data;
|
||||
int mode;
|
||||
{
|
||||
register ipnat_t *nat, *nt, *n = NULL, **np = NULL;
|
||||
int error = 0, ret, arg;
|
||||
int error = 0, ret, arg, getlock;
|
||||
ipnat_t natd;
|
||||
u_32_t i, j;
|
||||
|
||||
@ -436,9 +436,15 @@ int mode;
|
||||
|
||||
nat = NULL; /* XXX gcc -Wuninitialized */
|
||||
KMALLOC(nt, ipnat_t *);
|
||||
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT))
|
||||
error = IRCOPYPTR(data, (char *)&natd, sizeof(natd));
|
||||
else if (cmd == SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
|
||||
getlock = (mode & NAT_LOCKHELD) ? 0 : 1;
|
||||
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
|
||||
if (mode & NAT_SYSSPACE) {
|
||||
bcopy(data, (char *)&natd, sizeof(natd));
|
||||
error = 0;
|
||||
} else {
|
||||
error = IRCOPYPTR(data, (char *)&natd, sizeof(natd));
|
||||
}
|
||||
} else if (cmd == SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
|
||||
error = IRCOPY(data, (char *)&arg, sizeof(arg));
|
||||
if (error)
|
||||
error = EFAULT;
|
||||
@ -450,7 +456,8 @@ int mode;
|
||||
/*
|
||||
* For add/delete, look to see if the NAT entry is already present
|
||||
*/
|
||||
WRITE_ENTER(&ipf_nat);
|
||||
if (getlock == 1)
|
||||
WRITE_ENTER(&ipf_nat);
|
||||
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
|
||||
nat = &natd;
|
||||
nat->in_flags &= IPN_USERFLAGS;
|
||||
@ -715,7 +722,8 @@ int mode;
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
|
||||
if (getlock == 1)
|
||||
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
|
||||
done:
|
||||
if (nt)
|
||||
KFREE(nt);
|
||||
@ -831,7 +839,7 @@ caddr_t data;
|
||||
return ENOMEM;
|
||||
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
|
||||
|
||||
bcopy((char *)aps, ipnn->ipn_data, sizeof(*aps));
|
||||
bcopy((char *)aps, (char *)ipnn->ipn_data, sizeof(*aps));
|
||||
if (aps->aps_data) {
|
||||
bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
|
||||
aps->aps_psiz);
|
||||
@ -1650,11 +1658,12 @@ int dir;
|
||||
{
|
||||
u_32_t sum1, sum2, sumd, sumd2 = 0;
|
||||
struct in_addr in;
|
||||
int flags, dlen;
|
||||
icmphdr_t *icmp;
|
||||
udphdr_t *udp;
|
||||
tcphdr_t *tcp;
|
||||
nat_t *nat;
|
||||
ip_t *oip;
|
||||
int flags;
|
||||
|
||||
if ((fin->fin_fl & FI_SHORT) || (fin->fin_off != 0))
|
||||
return NULL;
|
||||
@ -1673,6 +1682,13 @@ int dir;
|
||||
else if (oip->ip_p == IPPROTO_UDP)
|
||||
flags = IPN_UDP;
|
||||
udp = (udphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
|
||||
dlen = ip->ip_len - ((char *)udp - (char *)ip);
|
||||
/*
|
||||
* XXX - what if this is bogus hl and we go off the end ?
|
||||
* In this case, nat_icmplookup() will have returned NULL.
|
||||
*/
|
||||
tcp = (tcphdr_t *)udp;
|
||||
|
||||
/*
|
||||
* Need to adjust ICMP header to include the real IP#'s and
|
||||
* port #'s. Only apply a checksum change relative to the
|
||||
@ -1695,8 +1711,6 @@ int dir;
|
||||
* change in the UDP and TCP checksums require yet another
|
||||
* adjustment of the ICMP checksum of the ICMP error message.
|
||||
*
|
||||
* For the moment we forget about TCP, because that checksum is not
|
||||
* in the first 8 bytes, so it will not be available in most cases.
|
||||
*/
|
||||
|
||||
if (oip->ip_dst.s_addr == nat->nat_oip.s_addr) {
|
||||
@ -1754,15 +1768,25 @@ int dir;
|
||||
sumd2 = sumd;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/*
|
||||
* Fix TCP pseudo header checksum to compensate for the
|
||||
* IP address change. Before we can do the change, we
|
||||
* must make sure that oip is sufficient large to hold
|
||||
* the TCP checksum (normally it does not!).
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP) {
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the TCP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@ -1813,15 +1837,25 @@ int dir;
|
||||
sumd2 = sumd;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/*
|
||||
* Fix TCP pseudo header checksum to compensate for the
|
||||
* IP address change. Before we can do the change, we
|
||||
* must make sure that oip is sufficient large to hold
|
||||
* the TCP checksum (normally it does not!).
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP) {
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the TCP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1829,14 +1863,6 @@ int dir;
|
||||
}
|
||||
|
||||
if ((flags & IPN_TCPUDP) != 0) {
|
||||
tcphdr_t *tcp;
|
||||
|
||||
/*
|
||||
* XXX - what if this is bogus hl and we go off the end ?
|
||||
* In this case, nat_icmpinlookup() will have returned NULL.
|
||||
*/
|
||||
tcp = (tcphdr_t *)udp;
|
||||
|
||||
/*
|
||||
* Step 2 :
|
||||
* For offending TCP/UDP IP packets, translate the ports as
|
||||
@ -1852,8 +1878,9 @@ int dir;
|
||||
*
|
||||
* To further complicate: the TCP checksum is not in the first
|
||||
* 8 bytes of the offending ip packet, so it most likely is not
|
||||
* available (we might have to fix that if the encounter a
|
||||
* device that returns more than 8 data bytes on icmp error)
|
||||
* available. Some OSses like Solaris return enough bytes to
|
||||
* include the TCP checksum. So we have to check if the
|
||||
* ip->ip_len actually holds the TCP checksum of the oip!
|
||||
*/
|
||||
|
||||
if (nat->nat_oport == tcp->th_dport) {
|
||||
@ -1891,6 +1918,27 @@ int dir;
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix tcp checksum (if present) to compensate
|
||||
* port adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared to
|
||||
* the ICMP message.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to
|
||||
* compensate TCP checksum
|
||||
* adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tcp->th_dport != nat->nat_outport) {
|
||||
@ -1926,6 +1974,26 @@ int dir;
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix tcp checksum (if present) to compensate
|
||||
* port adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared to
|
||||
* the ICMP message.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate
|
||||
* UDP checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sumd2) {
|
||||
@ -2435,7 +2503,7 @@ maskloop:
|
||||
csump = &tcp->th_sum;
|
||||
MUTEX_ENTER(&nat->nat_lock);
|
||||
fr_tcp_age(&nat->nat_age,
|
||||
nat->nat_tcpstate, fin, 1);
|
||||
nat->nat_tcpstate, fin, 1, 0);
|
||||
if (nat->nat_age < fr_defnaticmpage)
|
||||
nat->nat_age = fr_defnaticmpage;
|
||||
#ifdef LARGE_NAT
|
||||
@ -2643,7 +2711,7 @@ maskloop:
|
||||
csump = &tcp->th_sum;
|
||||
MUTEX_ENTER(&nat->nat_lock);
|
||||
fr_tcp_age(&nat->nat_age,
|
||||
nat->nat_tcpstate, fin, 0);
|
||||
nat->nat_tcpstate, fin, 0, 0);
|
||||
if (nat->nat_age < fr_defnaticmpage)
|
||||
nat->nat_age = fr_defnaticmpage;
|
||||
#ifdef LARGE_NAT
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* @(#)ip_nat.h 1.5 2/4/96
|
||||
* $Id: ip_nat.h,v 2.17.2.25 2002/01/01 15:10:49 darrenr Exp $
|
||||
* $Id: ip_nat.h,v 2.17.2.26 2002/04/20 16:42:05 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_NAT_H__
|
||||
@ -276,6 +276,8 @@ typedef struct natlog {
|
||||
(sd) = (s2) - (s1); \
|
||||
(sd) = ((sd) & 0xffff) + ((sd) >> 16); }
|
||||
|
||||
#define NAT_SYSSPACE 0x80000000
|
||||
#define NAT_LOCKHELD 0x40000000
|
||||
|
||||
extern u_int ipf_nattable_sz;
|
||||
extern u_int ipf_natrules_sz;
|
||||
|
@ -93,7 +93,7 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.61 2002/03/06 14:07:36 darrenr Exp $";
|
||||
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.66 2002/04/15 12:14:03 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
@ -123,6 +123,7 @@ static ips_stat_t *fr_statetstats __P((void));
|
||||
static void fr_delstate __P((ipstate_t *));
|
||||
static int fr_state_remove __P((caddr_t));
|
||||
static void fr_ipsmove __P((ipstate_t **, ipstate_t *, u_int));
|
||||
static int fr_tcpoptions __P((tcphdr_t *));
|
||||
int fr_stputent __P((caddr_t));
|
||||
int fr_stgetent __P((caddr_t));
|
||||
void fr_stinsert __P((ipstate_t *));
|
||||
@ -298,7 +299,7 @@ caddr_t data;
|
||||
if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
|
||||
!bcmp((char *)&sp->is_src, (char *)&st.is_src,
|
||||
sizeof(st.is_src)) &&
|
||||
!bcmp((char *)&sp->is_dst, (char *)&st.is_src,
|
||||
!bcmp((char *)&sp->is_dst, (char *)&st.is_dst,
|
||||
sizeof(st.is_dst)) &&
|
||||
!bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
|
||||
sizeof(st.is_ps))) {
|
||||
@ -578,7 +579,8 @@ u_int flags;
|
||||
void *ifp;
|
||||
int out;
|
||||
|
||||
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT))
|
||||
if (fr_state_lock || (fin->fin_off != 0) || (fin->fin_fl & FI_SHORT) ||
|
||||
(fin->fin_misc & FM_BADSTATE))
|
||||
return NULL;
|
||||
if (ips_num == fr_statemax) {
|
||||
ips_stats.iss_max++;
|
||||
@ -619,6 +621,8 @@ u_int flags;
|
||||
|
||||
switch (is->is_p)
|
||||
{
|
||||
int off;
|
||||
|
||||
#ifdef USE_INET6
|
||||
case IPPROTO_ICMPV6 :
|
||||
ic = (struct icmp *)fin->fin_dp;
|
||||
@ -680,15 +684,22 @@ u_int flags;
|
||||
hv += is->is_dport;
|
||||
}
|
||||
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
|
||||
(tcp->th_off << 2) +
|
||||
(off = (tcp->th_off << 2)) +
|
||||
((tcp->th_flags & TH_SYN) ? 1 : 0) +
|
||||
((tcp->th_flags & TH_FIN) ? 1 : 0);
|
||||
is->is_maxsend = is->is_send;
|
||||
is->is_dend = 0;
|
||||
is->is_maxdwin = 1;
|
||||
is->is_maxswin = ntohs(tcp->th_win);
|
||||
if (is->is_maxswin == 0)
|
||||
is->is_maxswin = 1;
|
||||
|
||||
if ((tcp->th_flags & TH_OPENING) == TH_SYN)
|
||||
is->is_fsm = 1;
|
||||
|
||||
if ((tcp->th_flags & TH_SYN) &&
|
||||
((tcp->th_off << 2) >= (sizeof(*tcp) + 4)))
|
||||
is->is_swscale = fr_tcpoptions(tcp);
|
||||
|
||||
/*
|
||||
* If we're creating state for a starting connection, start the
|
||||
* timer on it as we'll never see an error if it fails to
|
||||
@ -785,7 +796,7 @@ u_int flags;
|
||||
is->is_me = stsave;
|
||||
if (is->is_p == IPPROTO_TCP) {
|
||||
fr_tcp_age(&is->is_age, is->is_state, fin,
|
||||
0); /* 0 = packet from the source */
|
||||
0, is->is_fsm); /* 0 = packet from the source */
|
||||
}
|
||||
#ifdef IPFILTER_LOG
|
||||
ipstate_log(is, ISL_NEW);
|
||||
@ -798,6 +809,46 @@ u_int flags;
|
||||
}
|
||||
|
||||
|
||||
static int fr_tcpoptions(tcp)
|
||||
tcphdr_t *tcp;
|
||||
{
|
||||
u_char *opt, *last;
|
||||
int wscale;
|
||||
|
||||
opt = (u_char *) (tcp + 1);
|
||||
last = ((u_char *)tcp) + (tcp->th_off << 2);
|
||||
|
||||
/* If we don't find wscale here, we need to clear it */
|
||||
wscale = -2;
|
||||
|
||||
/* Termination condition picked such that opt[0 .. 2] exist */
|
||||
while ((opt < last - 2) && (*opt != TCPOPT_EOL)) {
|
||||
switch (*opt) {
|
||||
case TCPOPT_NOP:
|
||||
opt++;
|
||||
continue;
|
||||
case TCPOPT_WSCALE:
|
||||
/* Proper length ? */
|
||||
if (opt[1] == 3) {
|
||||
if (opt[2] > 14)
|
||||
wscale = 14;
|
||||
else
|
||||
wscale = opt[2];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Unknown options must be two bytes+ */
|
||||
if (opt[1] < 2)
|
||||
break;
|
||||
opt += opt[1];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return wscale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* check to see if a packet with TCP headers fits within the TCP window.
|
||||
@ -813,9 +864,10 @@ tcphdr_t *tcp;
|
||||
register tcp_seq seq, ack, end;
|
||||
register int ackskew;
|
||||
tcpdata_t *fdata, *tdata;
|
||||
u_short win, maxwin;
|
||||
int ret = 0;
|
||||
u_32_t win, maxwin;
|
||||
int ret = 0, off;
|
||||
int source;
|
||||
int wscale;
|
||||
|
||||
/*
|
||||
* Find difference between last checked packet and this packet.
|
||||
@ -825,15 +877,29 @@ tcphdr_t *tcp;
|
||||
source = 0;
|
||||
fdata = &is->is_tcp.ts_data[!source];
|
||||
tdata = &is->is_tcp.ts_data[source];
|
||||
off = tcp->th_off << 2;
|
||||
seq = ntohl(tcp->th_seq);
|
||||
ack = ntohl(tcp->th_ack);
|
||||
win = ntohs(tcp->th_win);
|
||||
end = seq + fin->fin_dlen - (tcp->th_off << 2) +
|
||||
end = seq + fin->fin_dlen - off +
|
||||
((tcp->th_flags & TH_SYN) ? 1 : 0) +
|
||||
((tcp->th_flags & TH_FIN) ? 1 : 0);
|
||||
|
||||
|
||||
if ((tcp->th_flags & TH_SYN) && (off >= sizeof(*tcp) + 4))
|
||||
wscale = fr_tcpoptions(tcp);
|
||||
else
|
||||
wscale = -1;
|
||||
|
||||
MUTEX_ENTER(&is->is_lock);
|
||||
if (fdata->td_end == 0) {
|
||||
|
||||
if (wscale >= 0)
|
||||
fdata->td_wscale = wscale;
|
||||
else if (wscale == -2)
|
||||
fdata->td_wscale = tdata->td_wscale = 0;
|
||||
|
||||
if ((fdata->td_end == 0) &&
|
||||
(!is->is_fsm || ((tcp->th_flags & TH_OPENING) == TH_OPENING))) {
|
||||
/*
|
||||
* Must be a (outgoing) SYN-ACK in reply to a SYN.
|
||||
*/
|
||||
@ -853,6 +919,7 @@ tcphdr_t *tcp;
|
||||
if (seq == end)
|
||||
seq = end = fdata->td_end;
|
||||
|
||||
win <<= fdata->td_wscale;
|
||||
maxwin = tdata->td_maxwin;
|
||||
ackskew = tdata->td_end - ack;
|
||||
|
||||
@ -878,29 +945,33 @@ tcphdr_t *tcp;
|
||||
* Thus, when ackskew is negative but still seems to belong
|
||||
* to this session, we bump up the destinations end value.
|
||||
*/
|
||||
if (ackskew < 0)
|
||||
tdata->td_end = ack;
|
||||
|
||||
/* update max window seen */
|
||||
if (fdata->td_maxwin < win)
|
||||
fdata->td_maxwin = win;
|
||||
if (SEQ_GT(end, fdata->td_end))
|
||||
fdata->td_end = end;
|
||||
if (SEQ_GE(ack + win, tdata->td_maxend)) {
|
||||
tdata->td_maxend = ack + win;
|
||||
if (win == 0)
|
||||
tdata->td_maxend++;
|
||||
}
|
||||
|
||||
ATOMIC_INCL(ips_stats.iss_hits);
|
||||
/*
|
||||
* Nearing end of connection, start timeout.
|
||||
*/
|
||||
/* source ? 0 : 1 -> !source */
|
||||
fr_tcp_age(&is->is_age, is->is_state, fin, !source);
|
||||
ret = 1;
|
||||
if (fr_tcp_age(&is->is_age, is->is_state, fin, !source,
|
||||
(int)is->is_fsm) == 0) {
|
||||
if (ackskew < 0)
|
||||
tdata->td_end = ack;
|
||||
|
||||
/* update max window seen */
|
||||
if (fdata->td_maxwin < win)
|
||||
fdata->td_maxwin = win;
|
||||
if (SEQ_GT(end, fdata->td_end))
|
||||
fdata->td_end = end;
|
||||
if (SEQ_GE(ack + win, tdata->td_maxend)) {
|
||||
tdata->td_maxend = ack + win;
|
||||
if (win == 0)
|
||||
tdata->td_maxend++;
|
||||
}
|
||||
|
||||
ATOMIC_INCL(ips_stats.iss_hits);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
MUTEX_EXIT(&is->is_lock);
|
||||
if ((ret == 0) && (tcp->th_flags != TH_SYN))
|
||||
fin->fin_misc |= FM_BADSTATE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1079,9 +1150,9 @@ fr_info_t *fin;
|
||||
register ipstate_t *is, **isp;
|
||||
register u_short sport, dport;
|
||||
register u_char pr;
|
||||
u_short savelen, ohlen;
|
||||
union i6addr dst, src;
|
||||
struct icmp *ic;
|
||||
u_short savelen;
|
||||
icmphdr_t *icmp;
|
||||
fr_info_t ofin;
|
||||
int type, len;
|
||||
@ -1110,14 +1181,15 @@ fr_info_t *fin;
|
||||
return NULL;
|
||||
|
||||
oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
|
||||
if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2))
|
||||
ohlen = oip->ip_hl << 2;
|
||||
if (fin->fin_plen < ICMPERR_MAXPKTLEN + ohlen - sizeof(*oip))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Sanity checks.
|
||||
*/
|
||||
len = fin->fin_dlen - ICMPERR_ICMPHLEN;
|
||||
if ((len <= 0) || ((oip->ip_hl << 2) > len))
|
||||
if ((len <= 0) || (ohlen > len))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
@ -1157,7 +1229,7 @@ fr_info_t *fin;
|
||||
switch (oip->ip_p)
|
||||
{
|
||||
case IPPROTO_ICMP :
|
||||
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
|
||||
icmp = (icmphdr_t *)((char *)oip + ohlen);
|
||||
|
||||
/*
|
||||
* a ICMP error can only be generated as a result of an
|
||||
@ -1187,7 +1259,7 @@ fr_info_t *fin;
|
||||
savelen = oip->ip_len;
|
||||
oip->ip_len = len;
|
||||
ofin.fin_v = 4;
|
||||
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
|
||||
fr_makefrip(ohlen, oip, &ofin);
|
||||
oip->ip_len = savelen;
|
||||
ofin.fin_ifp = fin->fin_ifp;
|
||||
ofin.fin_out = !fin->fin_out;
|
||||
@ -1209,12 +1281,14 @@ fr_info_t *fin;
|
||||
|
||||
case IPPROTO_TCP :
|
||||
case IPPROTO_UDP :
|
||||
if (fin->fin_plen < ICMPERR_MAXPKTLEN)
|
||||
return NULL;
|
||||
break;
|
||||
default :
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
|
||||
tcp = (tcphdr_t *)((char *)oip + ohlen);
|
||||
dport = tcp->th_dport;
|
||||
sport = tcp->th_sport;
|
||||
|
||||
@ -1239,7 +1313,7 @@ fr_info_t *fin;
|
||||
savelen = oip->ip_len;
|
||||
oip->ip_len = len;
|
||||
ofin.fin_v = 4;
|
||||
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
|
||||
fr_makefrip(ohlen, oip, &ofin);
|
||||
oip->ip_len = savelen;
|
||||
ofin.fin_ifp = fin->fin_ifp;
|
||||
ofin.fin_out = !fin->fin_out;
|
||||
@ -1481,9 +1555,8 @@ retry_tcpudp:
|
||||
fr_matchsrcdst(is, src, dst, fin, tcp)) {
|
||||
rev = fin->fin_rev;
|
||||
if ((pr == IPPROTO_TCP)) {
|
||||
if (!fr_tcpstate(is, fin, ip, tcp)) {
|
||||
continue;
|
||||
}
|
||||
if (!fr_tcpstate(is, fin, ip, tcp))
|
||||
is = NULL;
|
||||
} else if ((pr == IPPROTO_UDP)) {
|
||||
if (is->is_frage[rev] != 0)
|
||||
is->is_age = is->is_frage[rev];
|
||||
@ -1504,6 +1577,7 @@ retry_tcpudp:
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RWLOCK_EXIT(&ipf_state);
|
||||
if (!tryagain && ips_wild) {
|
||||
hv -= dport;
|
||||
@ -1703,15 +1777,16 @@ void fr_timeoutstate()
|
||||
* dir == 1 : a packet from dest to source
|
||||
*
|
||||
*/
|
||||
void fr_tcp_age(age, state, fin, dir)
|
||||
int fr_tcp_age(age, state, fin, dir, fsm)
|
||||
u_long *age;
|
||||
u_char *state;
|
||||
fr_info_t *fin;
|
||||
int dir;
|
||||
int dir, fsm;
|
||||
{
|
||||
tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
|
||||
u_char flags = tcp->th_flags;
|
||||
int dlen, ostate;
|
||||
u_long newage;
|
||||
|
||||
ostate = state[1 - dir];
|
||||
|
||||
@ -1725,10 +1800,10 @@ int dir;
|
||||
*age = fr_tcpclosewait;
|
||||
state[dir] = TCPS_CLOSE_WAIT;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*age = fr_tcptimeout; /* default 4 mins */
|
||||
newage = 0;
|
||||
|
||||
switch(state[dir])
|
||||
{
|
||||
@ -1739,11 +1814,11 @@ int dir;
|
||||
* CLOSED -> SYN_RECEIVED
|
||||
*/
|
||||
state[dir] = TCPS_SYN_RECEIVED;
|
||||
*age = fr_tcptimeout;
|
||||
} else if ((flags & (TH_SYN|TH_ACK)) == TH_SYN) {
|
||||
newage = fr_tcptimeout;
|
||||
} else if ((flags & TH_OPENING) == TH_SYN) {
|
||||
/* 'dir' sent S, CLOSED -> SYN_SENT */
|
||||
state[dir] = TCPS_SYN_SENT;
|
||||
*age = fr_tcptimeout;
|
||||
newage = fr_tcptimeout;
|
||||
}
|
||||
/*
|
||||
* The next piece of code makes it possible to get
|
||||
@ -1752,12 +1827,12 @@ int dir;
|
||||
* does not work when a strict 'flags S keep state' is
|
||||
* used for tcp connections of course
|
||||
*/
|
||||
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
|
||||
if (!fsm && (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
|
||||
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
|
||||
if (state[1 - dir] == TCPS_CLOSED ||
|
||||
state[1 - dir] == TCPS_ESTABLISHED) {
|
||||
state[dir] = TCPS_ESTABLISHED;
|
||||
*age = fr_tcpidletimeout;
|
||||
newage = fr_tcpidletimeout;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -1772,14 +1847,24 @@ int dir;
|
||||
break;
|
||||
|
||||
case TCPS_SYN_SENT: /* 2 */
|
||||
if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
|
||||
if (flags == TH_SYN) {
|
||||
/*
|
||||
* A retransmitted SYN packet. We do not reset the
|
||||
* timeout here to fr_tcptimeout because a connection
|
||||
* connect timeout does not renew after every packet
|
||||
* that is sent. We need to set newage to something
|
||||
* to indicate the packet has passed the check for its
|
||||
* flags being valid in the TCP FSM.
|
||||
*/
|
||||
newage = *age;
|
||||
} else if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
|
||||
/*
|
||||
* We see an A from 'dir' which is in SYN_SENT
|
||||
* state: 'dir' sent an A in response to an SA
|
||||
* which it received, SYN_SENT -> ESTABLISHED
|
||||
*/
|
||||
state[dir] = TCPS_ESTABLISHED;
|
||||
*age = fr_tcpidletimeout;
|
||||
newage = fr_tcpidletimeout;
|
||||
} else if (flags & TH_FIN) {
|
||||
/*
|
||||
* We see an F from 'dir' which is in SYN_SENT
|
||||
@ -1787,7 +1872,7 @@ int dir;
|
||||
* connection; SYN_SENT -> FIN_WAIT_1
|
||||
*/
|
||||
state[dir] = TCPS_FIN_WAIT_1;
|
||||
*age = fr_tcpidletimeout; /* or fr_tcptimeout? */
|
||||
newage = fr_tcpidletimeout; /* or fr_tcptimeout? */
|
||||
} else if ((flags & TH_OPENING) == TH_OPENING) {
|
||||
/*
|
||||
* We see an SA from 'dir' which is already in
|
||||
@ -1795,7 +1880,7 @@ int dir;
|
||||
* simultaneous open; SYN_SENT -> SYN_RECEIVED
|
||||
*/
|
||||
state[dir] = TCPS_SYN_RECEIVED;
|
||||
*age = fr_tcptimeout;
|
||||
newage = fr_tcptimeout;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1807,7 +1892,7 @@ int dir;
|
||||
* SYN_RECEIVED -> ESTABLISHED
|
||||
*/
|
||||
state[dir] = TCPS_ESTABLISHED;
|
||||
*age = fr_tcpidletimeout;
|
||||
newage = fr_tcpidletimeout;
|
||||
} else if (flags & TH_FIN) {
|
||||
/*
|
||||
* We see an F from 'dir' which is in SYN_RECEIVED
|
||||
@ -1815,7 +1900,7 @@ int dir;
|
||||
* SYN_RECEIVED -> FIN_WAIT_1
|
||||
*/
|
||||
state[dir] = TCPS_FIN_WAIT_1;
|
||||
*age = fr_tcpidletimeout;
|
||||
newage = fr_tcpidletimeout;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1827,7 +1912,7 @@ int dir;
|
||||
* ESTABLISHED -> FIN_WAIT_1
|
||||
*/
|
||||
state[dir] = TCPS_FIN_WAIT_1;
|
||||
*age = fr_tcphalfclosed;
|
||||
newage = fr_tcphalfclosed;
|
||||
} else if (flags & TH_ACK) {
|
||||
/* an ACK, should we exclude other flags here? */
|
||||
if (ostate == TCPS_FIN_WAIT_1) {
|
||||
@ -1839,13 +1924,13 @@ int dir;
|
||||
* a half-closed connection
|
||||
*/
|
||||
state[dir] = TCPS_CLOSE_WAIT;
|
||||
*age = fr_tcphalfclosed;
|
||||
newage = fr_tcphalfclosed;
|
||||
} else if (ostate < TCPS_CLOSE_WAIT)
|
||||
/*
|
||||
* Still a fully established connection,
|
||||
* reset timeout
|
||||
*/
|
||||
*age = fr_tcpidletimeout;
|
||||
newage = fr_tcpidletimeout;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1855,7 +1940,7 @@ int dir;
|
||||
* Application closed and 'dir' sent a FIN, we're now
|
||||
* going into LAST_ACK state
|
||||
*/
|
||||
*age = fr_tcplastack;
|
||||
newage = fr_tcplastack;
|
||||
state[dir] = TCPS_LAST_ACK;
|
||||
} else {
|
||||
/*
|
||||
@ -1863,7 +1948,7 @@ int dir;
|
||||
* closed already and we did not close our side yet;
|
||||
* reset timeout
|
||||
*/
|
||||
*age = fr_tcphalfclosed;
|
||||
newage = fr_tcphalfclosed;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1880,14 +1965,14 @@ int dir;
|
||||
* packet here? does the window code guarantee that?
|
||||
*/
|
||||
state[dir] = TCPS_TIME_WAIT;
|
||||
*age = fr_tcptimeout;
|
||||
newage = fr_tcptimeout;
|
||||
} else
|
||||
/*
|
||||
* We closed our side of the connection already but the
|
||||
* other side is still active (ESTABLISHED/CLOSE_WAIT);
|
||||
* continue with this half-closed connection
|
||||
*/
|
||||
*age = fr_tcphalfclosed;
|
||||
newage = fr_tcphalfclosed;
|
||||
break;
|
||||
|
||||
case TCPS_CLOSING: /* 7 */
|
||||
@ -1901,7 +1986,7 @@ int dir;
|
||||
* There is still data to be delivered, reset
|
||||
* timeout
|
||||
*/
|
||||
*age = fr_tcplastack;
|
||||
newage = fr_tcplastack;
|
||||
}
|
||||
/*
|
||||
* We cannot detect when we go out of LAST_ACK state to CLOSED
|
||||
@ -1916,9 +2001,16 @@ int dir;
|
||||
break;
|
||||
|
||||
case TCPS_TIME_WAIT: /* 10 */
|
||||
newage = fr_tcptimeout; /* default 4 mins */
|
||||
/* we're in 2MSL timeout now */
|
||||
break;
|
||||
}
|
||||
|
||||
if (newage != 0) {
|
||||
*age = newage;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -2068,8 +2160,14 @@ fr_info_t *fin;
|
||||
hv = (pr = oip->ip6_nxt);
|
||||
src.in6 = oip->ip6_src;
|
||||
hv += src.in4.s_addr;
|
||||
hv += src.i6[1];
|
||||
hv += src.i6[2];
|
||||
hv += src.i6[3];
|
||||
dst.in6 = oip->ip6_dst;
|
||||
hv += dst.in4.s_addr;
|
||||
hv += dst.i6[1];
|
||||
hv += dst.i6[2];
|
||||
hv += dst.i6[3];
|
||||
hv += dport;
|
||||
hv += sport;
|
||||
hv %= fr_statesize;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
|
||||
* $Id: ip_state.h,v 2.13.2.10 2002/03/06 14:07:38 darrenr Exp $
|
||||
* $Id: ip_state.h,v 2.13.2.12 2002/03/25 11:14:55 darrenr Exp $
|
||||
*/
|
||||
#ifndef __IP_STATE_H__
|
||||
#define __IP_STATE_H__
|
||||
@ -42,7 +42,8 @@ typedef struct icmpstate {
|
||||
typedef struct tcpdata {
|
||||
u_32_t td_end;
|
||||
u_32_t td_maxend;
|
||||
u_short td_maxwin;
|
||||
u_32_t td_maxwin;
|
||||
u_char td_wscale;
|
||||
} tcpdata_t;
|
||||
|
||||
typedef struct tcpstate {
|
||||
@ -58,20 +59,22 @@ typedef struct ipstate {
|
||||
struct ipstate *is_hnext;
|
||||
struct ipstate **is_phnext;
|
||||
struct ipstate **is_me;
|
||||
frentry_t *is_rule;
|
||||
U_QUAD_T is_pkts;
|
||||
U_QUAD_T is_bytes;
|
||||
union i6addr is_src;
|
||||
union i6addr is_dst;
|
||||
void *is_ifp[4];
|
||||
u_long is_age;
|
||||
u_int is_frage[2]; /* age from filter rule, forward & reverse */
|
||||
u_int is_pass;
|
||||
U_QUAD_T is_pkts;
|
||||
U_QUAD_T is_bytes;
|
||||
void *is_ifp[4];
|
||||
frentry_t *is_rule;
|
||||
union i6addr is_src;
|
||||
union i6addr is_dst;
|
||||
u_char is_p; /* Protocol */
|
||||
u_char is_v;
|
||||
u_int is_hv;
|
||||
u_char is_v; /* IP version */
|
||||
u_char is_fsm; /* 1 = following FSM, 0 = not */
|
||||
u_char is_xxx; /* pad */
|
||||
u_int is_hv; /* hash value for this in the table */
|
||||
u_32_t is_rulen; /* rule number */
|
||||
u_32_t is_flags;
|
||||
u_32_t is_flags; /* flags for this structure */
|
||||
u_32_t is_opt; /* packet options set */
|
||||
u_32_t is_optmsk; /* " " mask */
|
||||
u_short is_sec; /* security options set */
|
||||
@ -100,6 +103,8 @@ typedef struct ipstate {
|
||||
#define is_dend is_tcp.ts_data[1].td_end
|
||||
#define is_maxswin is_tcp.ts_data[0].td_maxwin
|
||||
#define is_maxdwin is_tcp.ts_data[1].td_maxwin
|
||||
#define is_swscale is_tcp.ts_data[0].td_wscale
|
||||
#define is_dwscale is_tcp.ts_data[1].td_wscale
|
||||
#define is_maxsend is_tcp.ts_data[0].td_maxend
|
||||
#define is_maxdend is_tcp.ts_data[1].td_maxend
|
||||
#define is_sport is_tcp.ts_sport
|
||||
@ -191,7 +196,7 @@ extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, ipstate_t **, u_int));
|
||||
extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
|
||||
extern void ip_statesync __P((void *));
|
||||
extern void fr_timeoutstate __P((void));
|
||||
extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));
|
||||
extern int fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int, int));
|
||||
extern void fr_stateunload __P((void));
|
||||
extern void ipstate_log __P((struct ipstate *, u_int));
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
@ -4,12 +4,12 @@
|
||||
* See the IPFILTER.LICENCE file for details on licencing.
|
||||
*
|
||||
* @(#)ipl.h 1.21 6/5/96
|
||||
* $Id: ipl.h,v 2.15.2.31 2002/03/13 03:57:42 darrenr Exp $
|
||||
* $Id: ipl.h,v 2.15.2.32 2002/04/23 14:59:13 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IPL_H__
|
||||
#define __IPL_H__
|
||||
|
||||
#define IPL_VERSION "IP Filter: v3.4.25"
|
||||
#define IPL_VERSION "IP Filter: v3.4.26"
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user