mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-11 09:50:12 +00:00
Import version 3.2alpha7
This commit is contained in:
parent
1fddb84ad6
commit
e10102a12a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-sys/ipfilter/dist-old/; revision=26124 svn path=/vendor-sys/ipfilter/v3-2-a7/; revision=26126; tag=vendor/ipfilter-sys/v3-2-a7
@ -7,7 +7,7 @@
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
|
||||
static char rcsid[] = "$Id: fil.c,v 1.1.1.3 1997/04/03 10:10:10 darrenr Exp $";
|
||||
static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#include <sys/errno.h>
|
||||
@ -45,11 +45,12 @@ static char rcsid[] = "$Id: fil.c,v 1.1.1.3 1997/04/03 10:10:10 darrenr Exp $";
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "ip_compat.h"
|
||||
#include "ip_fil.h"
|
||||
#include "ip_nat.h"
|
||||
#include "ip_frag.h"
|
||||
#include "ip_state.h"
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_proxy.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_frag.h"
|
||||
#include "netinet/ip_state.h"
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
@ -70,7 +71,6 @@ extern int opts;
|
||||
# define IPLLOG(a, c, d, e) ipllog()
|
||||
# if SOLARIS
|
||||
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip)
|
||||
# define bcmp memcmp
|
||||
# else
|
||||
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(b, ip, if)
|
||||
# endif
|
||||
@ -100,19 +100,12 @@ extern kmutex_t ipf_mutex;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef IPF_LOGGING
|
||||
#define IPF_LOGGING 0
|
||||
#endif
|
||||
#ifdef IPF_DEFAULT_PASS
|
||||
#define IPF_NOMATCH (IPF_DEFAULT_PASS|FR_NOMATCH)
|
||||
#else
|
||||
#define IPF_NOMATCH (FR_PASS|FR_NOMATCH)
|
||||
#endif
|
||||
|
||||
struct filterstats frstats[2] = {{0,0,0,0,0},{0,0,0,0,0}};
|
||||
struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
|
||||
*ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } };
|
||||
int fr_flags = IPF_LOGGING, fr_active = 0;
|
||||
int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
|
||||
|
||||
fr_info_t frcache[2];
|
||||
|
||||
@ -417,7 +410,7 @@ void *m;
|
||||
#endif
|
||||
{
|
||||
register u_long *ld, *lm, *lip;
|
||||
register int i;
|
||||
register int i, j;
|
||||
|
||||
lip = (u_long *)fi;
|
||||
lm = (u_long *)&fr->fr_mip;
|
||||
@ -425,10 +418,10 @@ void *m;
|
||||
i = ((lip[0] & lm[0]) != ld[0]);
|
||||
FR_IFDEBUG(i,continue,("0. %#08x & %#08x != %#08x\n",
|
||||
lip[0], lm[0], ld[0]));
|
||||
i |= ((lip[1] & lm[1]) != ld[1]);
|
||||
i |= ((lip[1] & lm[1]) != ld[1]) << 21;
|
||||
FR_IFDEBUG(i,continue,("1. %#08x & %#08x != %#08x\n",
|
||||
lip[1], lm[1], ld[1]));
|
||||
i |= ((lip[2] & lm[2]) != ld[2]);
|
||||
i |= ((lip[2] & lm[2]) != ld[2]) << 22;
|
||||
FR_IFDEBUG(i,continue,("2. %#08x & %#08x != %#08x\n",
|
||||
lip[2], lm[2], ld[2]));
|
||||
i |= ((lip[3] & lm[3]) != ld[3]);
|
||||
@ -437,6 +430,7 @@ void *m;
|
||||
i |= ((lip[4] & lm[4]) != ld[4]);
|
||||
FR_IFDEBUG(i,continue,("4. %#08x & %#08x != %#08x\n",
|
||||
lip[4], lm[4], ld[4]));
|
||||
i ^= (fi->fi_fl & (FR_NOTSRCIP|FR_NOTDSTIP));
|
||||
if (i)
|
||||
continue;
|
||||
}
|
||||
@ -557,6 +551,7 @@ int out;
|
||||
fr_makefrip(hlen, ip, fin);
|
||||
fin->fin_ifp = ifp;
|
||||
fin->fin_out = out;
|
||||
fin->fin_mp = mp;
|
||||
|
||||
MUTEX_ENTER(&ipf_mutex);
|
||||
if (!out) {
|
||||
@ -566,24 +561,8 @@ int out;
|
||||
frstats[0].fr_acct++;
|
||||
}
|
||||
|
||||
if ((pass = ipfr_knownfrag(ip, fin))) {
|
||||
if ((pass & FR_KEEPSTATE)) {
|
||||
if (fr_addstate(ip, fin, pass) == -1)
|
||||
frstats[out].fr_bads++;
|
||||
else
|
||||
frstats[out].fr_ads++;
|
||||
}
|
||||
} else if ((pass = fr_checkstate(ip, fin))) {
|
||||
if ((pass & FR_KEEPFRAG)) {
|
||||
if (fin->fin_fi.fi_fl & FI_FRAG) {
|
||||
if (ipfr_newfrag(ip, fin, pass) == -1)
|
||||
frstats[out].fr_bnfr++;
|
||||
else
|
||||
frstats[out].fr_nfr++;
|
||||
} else
|
||||
frstats[out].fr_cfr++;
|
||||
}
|
||||
} else {
|
||||
if (!(pass = ipfr_knownfrag(ip, fin)) &&
|
||||
!(pass = fr_checkstate(ip, fin))) {
|
||||
fc = frcache + out;
|
||||
if (fc->fin_fr && !bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
|
||||
/*
|
||||
@ -594,16 +573,16 @@ int out;
|
||||
frstats[out].fr_chit++;
|
||||
pass = fin->fin_fr->fr_flags;
|
||||
} else {
|
||||
pass = IPF_NOMATCH;
|
||||
pass = fr_pass;
|
||||
if ((fin->fin_fr = ipfilter[out][fr_active]))
|
||||
pass = FR_SCANLIST(IPF_NOMATCH, ip, fin, m);
|
||||
pass = FR_SCANLIST(fr_pass, ip, fin, m);
|
||||
bcopy((char *)fin, (char *)fc, FI_CSIZE);
|
||||
if (pass & FR_NOMATCH)
|
||||
frstats[out].fr_nom++;
|
||||
}
|
||||
fr = fin->fin_fr;
|
||||
|
||||
if ((pass & FR_KEEPFRAG)) {
|
||||
if (pass & FR_KEEPFRAG) {
|
||||
if (fin->fin_fi.fi_fl & FI_FRAG) {
|
||||
if (ipfr_newfrag(ip, fin, pass) == -1)
|
||||
frstats[out].fr_bnfr++;
|
||||
@ -660,6 +639,19 @@ int out;
|
||||
}
|
||||
}
|
||||
#endif /* IPFILTER_LOG */
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Only allow FR_DUP to work if a rule matched - it makes no sense to
|
||||
* set FR_DUP as a "default" as there are no instructions about where
|
||||
* to send the packet.
|
||||
*/
|
||||
if (fr && (pass & FR_DUP))
|
||||
# if SOLARIS
|
||||
mc = dupmsg(m);
|
||||
# else
|
||||
mc = m_copy(m, 0, M_COPYALL);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (pass & FR_PASS)
|
||||
frstats[out].fr_pass++;
|
||||
@ -703,10 +695,16 @@ int out;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't drop off the bottom of the list of rules (and thus
|
||||
* the 'current' rule fr is not NULL), then we may have some extra
|
||||
* instructions about what to do with a packet.
|
||||
* Once we're finished return to our caller, freeing the packet if
|
||||
* we are dropping it (* BSD ONLY *).
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
# if !SOLARIS
|
||||
if (pass & FR_DUP)
|
||||
mc = m_copy(m, 0, M_COPYALL);
|
||||
if (fr) {
|
||||
frdest_t *fdp = &fr->fr_tif;
|
||||
|
||||
@ -722,8 +720,6 @@ int out;
|
||||
m_freem(m);
|
||||
return (pass & FR_PASS) ? 0 : -1;
|
||||
# else
|
||||
if (pass & FR_DUP)
|
||||
mc = dupmsg(m);
|
||||
if (fr) {
|
||||
frdest_t *fdp = &fr->fr_tif;
|
||||
|
||||
@ -777,3 +773,126 @@ int len;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
u_short ipf_cksum(addr, len)
|
||||
register u_short *addr;
|
||||
register int len;
|
||||
{
|
||||
register u_long sum = 0;
|
||||
|
||||
for (sum = 0; len > 1; len -= 2)
|
||||
sum += *addr++;
|
||||
|
||||
/* mop up an odd byte, if necessary */
|
||||
if (len == 1)
|
||||
sum += *(u_char *)addr;
|
||||
|
||||
/*
|
||||
* add back carry outs from top 16 bits to low 16 bits
|
||||
*/
|
||||
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
|
||||
sum += (sum >> 16); /* add carry */
|
||||
return (u_short)(~sum);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NB: This function assumes we've pullup'd enough for all of the IP header
|
||||
* and the TCP header. We also assume that data blocks aren't allocated in
|
||||
* odd sizes.
|
||||
*/
|
||||
u_short fr_tcpsum(m, ip, tcp)
|
||||
#if SOLARIS
|
||||
mblk_t *m;
|
||||
#else
|
||||
struct mbuf *m;
|
||||
#endif
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
{
|
||||
union {
|
||||
u_char c[2];
|
||||
u_short s;
|
||||
} bytes;
|
||||
u_long sum;
|
||||
u_short *sp;
|
||||
int len, add, hlen, ilen;
|
||||
|
||||
/*
|
||||
* Add up IP Header portion
|
||||
*/
|
||||
ilen = len = ip->ip_len - (ip->ip_hl << 2);
|
||||
bytes.c[0] = 0;
|
||||
bytes.c[1] = IPPROTO_TCP;
|
||||
sum = bytes.s;
|
||||
sum += htons((u_short)len);
|
||||
sp = (u_short *)&ip->ip_src;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
if (sp != (u_short *)tcp)
|
||||
sp = (u_short *)tcp;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp++;
|
||||
sum += *sp;
|
||||
sp += 2; /* Skip over checksum */
|
||||
sum += *sp++;
|
||||
|
||||
#if SOLARIS
|
||||
/*
|
||||
* In case we had to copy the IP & TCP header out of mblks,
|
||||
* skip over the mblk bits which are the header
|
||||
*/
|
||||
if ((caddr_t)ip != (caddr_t)m->b_rptr) {
|
||||
hlen = (caddr_t)sp - (caddr_t)ip;
|
||||
while (hlen) {
|
||||
add = MIN(hlen, m->b_wptr - m->b_rptr);
|
||||
sp = (u_short *)((caddr_t)m->b_rptr + add);
|
||||
if ((hlen -= add))
|
||||
m = m->b_cont;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(len -= sizeof(*tcp)))
|
||||
goto nodata;
|
||||
while (len > 1) {
|
||||
sum += *sp++;
|
||||
len -= 2;
|
||||
#if SOLARIS
|
||||
if ((caddr_t)sp > (caddr_t)m->b_wptr) {
|
||||
m = m->b_cont;
|
||||
PANIC((!m),("fr_tcpsum: not enough data"));
|
||||
sp = (u_short *)m->b_rptr;
|
||||
}
|
||||
#else
|
||||
# ifdef m_data
|
||||
if ((caddr_t)sp > (m->m_data + m->m_len))
|
||||
# else
|
||||
if ((caddr_t)sp > (caddr_t)(m->m_dat + m->m_off + m->m_len))
|
||||
# endif
|
||||
{
|
||||
m = m->m_next;
|
||||
PANIC((!m),("fr_tcpsum: not enough data"));
|
||||
sp = mtod(m, u_short *);
|
||||
}
|
||||
#endif /* SOLARIS */
|
||||
}
|
||||
if (len) {
|
||||
bytes.c[1] = 0;
|
||||
bytes.c[0] = *(u_char *)sp;
|
||||
sum += bytes.s;
|
||||
}
|
||||
nodata:
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
sum = (u_short)((~sum) & 0xffff);
|
||||
return sum;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
* (C)opyright 1993, 1994, 1995 by Darren Reed.
|
||||
* (C)opyright 1993-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ip_compat.h 1.8 1/14/96
|
||||
* $Id: ip_compat.h,v 1.1.1.2 1997/04/03 10:10:48 darrenr Exp $
|
||||
* $Id: ip_compat.h,v 2.0.2.11 1997/05/04 05:29:02 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_COMPAT_H_
|
||||
#ifndef __IP_COMPAT_H__
|
||||
#define __IP_COMPAT_H__
|
||||
|
||||
#ifndef __P
|
||||
@ -24,6 +24,22 @@
|
||||
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
|
||||
#endif
|
||||
|
||||
#if defined(_KERNEL) && !defined(KERNEL)
|
||||
#define KERNEL
|
||||
#endif
|
||||
#if defined(KERNEL) && !defined(_KERNEL)
|
||||
#define _KERNEL
|
||||
#endif
|
||||
|
||||
#if defined(__SVR4) || defined(__svr4__)
|
||||
#define index strchr
|
||||
# ifndef _KERNEL
|
||||
# define bzero(a,b) memset(a,0,b)
|
||||
# define bcmp memcmp
|
||||
# define bcopy(a,b,c) memmove(b,a,c)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if SOLARIS
|
||||
# define MTYPE(m) ((m)->b_datap->db_type)
|
||||
# include <sys/ioccom.h>
|
||||
@ -58,8 +74,10 @@
|
||||
#if BSD > 199306
|
||||
# define USE_QUAD_T
|
||||
# define U_QUAD_T u_quad_t
|
||||
# define QUAD_T quad_t
|
||||
#else
|
||||
# define U_QUAD_T u_long
|
||||
# define QUAD_T long
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
@ -167,6 +185,7 @@ extern ill_t *get_unit __P((char *));
|
||||
# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
|
||||
# define SLEEP(id, n) sleep((id), PZERO+1)
|
||||
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
|
||||
# define KFREES(x,s) kmem_free((char *)(x), (s))
|
||||
# if SOLARIS
|
||||
typedef struct qif {
|
||||
struct qif *qf_next;
|
||||
@ -219,13 +238,16 @@ extern vm_map_t kmem_map;
|
||||
# define KMALLOC(a,b,c) (a) = (b)kmem_alloc(kmem_map, (c))
|
||||
# define KFREE(x) kmem_free(kmem_map, (vm_offset_t)(x), \
|
||||
sizeof(*(x)))
|
||||
# define KFREES(x,s) kmem_free(kmem_map, (vm_offset_t)(x), (s))
|
||||
*/
|
||||
# ifdef M_PFIL
|
||||
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
|
||||
# define KFREE(x) FREE((x), M_PFIL)
|
||||
# define KFREES(x,s) FREE((x), M_PFIL)
|
||||
# else
|
||||
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
|
||||
# define KFREE(x) FREE((x), M_TEMP)
|
||||
# define KFREES(x,s) FREE((x), M_TEMP)
|
||||
# endif
|
||||
# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
|
||||
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
|
||||
@ -238,7 +260,9 @@ extern vm_map_t kmem_map;
|
||||
# define SPLX(x) (void) splx(x)
|
||||
# endif
|
||||
# endif
|
||||
# define PANIC(x,y) if (x) panic y
|
||||
#else
|
||||
# define PANIC(x,y) ;
|
||||
# define MUTEX_ENTER(x) ;
|
||||
# define MUTEX_EXIT(x) ;
|
||||
# define SPLNET(x) ;
|
||||
@ -246,6 +270,7 @@ extern vm_map_t kmem_map;
|
||||
# define SPLX(x) ;
|
||||
# define KMALLOC(a,b,c) (a) = (b)malloc(c)
|
||||
# define KFREE(x) free(x)
|
||||
# define KFREES(x,s) free(x)
|
||||
# define GETUNIT(x) get_unit(x)
|
||||
# define IRCOPY(a,b,c) bcopy((a), (b), (c))
|
||||
# define IWCOPY(a,b,c) bcopy((a), (b), (c))
|
||||
@ -365,6 +390,7 @@ struct ipovly {
|
||||
|
||||
# define KMALLOC(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
|
||||
# define KFREE(x) kfree_s((x), sizeof(*(x)))
|
||||
# define KFREES(x,s) kfree_s((x), (s))
|
||||
# define IRCOPY(a,b,c) { \
|
||||
error = verify_area(VERIFY_READ, \
|
||||
(b) ,sizeof((b))); \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C)opyright 1993,1994,1995 by Darren Reed.
|
||||
* (C)opyright 1993-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
@ -7,7 +7,7 @@
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
|
||||
static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $";
|
||||
static char rcsid[] = "$Id: ip_fil.c,v 2.0.2.12 1997/05/24 07:39:56 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#ifndef SOLARIS
|
||||
@ -15,7 +15,14 @@ static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <osreldate.h>
|
||||
# if defined(KERNEL) && !defined(_KERNEL)
|
||||
# define _KERNEL
|
||||
# endif
|
||||
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
|
||||
# include <sys/osreldate.h>
|
||||
# else
|
||||
# include <osreldate.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifndef _KERNEL
|
||||
#include <stdio.h>
|
||||
@ -25,7 +32,12 @@ static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if __FreeBSD_version >= 220000 && defined(_KERNEL)
|
||||
# include <sys/fcntl.h>
|
||||
# include <sys/filio.h>
|
||||
#else
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#ifdef _KERNEL
|
||||
#include <sys/systm.h>
|
||||
@ -35,9 +47,6 @@ static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $
|
||||
#include <sys/dir.h>
|
||||
#include <sys/mbuf.h>
|
||||
#else
|
||||
#define bcmp memcmp
|
||||
#define bzero(a,b) memset(a,0,b)
|
||||
#define bcopy(a,b,c) memcpy(b,a,c)
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#include <sys/protosw.h>
|
||||
@ -47,6 +56,9 @@ static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $
|
||||
#ifdef sun
|
||||
#include <net/af.h>
|
||||
#endif
|
||||
#if __FreeBSD_version >= 300000
|
||||
# include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
@ -57,17 +69,23 @@ static char rcsid[] = "$Id: ip_fil.c,v 1.1.1.3 1997/04/03 10:10:52 darrenr Exp $
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <syslog.h>
|
||||
#include "ip_compat.h"
|
||||
#include "ip_fil.h"
|
||||
#include "ip_frag.h"
|
||||
#include "ip_nat.h"
|
||||
#include "ip_state.h"
|
||||
#ifndef _KERNEL
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_proxy.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_frag.h"
|
||||
#include "netinet/ip_state.h"
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
#if !SOLARIS && defined(_KERNEL)
|
||||
extern int ip_optcopy __P((struct ip *, struct ip *));
|
||||
#endif
|
||||
|
||||
|
||||
extern fr_flags, fr_active;
|
||||
extern struct protosw inetsw[];
|
||||
#if BSD < 199306
|
||||
static int (*fr_saveslowtimo) __P((void));
|
||||
@ -139,6 +157,7 @@ char *s;
|
||||
|
||||
int iplattach()
|
||||
{
|
||||
char *defpass;
|
||||
int s, i;
|
||||
|
||||
SPLNET(s);
|
||||
@ -157,11 +176,21 @@ int iplattach()
|
||||
/*
|
||||
* Set log buffer pointers for each of the log buffers
|
||||
*/
|
||||
#ifdef IPFILTER_LOG
|
||||
for (i = 0; i <= 2; i++) {
|
||||
iplh[i] = iplbuf[i];
|
||||
iplt[i] = iplbuf[i];
|
||||
}
|
||||
#endif
|
||||
SPLX(s);
|
||||
if (fr_pass & FR_PASS)
|
||||
defpass = "pass";
|
||||
else if (fr_pass & FR_BLOCK)
|
||||
defpass = "block";
|
||||
else
|
||||
defpass = "no-match -> block";
|
||||
|
||||
printf("IP Filter: initialized. Default = %s all\n", defpass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -258,7 +287,8 @@ caddr_t data;
|
||||
* Filter ioctl interface.
|
||||
*/
|
||||
int iplioctl(dev, cmd, data, mode
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506)) && defined(_KERNEL)
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
|
||||
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
|
||||
, p)
|
||||
struct proc *p;
|
||||
#else
|
||||
@ -278,10 +308,21 @@ int mode;
|
||||
#endif
|
||||
|
||||
SPLNET(s);
|
||||
|
||||
if (unit == IPL_LOGNAT) {
|
||||
error = nat_ioctl(data, cmd, mode);
|
||||
SPLX(s);
|
||||
return error;
|
||||
}
|
||||
if (unit == IPL_LOGSTATE) {
|
||||
error = fr_state_ioctl(data, cmd, mode);
|
||||
SPLX(s);
|
||||
return error;
|
||||
}
|
||||
switch (cmd) {
|
||||
case FIONREAD :
|
||||
#ifdef IPFILTER_LOG
|
||||
*(int *)data = iplused[unit];
|
||||
*(int *)data = iplused[IPL_LOGIPF];
|
||||
#endif
|
||||
break;
|
||||
#if !defined(IPFILTER_LKM) && defined(_KERNEL)
|
||||
@ -373,24 +414,13 @@ int mode;
|
||||
else {
|
||||
*(int *)data = iplused[unit];
|
||||
iplh[unit] = iplt[unit] = iplbuf[unit];
|
||||
iplused[unit] = 0;
|
||||
iplused[unix] = 0;
|
||||
}
|
||||
break;
|
||||
#endif /* IPFILTER_LOG */
|
||||
case SIOCADNAT :
|
||||
case SIOCRMNAT :
|
||||
case SIOCGNATS :
|
||||
case SIOCGNATL :
|
||||
case SIOCFLNAT :
|
||||
case SIOCCNATL :
|
||||
error = nat_ioctl(data, cmd, mode);
|
||||
break;
|
||||
case SIOCGFRST :
|
||||
IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
|
||||
break;
|
||||
case SIOCGIPST :
|
||||
IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t));
|
||||
break;
|
||||
default :
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -508,7 +538,8 @@ caddr_t data;
|
||||
* routines below for saving IP headers to buffer
|
||||
*/
|
||||
int iplopen(dev, flags
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506)) && defined(_KERNEL)
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
|
||||
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
|
||||
, devtype, p)
|
||||
int devtype;
|
||||
struct proc *p;
|
||||
@ -529,7 +560,8 @@ int flags;
|
||||
|
||||
|
||||
int iplclose(dev, flags
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506)) && defined(_KERNEL)
|
||||
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
|
||||
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
|
||||
, devtype, p)
|
||||
int devtype;
|
||||
struct proc *p;
|
||||
@ -699,6 +731,9 @@ struct tcpiphdr *ti;
|
||||
struct tcphdr *tcp;
|
||||
struct mbuf *m;
|
||||
int tlen = 0;
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
|
||||
struct route ro;
|
||||
#endif
|
||||
|
||||
if (ti->ti_flags & TH_RST)
|
||||
return -1; /* feedback loop */
|
||||
@ -710,6 +745,8 @@ struct tcpiphdr *ti;
|
||||
# endif
|
||||
if (m == NULL)
|
||||
return -1;
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
|
||||
#endif
|
||||
|
||||
if (ti->ti_flags & TH_SYN)
|
||||
tlen = 1;
|
||||
@ -743,18 +780,29 @@ struct tcpiphdr *ti;
|
||||
ip->ip_ttl = ip_defttl;
|
||||
# endif
|
||||
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
|
||||
bzero((char *)&ro, sizeof(ro));
|
||||
(void) ip_output(m, (struct mbuf *)0, &ro, 0, 0);
|
||||
if (ro.ro_rt)
|
||||
RTFREE(ro.ro_rt);
|
||||
#else
|
||||
/*
|
||||
* extra 0 in case of multicast
|
||||
*/
|
||||
(void) ip_output(m, (struct mbuf *)0, 0, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
# ifndef IPFILTER_LKM
|
||||
# if !defined(IPFILTER_LKM) && !(__FreeBSD_version >= 300000)
|
||||
# if BSD < 199306
|
||||
int iplinit __P((void));
|
||||
|
||||
int
|
||||
# else
|
||||
void iplinit __P((void));
|
||||
|
||||
void
|
||||
# endif
|
||||
iplinit()
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* (C)opyright 1993-1996 by Darren Reed.
|
||||
* (C)opyright 1993-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ip_fil.h 1.35 6/5/96
|
||||
* $Id: ip_fil.h,v 1.1.1.2 1997/04/03 10:10:58 darrenr Exp $
|
||||
* $Id: ip_fil.h,v 2.0.2.13 1997/05/24 07:41:55 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_FIL_H__
|
||||
@ -97,6 +97,7 @@ typedef struct fr_info {
|
||||
u_short fin_dlen;
|
||||
char *fin_dp; /* start of data past IP header */
|
||||
struct frentry *fin_fr;
|
||||
void *fin_mp;
|
||||
} fr_info_t;
|
||||
|
||||
#define FI_CSIZE (sizeof(struct fr_ip) + 11)
|
||||
@ -179,16 +180,18 @@ typedef struct frentry {
|
||||
#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
|
||||
#define FR_DUP 0x20000 /* duplicate packet */
|
||||
#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
|
||||
#define FR_NOTSRCIP 0x80000 /* not the src IP# */
|
||||
#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
|
||||
|
||||
#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
|
||||
/*
|
||||
* recognized flags for SIOCGETFF and SIOCSETFF
|
||||
*/
|
||||
#define FF_LOGPASS 0x100000
|
||||
#define FF_LOGBLOCK 0x200000
|
||||
#define FF_LOGNOMATCH 0x400000
|
||||
#define FF_LOGPASS 0x10000000
|
||||
#define FF_LOGBLOCK 0x20000000
|
||||
#define FF_LOGNOMATCH 0x40000000
|
||||
#define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH)
|
||||
#define FF_BLOCKNONIP 0x800000 /* Solaris2 Only */
|
||||
#define FF_BLOCKNONIP 0x80000000 /* Solaris2 Only */
|
||||
|
||||
#define FR_NONE 0
|
||||
#define FR_EQUAL 1
|
||||
@ -257,9 +260,9 @@ typedef struct ipl_ci {
|
||||
u_long flags;
|
||||
u_char ifname[IFNAMSIZ]; /* = 32 bytes */
|
||||
#else
|
||||
u_long flags:24;
|
||||
u_long unit:8;
|
||||
u_char ifname[4]; /* = 20 bytes */
|
||||
u_long flags;
|
||||
u_int unit;
|
||||
u_char ifname[4]; /* = 24 bytes */
|
||||
#endif
|
||||
} ipl_ci_t;
|
||||
|
||||
@ -268,6 +271,13 @@ typedef struct ipl_ci {
|
||||
#define ICMP_UNREACH_FILTER 13
|
||||
#endif
|
||||
|
||||
#ifndef IPF_LOGGING
|
||||
#define IPF_LOGGING 0
|
||||
#endif
|
||||
#ifndef IPF_DEFAULT_PASS
|
||||
#define IPF_DEFAULT_PASS 0
|
||||
#endif
|
||||
|
||||
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
|
||||
#define IPLLOGSIZE 8192
|
||||
|
||||
@ -301,7 +311,12 @@ extern int send_reset __P((struct ip *, struct ifnet *));
|
||||
extern int icmp_error __P((struct ip *, struct ifnet *));
|
||||
extern void ipllog __P((void));
|
||||
extern void ipfr_fastroute __P((struct ip *, fr_info_t *, frdest_t *));
|
||||
#else
|
||||
extern int iplioctl __P((dev_t, int, caddr_t, int));
|
||||
extern int iplopen __P((dev_t, int));
|
||||
extern int iplclose __P((dev_t, int));
|
||||
#else /* #ifndef _KERNEL */
|
||||
extern int iplattach __P((void));
|
||||
extern int ipldetach __P((void));
|
||||
# if SOLARIS
|
||||
extern int fr_check __P((struct ip *, int, struct ifnet *, int, qif_t *,
|
||||
queue_t *, mblk_t **));
|
||||
@ -309,33 +324,6 @@ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *,
|
||||
int, qif_t *, queue_t *, mblk_t *));
|
||||
extern int icmp_error __P((queue_t *, ip_t *, int, int, qif_t *,
|
||||
struct in_addr));
|
||||
# else
|
||||
extern int fr_check __P((struct ip *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
extern int send_reset __P((struct tcpiphdr *));
|
||||
extern int ipllog __P((u_int, int, struct ip *, fr_info_t *, struct mbuf *));
|
||||
extern void ipfr_fastroute __P((struct mbuf *, fr_info_t *, frdest_t *));
|
||||
# endif
|
||||
#endif
|
||||
extern int fr_copytolog __P((int, char *, int));
|
||||
extern int ipl_unreach;
|
||||
extern fr_info_t frcache[];
|
||||
extern char *iplh[3], *iplt[3];
|
||||
extern char iplbuf[3][IPLLOGSIZE];
|
||||
extern int iplused[3];
|
||||
extern struct frentry *ipfilter[2][2], *ipacct[2][2];
|
||||
extern struct filterstats frstats[];
|
||||
|
||||
#ifndef _KERNEL
|
||||
extern int iplioctl __P((dev_t, int, caddr_t, int));
|
||||
extern int iplopen __P((dev_t, int));
|
||||
extern int iplclose __P((dev_t, int));
|
||||
#else
|
||||
extern int iplattach __P((void));
|
||||
extern int ipldetach __P((void));
|
||||
# if SOLARIS
|
||||
extern int iplioctl __P((dev_t, int, int, int, cred_t *, int *));
|
||||
extern int iplopen __P((dev_t *, int, int, cred_t *));
|
||||
extern int iplclose __P((dev_t, int, int, cred_t *));
|
||||
@ -343,11 +331,21 @@ extern int ipfsync __P((void));
|
||||
# ifdef IPFILTER_LOG
|
||||
extern int iplread __P((dev_t, struct uio *, cred_t *));
|
||||
# endif
|
||||
# else
|
||||
extern u_short fr_tcpsum __P((mblk_t *, ip_t *, tcphdr_t *));
|
||||
# else /* SOLARIS */
|
||||
extern int fr_check __P((struct ip *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
extern int send_reset __P((struct tcpiphdr *));
|
||||
extern int ipllog __P((u_int, int, struct ip *, fr_info_t *, struct mbuf *));
|
||||
extern void ipfr_fastroute __P((struct mbuf *, fr_info_t *, frdest_t *));
|
||||
# ifdef IPFILTER_LKM
|
||||
extern int iplidentify __P((char *));
|
||||
# endif
|
||||
# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 199612)
|
||||
extern u_short fr_tcpsum __P((struct mbuf *, ip_t *, tcphdr_t *));
|
||||
# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
|
||||
(NetBSD >= 199511)
|
||||
extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
|
||||
extern int iplopen __P((dev_t, int, int, struct proc *));
|
||||
extern int iplclose __P((dev_t, int, int, struct proc *));
|
||||
@ -366,5 +364,18 @@ extern int iplread __P((dev_t, struct uio *));
|
||||
# define iplread noread
|
||||
# endif /* IPFILTER_LOG */
|
||||
# endif /* SOLARIS */
|
||||
#endif /* _KERNEL */
|
||||
#endif /* #ifndef _KERNEL */
|
||||
extern u_short ipf_cksum __P((u_short *, int));
|
||||
extern int fr_copytolog __P((int, char *, int));
|
||||
extern int ipl_unreach;
|
||||
extern int ipl_inited;
|
||||
extern int fr_pass;
|
||||
extern int fr_flags;
|
||||
extern int fr_active;
|
||||
extern fr_info_t frcache[];
|
||||
extern char *iplh[3], *iplt[3];
|
||||
extern char iplbuf[3][IPLLOGSIZE];
|
||||
extern int iplused[3];
|
||||
extern struct frentry *ipfilter[2][2], *ipacct[2][2];
|
||||
extern struct filterstats frstats[];
|
||||
#endif /* __IP_FIL_H__ */
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
|
||||
static char rcsid[] = "$Id: ip_frag.c,v 1.1.1.3 1997/04/03 10:11:03 darrenr Exp $";
|
||||
static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#if !defined(_KERNEL) && !defined(KERNEL)
|
||||
@ -19,8 +19,7 @@ static char rcsid[] = "$Id: ip_frag.c,v 1.1.1.3 1997/04/03 10:11:03 darrenr Exp
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#if defined(__FreeBSD__) && (__FreeBSD__ >= 3)
|
||||
#include <sys/ioccom.h>
|
||||
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
|
||||
#include <sys/filio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#else
|
||||
@ -54,39 +53,36 @@ static char rcsid[] = "$Id: ip_frag.c,v 1.1.1.3 1997/04/03 10:11:03 darrenr Exp
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "ip_compat.h"
|
||||
#include "ip_fil.h"
|
||||
#include "ip_frag.h"
|
||||
#include "ip_nat.h"
|
||||
#include "ip_state.h"
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_proxy.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_frag.h"
|
||||
#include "netinet/ip_state.h"
|
||||
|
||||
ipfr_t *ipfr_heads[IPFT_SIZE];
|
||||
ipfr_t *ipfr_nattab[IPFT_SIZE];
|
||||
ipfrstat_t ipfr_stats;
|
||||
u_long ipfr_inuse = 0,
|
||||
fr_ipfrttl = 120; /* 60 seconds */
|
||||
#ifdef _KERNEL
|
||||
extern int ipfr_timer_id;
|
||||
#endif
|
||||
#if SOLARIS
|
||||
# ifdef _KERNEL
|
||||
#if SOLARIS && defined(_KERNEL)
|
||||
extern kmutex_t ipf_frag;
|
||||
# else
|
||||
#define bcmp(a,b,c) memcmp(a,b,c)
|
||||
#define bcopy(a,b,c) memmove(b,a,c)
|
||||
# endif
|
||||
extern kmutex_t ipf_natfrag;
|
||||
extern kmutex_t ipf_nat;
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# if BSD < 199306
|
||||
int ipfr_slowtimer __P((void));
|
||||
# else
|
||||
void ipfr_slowtimer __P((void));
|
||||
# endif
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, int, ipfr_t **));
|
||||
static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, ipfr_t **));
|
||||
|
||||
|
||||
ipfrstat_t *ipfr_fragstats()
|
||||
{
|
||||
ipfr_stats.ifs_table = ipfr_heads;
|
||||
ipfr_stats.ifs_nattab = ipfr_nattab;
|
||||
ipfr_stats.ifs_inuse = ipfr_inuse;
|
||||
return &ipfr_stats;
|
||||
}
|
||||
@ -96,10 +92,11 @@ ipfrstat_t *ipfr_fragstats()
|
||||
* add a new entry to the fragment cache, registering it as having come
|
||||
* through this box, with the result of the filter operation.
|
||||
*/
|
||||
int ipfr_newfrag(ip, fin, pass)
|
||||
static ipfr_t *ipfr_new(ip, fin, pass, table)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
int pass;
|
||||
ipfr_t *table[];
|
||||
{
|
||||
ipfr_t **fp, *fr, frag;
|
||||
u_int idx;
|
||||
@ -119,33 +116,77 @@ int pass;
|
||||
/*
|
||||
* first, make sure it isn't already there...
|
||||
*/
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
for (fp = &ipfr_heads[idx]; (fr = *fp); fp = &fr->ipfr_next)
|
||||
for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next)
|
||||
if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src,
|
||||
IPFR_CMPSZ)) {
|
||||
ipfr_stats.ifs_exists++;
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate some memory, if possible, if not, just record that we
|
||||
* failed to do so.
|
||||
*/
|
||||
KMALLOC(fr, ipfr_t *, sizeof(*fr));
|
||||
if (fr == NULL) {
|
||||
ipfr_stats.ifs_nomem++;
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
if ((fr->ipfr_next = ipfr_heads[idx]))
|
||||
ipfr_heads[idx]->ipfr_prev = fr;
|
||||
|
||||
/*
|
||||
* Instert the fragment into the fragment table, copy the struct used
|
||||
* in the search using bcopy rather than reassign each field.
|
||||
* Set the ttl to the default and mask out logging from "pass"
|
||||
*/
|
||||
if ((fr->ipfr_next = table[idx]))
|
||||
table[idx]->ipfr_prev = fr;
|
||||
fr->ipfr_prev = NULL;
|
||||
ipfr_heads[idx] = fr;
|
||||
fr->ipfr_data = NULL;
|
||||
table[idx] = fr;
|
||||
bcopy((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ);
|
||||
fr->ipfr_ttl = fr_ipfrttl;
|
||||
fr->ipfr_pass = pass & ~(FR_LOGFIRST|FR_LOG);
|
||||
/*
|
||||
* Compute the offset of the expected start of the next packet.
|
||||
*/
|
||||
fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3);
|
||||
ipfr_stats.ifs_new++;
|
||||
ipfr_inuse++;
|
||||
return fr;
|
||||
}
|
||||
|
||||
|
||||
int ipfr_newfrag(ip, fin, pass)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
int pass;
|
||||
{
|
||||
ipfr_t *ipf;
|
||||
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
return 0;
|
||||
return ipf ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
int ipfr_nat_newfrag(ip, fin, pass, nat)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
int pass;
|
||||
nat_t *nat;
|
||||
{
|
||||
ipfr_t *ipf;
|
||||
|
||||
MUTEX_ENTER(&ipf_natfrag);
|
||||
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
|
||||
ipf->ipfr_data = nat;
|
||||
nat->nat_frag = ipf;
|
||||
}
|
||||
MUTEX_EXIT(&ipf_natfrag);
|
||||
return ipf ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
@ -153,9 +194,10 @@ int pass;
|
||||
* check the fragment cache to see if there is already a record of this packet
|
||||
* with its filter result known.
|
||||
*/
|
||||
int ipfr_knownfrag(ip, fin)
|
||||
static ipfr_t *ipfr_lookup(ip, fin, table)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
ipfr_t *table[];
|
||||
{
|
||||
ipfr_t *f, frag;
|
||||
u_int idx;
|
||||
@ -164,6 +206,8 @@ fr_info_t *fin;
|
||||
/*
|
||||
* For fragments, we record protocol, packet id, TOS and both IP#'s
|
||||
* (these should all be the same for all fragments of a packet).
|
||||
*
|
||||
* build up a hash value to index the table with.
|
||||
*/
|
||||
frag.ipfr_p = ip->ip_p;
|
||||
idx = ip->ip_p;
|
||||
@ -177,25 +221,26 @@ fr_info_t *fin;
|
||||
idx *= 127;
|
||||
idx %= IPFT_SIZE;
|
||||
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
for (f = ipfr_heads[idx]; f; f = f->ipfr_next)
|
||||
/*
|
||||
* check the table, careful to only compare the right amount of data
|
||||
*/
|
||||
for (f = table[idx]; f; f = f->ipfr_next)
|
||||
if (!bcmp((char *)&frag.ipfr_src, (char *)&f->ipfr_src,
|
||||
IPFR_CMPSZ)) {
|
||||
u_short atoff, off;
|
||||
|
||||
if (f != ipfr_heads[idx]) {
|
||||
if (f != table[idx]) {
|
||||
/*
|
||||
* move fragment info. to the top of the list
|
||||
* to speed up searches.
|
||||
*/
|
||||
if ((f->ipfr_prev->ipfr_next = f->ipfr_next))
|
||||
f->ipfr_next->ipfr_prev = f->ipfr_prev;
|
||||
f->ipfr_next = ipfr_heads[idx];
|
||||
ipfr_heads[idx]->ipfr_prev = f;
|
||||
f->ipfr_next = table[idx];
|
||||
table[idx]->ipfr_prev = f;
|
||||
f->ipfr_prev = NULL;
|
||||
ipfr_heads[idx] = f;
|
||||
table[idx] = f;
|
||||
}
|
||||
ret = f->ipfr_pass;
|
||||
off = ip->ip_off;
|
||||
atoff = (off & 0x1fff) - (fin->fin_dlen >> 3);
|
||||
/*
|
||||
@ -209,11 +254,45 @@ fr_info_t *fin;
|
||||
f->ipfr_off = off;
|
||||
}
|
||||
ipfr_stats.ifs_hits++;
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
return ret;
|
||||
return f;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* functional interface for normal lookups of the fragment cache
|
||||
*/
|
||||
nat_t *ipfr_nat_knownfrag(ip, fin)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
{
|
||||
nat_t *nat;
|
||||
ipfr_t *ipf;
|
||||
|
||||
MUTEX_ENTER(&ipf_natfrag);
|
||||
ipf = ipfr_lookup(ip, fin, ipfr_heads);
|
||||
nat = ipf ? ipf->ipfr_data : NULL;
|
||||
MUTEX_EXIT(&ipf_natfrag);
|
||||
return nat;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* functional interface for NAT lookups of the NAT fragment cache
|
||||
*/
|
||||
int ipfr_knownfrag(ip, fin)
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
{
|
||||
int ret;
|
||||
ipfr_t *ipf;
|
||||
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
ipf = ipfr_lookup(ip, fin, ipfr_heads);
|
||||
ret = ipf ? ipf->ipfr_pass : 0;
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -223,20 +302,35 @@ fr_info_t *fin;
|
||||
void ipfr_unload()
|
||||
{
|
||||
ipfr_t **fp, *fr;
|
||||
nat_t *nat;
|
||||
int idx;
|
||||
#if !SOLARIS && defined(_KERNEL)
|
||||
int s;
|
||||
#endif
|
||||
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
SPLNET(s);
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
|
||||
*fp = fr->ipfr_next;
|
||||
KFREE(fr);
|
||||
}
|
||||
SPLX(s);
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
|
||||
MUTEX_ENTER(&ipf_nat);
|
||||
MUTEX_ENTER(&ipf_natfrag);
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
|
||||
*fp = fr->ipfr_next;
|
||||
if ((nat = (nat_t *)fr->ipfr_data)) {
|
||||
if (nat->nat_frag == fr)
|
||||
nat->nat_frag = NULL;
|
||||
}
|
||||
KFREE(fr);
|
||||
}
|
||||
MUTEX_EXIT(&ipf_natfrag);
|
||||
MUTEX_EXIT(&ipf_nat);
|
||||
SPLX(s);
|
||||
}
|
||||
|
||||
|
||||
@ -252,11 +346,17 @@ int ipfr_slowtimer()
|
||||
# endif
|
||||
{
|
||||
ipfr_t **fp, *fr;
|
||||
nat_t *nat;
|
||||
int s, idx;
|
||||
|
||||
MUTEX_ENTER(&ipf_frag);
|
||||
SPLNET(s);
|
||||
|
||||
/*
|
||||
* Go through the entire table, looking for entries to expire,
|
||||
* decreasing the ttl by one for each entry. If it reaches 0,
|
||||
* remove it from the chain and free it.
|
||||
*/
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
|
||||
--fr->ipfr_ttl;
|
||||
@ -274,12 +374,45 @@ int ipfr_slowtimer()
|
||||
} else
|
||||
fp = &fr->ipfr_next;
|
||||
}
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
|
||||
/*
|
||||
* Same again for the NAT table, except that if the structure also
|
||||
* still points to a NAT structure, and the NAT structure points back
|
||||
* at the one to be free'd, NULL the reference from the NAT struct.
|
||||
* NOTE: We need to grab both mutex's early, and in this order so as
|
||||
* to prevent a deadlock if both try to expire at the same time.
|
||||
*/
|
||||
MUTEX_ENTER(&ipf_nat);
|
||||
MUTEX_ENTER(&ipf_natfrag);
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
|
||||
--fr->ipfr_ttl;
|
||||
if (fr->ipfr_ttl == 0) {
|
||||
if (fr->ipfr_prev)
|
||||
fr->ipfr_prev->ipfr_next =
|
||||
fr->ipfr_next;
|
||||
if (fr->ipfr_next)
|
||||
fr->ipfr_next->ipfr_prev =
|
||||
fr->ipfr_prev;
|
||||
*fp = fr->ipfr_next;
|
||||
ipfr_stats.ifs_expire++;
|
||||
ipfr_inuse--;
|
||||
if ((nat = (nat_t *)fr->ipfr_data)) {
|
||||
if (nat->nat_frag == fr)
|
||||
nat->nat_frag = NULL;
|
||||
}
|
||||
KFREE(fr);
|
||||
} else
|
||||
fp = &fr->ipfr_next;
|
||||
}
|
||||
MUTEX_EXIT(&ipf_natfrag);
|
||||
MUTEX_EXIT(&ipf_nat);
|
||||
SPLX(s);
|
||||
# if SOLARIS
|
||||
MUTEX_EXIT(&ipf_frag);
|
||||
fr_timeoutstate();
|
||||
ip_natexpire();
|
||||
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, HZ/2);
|
||||
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
|
||||
# else
|
||||
fr_timeoutstate();
|
||||
ip_natexpire();
|
||||
|
@ -1,21 +1,22 @@
|
||||
/*
|
||||
* (C)opyright 1993, 1994, 1995 by Darren Reed.
|
||||
* (C)opyright 1993-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ip_frag.h 1.5 3/24/96
|
||||
* $Id: ip_frag.h,v 1.1.1.2 1997/04/03 10:11:06 darrenr Exp $
|
||||
* $Id: ip_frag.h,v 2.0.2.7 1997/05/08 10:10:18 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_FRAG_H_
|
||||
#ifndef __IP_FRAG_H__
|
||||
#define __IP_FRAG_H__
|
||||
|
||||
#define IPFT_SIZE 257
|
||||
|
||||
typedef struct ipfr {
|
||||
struct ipfr *ipfr_next, *ipfr_prev;
|
||||
void *ipfr_data;
|
||||
struct in_addr ipfr_src;
|
||||
struct in_addr ipfr_dst;
|
||||
u_short ipfr_id;
|
||||
@ -35,14 +36,18 @@ typedef struct ipfrstat {
|
||||
u_long ifs_expire;
|
||||
u_long ifs_inuse;
|
||||
struct ipfr **ifs_table;
|
||||
struct ipfr **ifs_nattab;
|
||||
} ipfrstat_t;
|
||||
|
||||
#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
|
||||
|
||||
extern ipfrstat_t *ipfr_fragstats __P((void));
|
||||
extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int));
|
||||
extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *));
|
||||
extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
|
||||
extern int ipfr_knownfrag __P((ip_t *, fr_info_t *));
|
||||
extern void ipfr_unload __P((void));
|
||||
|
||||
#if (BSD >= 199306) || SOLARIS
|
||||
extern void ipfr_slowtimer __P((void));
|
||||
#else
|
||||
|
204
sys/netinet/ip_ftp_pxy.c
Normal file
204
sys/netinet/ip_ftp_pxy.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Simple FTP transparent proxy for in-kernel.
|
||||
*/
|
||||
|
||||
#define isdigit(x) ((x) >= '0' && (x) <= '9')
|
||||
|
||||
#define IPF_FTP_PROXY
|
||||
|
||||
#define IPF_MINPORTLEN 18
|
||||
#define IPF_MAXPORTLEN 30
|
||||
|
||||
|
||||
int ippr_ftp_init(fin, ip, tcp, aps, nat)
|
||||
fr_info_t *fin;
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
ap_session_t *aps;
|
||||
nat_t *nat;
|
||||
{
|
||||
aps->aps_sport = tcp->th_sport;
|
||||
aps->aps_dport = tcp->th_dport;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ippr_ftp_in(fin, ip, tcp, aps, nat)
|
||||
fr_info_t *fin;
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
ap_session_t *aps;
|
||||
nat_t *nat;
|
||||
{
|
||||
int ch = 0;
|
||||
u_long sum1, sum2;
|
||||
|
||||
if (tcp->th_dport != aps->aps_dport) {
|
||||
sum2 = (u_long)ntohl(tcp->th_ack);
|
||||
if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
|
||||
sum1 = (u_long)aps->aps_seqoff;
|
||||
tcp->th_ack = htonl(sum2 - sum1);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u_short ipf_ftp_atoi(ptr)
|
||||
char **ptr;
|
||||
{
|
||||
register char *s = *ptr, c;
|
||||
register u_char i = 0, j = 0;
|
||||
|
||||
while ((c = *s++) && isdigit(c)) {
|
||||
i *= 10;
|
||||
i += c - '0';
|
||||
}
|
||||
if (c != ',') {
|
||||
*ptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
while ((c = *s++) && isdigit(c)) {
|
||||
j *= 10;
|
||||
j += c - '0';
|
||||
}
|
||||
*ptr = s;
|
||||
return (i << 8) | j;
|
||||
}
|
||||
|
||||
|
||||
int ippr_ftp_out(fin, ip, tcp, aps, nat)
|
||||
fr_info_t *fin;
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
ap_session_t *aps;
|
||||
nat_t *nat;
|
||||
{
|
||||
register u_long sum1, sum2, sumd;
|
||||
char newbuf[IPF_MAXPORTLEN+1];
|
||||
char portbuf[IPF_MAXPORTLEN+1], *s, c;
|
||||
int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2), len;
|
||||
u_int a1, a2, a3, a4;
|
||||
u_short a5, a6;
|
||||
int olen, dlen, nlen, inc = 0, blen;
|
||||
tcphdr_t tcph, *tcp2 = &tcph;
|
||||
void *savep;
|
||||
nat_t *ipn;
|
||||
struct in_addr swip;
|
||||
#if SOLARIS
|
||||
mblk_t *m1, *m = *(mblk_t **)fin->fin_mp;
|
||||
|
||||
dlen = m->b_wptr - m->b_rptr - off;
|
||||
blen = m->b_datap->db_lim - m->b_datap->db_base;
|
||||
bzero(portbuf, sizeof(portbuf));
|
||||
copyout_mblk(m, off, portbuf, MIN(sizeof(portbuf), dlen));
|
||||
#else
|
||||
struct mbuf *m1, *m = *(struct mbuf **)fin->fin_mp;
|
||||
|
||||
dlen = m->m_len - off;
|
||||
# if BSD >= 199306
|
||||
blen = (MLEN - m->m_len) - (m->m_data - m->m_dat);
|
||||
# else
|
||||
blen = (MLEN - m->m_len) - m->m_off;
|
||||
# endif
|
||||
if (blen < 0)
|
||||
panic("blen < 0 - size of mblk/mbuf wrong");
|
||||
bzero(portbuf, sizeof(portbuf));
|
||||
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
|
||||
#endif
|
||||
portbuf[IPF_MAXPORTLEN] = '\0';
|
||||
len = MIN(32, dlen);
|
||||
|
||||
if ((len < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
|
||||
goto adjust_seqack;
|
||||
|
||||
/*
|
||||
* Skip the PORT command + space
|
||||
*/
|
||||
s = portbuf + 5;
|
||||
/*
|
||||
* Pick out the address components, two at a time.
|
||||
*/
|
||||
(void) ipf_ftp_atoi(&s);
|
||||
if (!s)
|
||||
goto adjust_seqack;
|
||||
(void) ipf_ftp_atoi(&s);
|
||||
if (!s)
|
||||
goto adjust_seqack;
|
||||
a5 = ipf_ftp_atoi(&s);
|
||||
if (!s)
|
||||
goto adjust_seqack;
|
||||
/*
|
||||
* check for CR-LF at the end.
|
||||
*/
|
||||
if (*s != '\n' || *(s - 1) != '\r')
|
||||
goto adjust_seqack;
|
||||
a6 = a5 & 0xff;
|
||||
a5 >>= 8;
|
||||
/*
|
||||
* Calculate new address parts for PORT command
|
||||
*/
|
||||
a1 = ntohl(ip->ip_src.s_addr);
|
||||
a2 = (a1 >> 16) & 0xff;
|
||||
a3 = (a1 >> 8) & 0xff;
|
||||
a4 = a1 & 0xff;
|
||||
a1 >>= 24;
|
||||
olen = s - portbuf + 1;
|
||||
(void) sprintf(newbuf, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||
a1, a2, a3, a4, a5, a6);
|
||||
nlen = strlen(newbuf);
|
||||
inc = nlen - olen;
|
||||
if (tcp->th_seq > aps->aps_after) {
|
||||
aps->aps_after = ntohl(tcp->th_seq) + dlen;
|
||||
aps->aps_seqoff += inc;
|
||||
}
|
||||
#if SOLARIS
|
||||
if (inc && dlen)
|
||||
if ((inc < 0) || (blen >= dlen)) {
|
||||
bcopy(m->b_rptr + off,
|
||||
m->b_rptr + off + aps->aps_seqoff, dlen);
|
||||
}
|
||||
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
|
||||
;
|
||||
m1->b_wptr += inc;
|
||||
copyin_mblk(m, off, newbuf, strlen(newbuf));
|
||||
#else
|
||||
if (inc && dlen)
|
||||
if ((inc < 0) || (blen >= dlen)) {
|
||||
bcopy((char *)ip + off,
|
||||
(char *)ip + off + aps->aps_seqoff, dlen);
|
||||
}
|
||||
m->m_len += inc;
|
||||
m_copyback(m, off, nlen, newbuf);
|
||||
#endif
|
||||
ip->ip_len += inc;
|
||||
ch = 1;
|
||||
|
||||
/*
|
||||
* Add skeleton NAT entry for connection which will come back the
|
||||
* other way.
|
||||
*/
|
||||
savep = fin->fin_dp;
|
||||
fin->fin_dp = (char *)tcp2;
|
||||
tcp2->th_sport = htons(a5 << 8 | a6);
|
||||
tcp2->th_dport = htons(20);
|
||||
swip = ip->ip_src;
|
||||
ip->ip_src = nat->nat_inip;
|
||||
if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND)))
|
||||
ipn->nat_age = fr_defnatage;
|
||||
ip->ip_src = swip;
|
||||
fin->fin_dp = (char *)savep;
|
||||
|
||||
adjust_seqack:
|
||||
if (tcp->th_dport == aps->aps_dport) {
|
||||
sum2 = (u_long)ntohl(tcp->th_seq);
|
||||
if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
|
||||
sum1 = (u_long)aps->aps_seqoff;
|
||||
tcp->th_seq = htonl(sum2 + sum1);
|
||||
ch = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ch ? 2 : 0;
|
||||
}
|
@ -9,10 +9,10 @@
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
|
||||
static char rcsid[] = "$Id: ip_nat.c,v 1.1.1.3 1997/04/03 10:11:11 darrenr Exp $";
|
||||
static char rcsid[] = "$Id: ip_nat.c,v 2.0.2.18 1997/05/24 07:34:44 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && defined(KERNEL)
|
||||
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
|
||||
#define _KERNEL
|
||||
#endif
|
||||
|
||||
@ -26,7 +26,13 @@ static char rcsid[] = "$Id: ip_nat.c,v 1.1.1.3 1997/04/03 10:11:11 darrenr Exp $
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
|
||||
# include <sys/filio.h>
|
||||
# include <sys/fnctl.h>
|
||||
#else
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
@ -36,13 +42,19 @@ static char rcsid[] = "$Id: ip_nat.c,v 1.1.1.3 1997/04/03 10:11:11 darrenr Exp $
|
||||
#if !defined(__SVR4) && !defined(__svr4__)
|
||||
# include <sys/mbuf.h>
|
||||
#else
|
||||
# include <sys/filio.h>
|
||||
# include <sys/byteorder.h>
|
||||
# include <sys/dditypes.h>
|
||||
# include <sys/stream.h>
|
||||
# include <sys/kmem.h>
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
# include <sys/queue.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#if __FreeBSD_version >= 300000
|
||||
# include <net/if_var.h>
|
||||
#endif
|
||||
#ifdef sun
|
||||
#include <net/af.h>
|
||||
#endif
|
||||
@ -62,36 +74,30 @@ extern struct ifnet vpnif;
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "ip_compat.h"
|
||||
#include "ip_fil.h"
|
||||
#include "ip_nat.h"
|
||||
#include "ip_state.h"
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_proxy.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_frag.h"
|
||||
#include "netinet/ip_state.h"
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
#undef SOCKADDR_IN
|
||||
#define SOCKADDR_IN struct sockaddr_in
|
||||
|
||||
nat_t *nat_table[2][NAT_SIZE], *nat_instances = NULL;
|
||||
ipnat_t *nat_list = NULL;
|
||||
u_long nat_inuse = 0,
|
||||
fr_defnatage = 1200;
|
||||
u_long fr_defnatage = 1200;
|
||||
natstat_t nat_stats;
|
||||
#if SOLARIS
|
||||
# ifndef _KERNEL
|
||||
#define bzero(a,b) memset(a,0,b)
|
||||
#define bcmp(a,b,c) memcpy(a,b,c)
|
||||
#define bcopy(a,b,c) memmove(b,a,c)
|
||||
# else
|
||||
#if SOLARIS && defined(_KERNEL)
|
||||
extern kmutex_t ipf_nat;
|
||||
# endif
|
||||
extern kmutex_t ipf_natfrag;
|
||||
#endif
|
||||
|
||||
static int flush_nattable __P((void)), clear_natlist __P((void));
|
||||
static void nattable_sync __P((void)), nat_delete __P((struct nat *));
|
||||
static nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
|
||||
static void fix_outcksum __P((u_short *, u_long));
|
||||
static void fix_incksum __P((u_short *, u_long));
|
||||
|
||||
static void fix_outcksum(sp, n)
|
||||
void fix_outcksum(sp, n)
|
||||
u_short *sp;
|
||||
u_long n;
|
||||
{
|
||||
@ -112,7 +118,7 @@ u_long n;
|
||||
}
|
||||
|
||||
|
||||
static void fix_incksum(sp, n)
|
||||
void fix_incksum(sp, n)
|
||||
u_short *sp;
|
||||
u_long n;
|
||||
{
|
||||
@ -197,6 +203,7 @@ int cmd, mode;
|
||||
}
|
||||
IRCOPY((char *)data, (char *)n, sizeof(*n));
|
||||
n->in_ifp = (void *)GETUNIT(n->in_ifname);
|
||||
n->in_apr = ap_match(n->in_p, n->in_plabel);
|
||||
n->in_next = *np;
|
||||
n->in_use = 0;
|
||||
n->in_space = ~(0xffffffff & ntohl(n->in_outmsk));
|
||||
@ -208,7 +215,7 @@ int cmd, mode;
|
||||
n->in_nip = ntohl(n->in_outip) + 1;
|
||||
else
|
||||
n->in_nip = ntohl(n->in_outip);
|
||||
if (n->in_redir == NAT_MAP) {
|
||||
if (n->in_redir & NAT_MAP) {
|
||||
n->in_pnext = ntohs(n->in_pmin);
|
||||
/*
|
||||
* Multiply by the number of ports made available.
|
||||
@ -219,6 +226,7 @@ int cmd, mode;
|
||||
}
|
||||
/* Otherwise, these fields are preset */
|
||||
*np = n;
|
||||
nat_stats.ns_rules++;
|
||||
break;
|
||||
case SIOCRMNAT :
|
||||
if (!(mode & FWRITE)) {
|
||||
@ -230,15 +238,20 @@ int cmd, mode;
|
||||
break;
|
||||
}
|
||||
*np = n->in_next;
|
||||
|
||||
KFREE(n);
|
||||
nattable_sync();
|
||||
if (!n->in_use) {
|
||||
if (n->in_apr)
|
||||
ap_free(n->in_apr);
|
||||
KFREE(n);
|
||||
nat_stats.ns_rules--;
|
||||
} else {
|
||||
n->in_flags |= IPN_DELETE;
|
||||
n->in_next = NULL;
|
||||
}
|
||||
break;
|
||||
case SIOCGNATS :
|
||||
nat_stats.ns_table[0] = nat_table[0];
|
||||
nat_stats.ns_table[1] = nat_table[1];
|
||||
nat_stats.ns_list = nat_list;
|
||||
nat_stats.ns_inuse = nat_inuse;
|
||||
IWCOPY((char *)&nat_stats, (char *)data, sizeof(nat_stats));
|
||||
break;
|
||||
case SIOCGNATL :
|
||||
@ -269,6 +282,11 @@ int cmd, mode;
|
||||
ret = clear_natlist();
|
||||
IWCOPY((caddr_t)&ret, data, sizeof(ret));
|
||||
break;
|
||||
case FIONREAD :
|
||||
#ifdef IPFILTER_LOG
|
||||
*(int *)data = iplused[IPL_LOGNAT];
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
SPLX(s);
|
||||
MUTEX_EXIT(&ipf_nat);
|
||||
@ -280,6 +298,7 @@ static void nat_delete(natd)
|
||||
struct nat *natd;
|
||||
{
|
||||
register struct nat **natp, *nat;
|
||||
struct ipnat *ipn;
|
||||
|
||||
for (natp = natd->nat_hstart[0]; (nat = *natp);
|
||||
natp = &nat->nat_hnext[0])
|
||||
@ -295,12 +314,21 @@ struct nat *natd;
|
||||
break;
|
||||
}
|
||||
|
||||
if (natd->nat_ptr) {
|
||||
natd->nat_ptr->in_space++;
|
||||
natd->nat_ptr->in_use--;
|
||||
if ((ipn = natd->nat_ptr)) {
|
||||
ipn->in_space++;
|
||||
ipn->in_use--;
|
||||
if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) {
|
||||
if (ipn->in_apr)
|
||||
ap_free(ipn->in_apr);
|
||||
KFREE(ipn);
|
||||
nat_stats.ns_rules--;
|
||||
}
|
||||
}
|
||||
MUTEX_ENTER(&ipf_natfrag);
|
||||
if (nat->nat_frag && nat->nat_frag->ipfr_data == nat)
|
||||
nat->nat_frag->ipfr_data = NULL;
|
||||
MUTEX_EXIT(&ipf_natfrag);
|
||||
KFREE(natd);
|
||||
nat_inuse--;
|
||||
}
|
||||
|
||||
|
||||
@ -329,44 +357,28 @@ static int flush_nattable()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* I know this is O(N*M), but it can't be avoided.
|
||||
*/
|
||||
static void nattable_sync()
|
||||
{
|
||||
register nat_t *nat;
|
||||
register ipnat_t *np;
|
||||
int i;
|
||||
|
||||
for (i = NAT_SIZE - 1; i >= 0; i--)
|
||||
for (nat = nat_instances; nat; nat = nat->nat_next) {
|
||||
for (np = nat_list; np; np = np->in_next)
|
||||
if (nat->nat_ptr == np)
|
||||
break;
|
||||
/*
|
||||
* XXX - is it better to remove this if ? works the
|
||||
* same if it is just "nat->nat_ptr = np".
|
||||
*/
|
||||
if (!np)
|
||||
nat->nat_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* clear_natlist - delete all entries in the active NAT mapping list.
|
||||
*/
|
||||
static int clear_natlist()
|
||||
{
|
||||
register ipnat_t *n, **np;
|
||||
register ipnat_t *n, **np = &nat_list;
|
||||
int i = 0;
|
||||
|
||||
for (np = &nat_list; (n = *np); i++) {
|
||||
while ((n = *np)) {
|
||||
*np = n->in_next;
|
||||
KFREE(n);
|
||||
if (!n->in_use) {
|
||||
if (n->in_apr)
|
||||
ap_free(n->in_apr);
|
||||
KFREE(n);
|
||||
nat_stats.ns_rules--;
|
||||
i++;
|
||||
} else {
|
||||
n->in_flags |= IPN_DELETE;
|
||||
n->in_next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nattable_sync();
|
||||
nat_stats.ns_inuse = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -374,7 +386,7 @@ static int clear_natlist()
|
||||
/*
|
||||
* Create a new NAT table entry.
|
||||
*/
|
||||
static nat_t *nat_new(np, ip, fin, flags, direction)
|
||||
nat_t *nat_new(np, ip, fin, flags, direction)
|
||||
ipnat_t *np;
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
@ -426,15 +438,31 @@ int direction;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
ifa = ifp->if_addrlist;
|
||||
# if BSD < 199306
|
||||
sin = (struct sockaddr_in *)&ifa->ifa_addr;
|
||||
# if (__FreeBSD_version >= 300000)
|
||||
ifa = TAILQ_FIRST(&ifp->if_addrhead);
|
||||
# else
|
||||
sin = (struct sockaddr_in *)ifa->ifa_addr;
|
||||
# ifdef __NetBSD__
|
||||
ifa = ifp->if_addrlist.tqh_first;
|
||||
# else
|
||||
ifa = ifp->if_addrlist;
|
||||
# endif
|
||||
# endif
|
||||
# if BSD < 199306
|
||||
sin = (SOCKADDR_IN *)&ifa->ifa_addr;
|
||||
# else
|
||||
sin = (SOCKADDR_IN *)ifa->ifa_addr;
|
||||
while (sin && ifa &&
|
||||
sin->sin_family != AF_INET) {
|
||||
# if (__FreeBSD_version >= 300000)
|
||||
ifa = TAILQ_NEXT(ifa, ifa_link);
|
||||
# else
|
||||
# ifdef __NetBSD__
|
||||
ifa = ifa->ifa_list.tqe_next;
|
||||
# else
|
||||
ifa = ifa->ifa_next;
|
||||
sin = (struct sockaddr_in *)ifa->ifa_addr;
|
||||
# endif
|
||||
# endif
|
||||
sin = (SOCKADDR_IN *)ifa->ifa_addr;
|
||||
}
|
||||
if (!ifa)
|
||||
sin = NULL;
|
||||
@ -465,7 +493,8 @@ int direction;
|
||||
if ((np->in_nip & ntohl(np->in_outmsk)) >
|
||||
ntohl(np->in_outip))
|
||||
np->in_nip = ntohl(np->in_outip) + 1;
|
||||
} while (nat_inlookup(flags, ip->ip_dst, dport, in, port));
|
||||
} while (nat_inlookup(fin->fin_ifp, flags, ip->ip_dst,
|
||||
dport, in, port));
|
||||
|
||||
/* Setup the NAT table */
|
||||
nat->nat_inip = ip->ip_src;
|
||||
@ -562,7 +591,10 @@ int direction;
|
||||
nat->nat_hnext[1] = *natp;
|
||||
*natp = nat;
|
||||
nat->nat_ptr = np;
|
||||
np->in_use++;
|
||||
nat->nat_bytes = 0;
|
||||
nat->nat_pkts = 0;
|
||||
nat->nat_ifp = fin->fin_ifp;
|
||||
nat->nat_dir = direction;
|
||||
if (direction == NAT_OUTBOUND) {
|
||||
if (flags & IPN_TCPUDP)
|
||||
tcp->th_sport = htons(port);
|
||||
@ -571,7 +603,8 @@ int direction;
|
||||
tcp->th_dport = htons(nport);
|
||||
}
|
||||
nat_stats.ns_added++;
|
||||
nat_inuse++;
|
||||
nat_stats.ns_inuse++;
|
||||
np->in_use++;
|
||||
return nat;
|
||||
}
|
||||
|
||||
@ -586,7 +619,8 @@ int direction;
|
||||
* we're looking for a table entry, based on the destination address.
|
||||
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
|
||||
*/
|
||||
nat_t *nat_inlookup(flags, src, sport, mapdst, mapdport)
|
||||
nat_t *nat_inlookup(ifp, flags, src, sport, mapdst, mapdport)
|
||||
void *ifp;
|
||||
register int flags;
|
||||
struct in_addr src , mapdst;
|
||||
u_short sport, mapdport;
|
||||
@ -597,7 +631,8 @@ u_short sport, mapdport;
|
||||
|
||||
nat = nat_table[1][mapdst.s_addr % NAT_SIZE];
|
||||
for (; nat; nat = nat->nat_hnext[1])
|
||||
if (nat->nat_oip.s_addr == src.s_addr &&
|
||||
if ((!ifp || ifp == nat->nat_ifp) &&
|
||||
nat->nat_oip.s_addr == src.s_addr &&
|
||||
nat->nat_outip.s_addr == mapdst.s_addr &&
|
||||
flags == nat->nat_flags && (!flags ||
|
||||
(nat->nat_oport == sport &&
|
||||
@ -613,7 +648,8 @@ u_short sport, mapdport;
|
||||
* we're looking for a table entry, based on the source address.
|
||||
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
|
||||
*/
|
||||
nat_t *nat_outlookup(flags, src, sport, dst, dport)
|
||||
nat_t *nat_outlookup(ifp, flags, src, sport, dst, dport)
|
||||
void *ifp;
|
||||
register int flags;
|
||||
struct in_addr src , dst;
|
||||
u_short sport, dport;
|
||||
@ -624,7 +660,8 @@ u_short sport, dport;
|
||||
|
||||
nat = nat_table[0][src.s_addr % NAT_SIZE];
|
||||
for (; nat; nat = nat->nat_hnext[0])
|
||||
if (nat->nat_inip.s_addr == src.s_addr &&
|
||||
if ((!ifp || ifp == nat->nat_ifp) &&
|
||||
nat->nat_inip.s_addr == src.s_addr &&
|
||||
nat->nat_oip.s_addr == dst.s_addr &&
|
||||
flags == nat->nat_flags && (!flags ||
|
||||
(nat->nat_inport == sport && nat->nat_oport == dport)))
|
||||
@ -638,7 +675,8 @@ u_short sport, dport;
|
||||
* real destination address/port. We use this lookup when sending a packet
|
||||
* out, we're looking for a table entry, based on the source address.
|
||||
*/
|
||||
nat_t *nat_lookupmapip(flags, mapsrc, mapsport, dst, dport)
|
||||
nat_t *nat_lookupmapip(ifp, flags, mapsrc, mapsport, dst, dport)
|
||||
void *ifp;
|
||||
register int flags;
|
||||
struct in_addr mapsrc , dst;
|
||||
u_short mapsport, dport;
|
||||
@ -649,8 +687,9 @@ u_short mapsport, dport;
|
||||
|
||||
nat = nat_table[1][mapsrc.s_addr % NAT_SIZE];
|
||||
for (; nat; nat = nat->nat_hnext[0])
|
||||
if (nat->nat_outip.s_addr == mapsrc.s_addr &&
|
||||
if ((!ifp || ifp == nat->nat_ifp) &&
|
||||
nat->nat_oip.s_addr == dst.s_addr &&
|
||||
nat->nat_outip.s_addr == mapsrc.s_addr &&
|
||||
flags == nat->nat_flags && (!flags ||
|
||||
(nat->nat_outport == mapsport &&
|
||||
nat->nat_oport == dport)))
|
||||
@ -671,7 +710,7 @@ register natlookup_t *np;
|
||||
* If nl_inip is non null, this is a lookup based on the real
|
||||
* ip address. Else, we use the fake.
|
||||
*/
|
||||
if ((nat = nat_outlookup(IPN_TCPUDP, np->nl_inip, np->nl_inport,
|
||||
if ((nat = nat_outlookup(NULL, IPN_TCPUDP, np->nl_inip, np->nl_inport,
|
||||
np->nl_outip, np->nl_outport))) {
|
||||
np->nl_inip = nat->nat_outip;
|
||||
np->nl_inport = nat->nat_outport;
|
||||
@ -718,43 +757,56 @@ fr_info_t *fin;
|
||||
ipa = ip->ip_src.s_addr;
|
||||
|
||||
MUTEX_ENTER(&ipf_nat);
|
||||
for (np = nat_list; np; np = np->in_next)
|
||||
if ((np->in_ifp == ifp) && np->in_space &&
|
||||
(!np->in_flags || (np->in_flags & nflags)) &&
|
||||
((ipa & np->in_inmsk) == np->in_inip) &&
|
||||
((np->in_redir == NAT_MAP) ||
|
||||
(np->in_pnext == sport))) {
|
||||
/*
|
||||
* If there is no current entry in the nat table for
|
||||
* this IP#, create one for it.
|
||||
*/
|
||||
if (!(nat = nat_outlookup(nflags, ip->ip_src, sport,
|
||||
ip->ip_dst, dport))) {
|
||||
if ((nat = ipfr_nat_knownfrag(ip, fin)))
|
||||
;
|
||||
else if ((nat = nat_outlookup(fin->fin_ifp, nflags, ip->ip_src, sport,
|
||||
ip->ip_dst, dport)))
|
||||
np = nat->nat_ptr;
|
||||
else
|
||||
/*
|
||||
* If there is no current entry in the nat table for this IP#,
|
||||
* create one for it (if there is a matching rule).
|
||||
*/
|
||||
for (np = nat_list; np; np = np->in_next)
|
||||
if ((np->in_ifp == ifp) && np->in_space &&
|
||||
(!np->in_flags || (np->in_flags & nflags)) &&
|
||||
((ipa & np->in_inmsk) == np->in_inip) &&
|
||||
((np->in_redir & NAT_MAP) ||
|
||||
(np->in_pnext == sport))) {
|
||||
if (*np->in_plabel && !ap_ok(ip, tcp, np))
|
||||
continue;
|
||||
/*
|
||||
* If it's a redirection, then we don't want
|
||||
* to create new outgoing port stuff.
|
||||
* If it's a redirection, then we don't want to
|
||||
* create new outgoing port stuff.
|
||||
* Redirections are only for incoming
|
||||
* connections.
|
||||
*/
|
||||
if (np->in_redir == NAT_REDIRECT)
|
||||
if (!(np->in_redir & NAT_MAP))
|
||||
continue;
|
||||
if (!(nat = nat_new(np, ip, fin, nflags,
|
||||
if ((nat = nat_new(np, ip, fin, nflags,
|
||||
NAT_OUTBOUND)))
|
||||
break;
|
||||
#ifdef IPFILTER_LOG
|
||||
nat_log(nat, (u_short)np->in_redir);
|
||||
nat_log(nat, (u_short)np->in_redir);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ip->ip_src = nat->nat_outip;
|
||||
|
||||
nat->nat_age = fr_defnatage; /* 5 mins */
|
||||
if (nat) {
|
||||
if (!nat->nat_frag && fin->fin_fi.fi_fl & FI_FRAG)
|
||||
ipfr_nat_newfrag(ip, fin, 0, nat);
|
||||
nat->nat_age = fr_defnatage;
|
||||
ip->ip_src = nat->nat_outip;
|
||||
nat->nat_bytes += ip->ip_len;
|
||||
nat->nat_pkts++;
|
||||
|
||||
/*
|
||||
* Fix up checksums, not by recalculating them, but
|
||||
* simply computing adjustments.
|
||||
*/
|
||||
#if SOLARIS
|
||||
if (np->in_redir == NAT_MAP)
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
|
||||
else
|
||||
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
|
||||
@ -770,6 +822,14 @@ fr_info_t *fin;
|
||||
csump = &tcp->th_sum;
|
||||
fr_tcp_age(&nat->nat_age,
|
||||
nat->nat_state, ip, fin,1);
|
||||
/*
|
||||
* Increase this because we may have
|
||||
* "keep state" following this too and
|
||||
* packet storms can occur if this is
|
||||
* removed too quickly.
|
||||
*/
|
||||
if (nat->nat_age == fr_tcpclosed)
|
||||
nat->nat_age = fr_tcplastack;
|
||||
} else if (ip->ip_p == IPPROTO_UDP) {
|
||||
udphdr_t *udp = (udphdr_t *)tcp;
|
||||
|
||||
@ -781,7 +841,7 @@ fr_info_t *fin;
|
||||
csump = &ic->icmp_cksum;
|
||||
}
|
||||
if (csump) {
|
||||
if (np->in_redir == NAT_MAP)
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_outcksum(csump,
|
||||
nat->nat_sumd);
|
||||
else
|
||||
@ -789,6 +849,7 @@ fr_info_t *fin;
|
||||
nat->nat_sumd);
|
||||
}
|
||||
}
|
||||
(void) ap_check(ip, tcp, fin, nat);
|
||||
nat_stats.ns_mapped[1]++;
|
||||
MUTEX_EXIT(&ipf_nat);
|
||||
return 1;
|
||||
@ -829,38 +890,55 @@ fr_info_t *fin;
|
||||
in = ip->ip_dst;
|
||||
|
||||
MUTEX_ENTER(&ipf_nat);
|
||||
for (np = nat_list; np; np = np->in_next)
|
||||
if ((np->in_ifp == ifp) &&
|
||||
(!np->in_flags || (nflags & np->in_flags)) &&
|
||||
((in.s_addr & np->in_outmsk) == np->in_outip) &&
|
||||
(np->in_redir == NAT_MAP || np->in_pmin == dport)) {
|
||||
if (!(nat = nat_inlookup(nflags, ip->ip_src, sport,
|
||||
ip->ip_dst, dport))) {
|
||||
|
||||
if ((nat = ipfr_nat_knownfrag(ip, fin)))
|
||||
;
|
||||
else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport,
|
||||
ip->ip_dst, dport)))
|
||||
np = nat->nat_ptr;
|
||||
else
|
||||
/*
|
||||
* If there is no current entry in the nat table for this IP#,
|
||||
* create one for it (if there is a matching rule).
|
||||
*/
|
||||
for (np = nat_list; np; np = np->in_next)
|
||||
if ((np->in_ifp == ifp) &&
|
||||
(!np->in_flags || (nflags & np->in_flags)) &&
|
||||
((in.s_addr & np->in_outmsk) == np->in_outip) &&
|
||||
(np->in_redir & NAT_REDIRECT ||
|
||||
np->in_pmin == dport)) {
|
||||
/*
|
||||
* If this rule (np) is a redirection, rather
|
||||
* than a mapping, then do a nat_new.
|
||||
* Otherwise, if it's just a mapping, do a
|
||||
* continue;
|
||||
*/
|
||||
if (np->in_redir == NAT_MAP)
|
||||
if (!(np->in_redir & NAT_REDIRECT))
|
||||
continue;
|
||||
if (!(nat = nat_new(np, ip, fin, nflags,
|
||||
if ((nat = nat_new(np, ip, fin, nflags,
|
||||
NAT_INBOUND)))
|
||||
break;
|
||||
#ifdef IPFILTER_LOG
|
||||
nat_log(nat, (u_short)np->in_redir);
|
||||
nat_log(nat, (u_short)np->in_redir);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
ip->ip_dst = nat->nat_inip;
|
||||
|
||||
if (nat) {
|
||||
if (!nat->nat_frag && fin->fin_fi.fi_fl & FI_FRAG)
|
||||
ipfr_nat_newfrag(ip, fin, 0, nat);
|
||||
(void) ap_check(ip, tcp, fin, nat);
|
||||
nat->nat_age = fr_defnatage;
|
||||
ip->ip_dst = nat->nat_inip;
|
||||
nat->nat_bytes += ip->ip_len;
|
||||
nat->nat_pkts++;
|
||||
|
||||
/*
|
||||
* Fix up checksums, not by recalculating them, but
|
||||
* simply computing adjustments.
|
||||
*/
|
||||
#if SOLARIS
|
||||
if (np->in_redir == NAT_MAP)
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
|
||||
else
|
||||
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
|
||||
@ -875,6 +953,14 @@ fr_info_t *fin;
|
||||
csump = &tcp->th_sum;
|
||||
fr_tcp_age(&nat->nat_age,
|
||||
nat->nat_state, ip, fin,0);
|
||||
/*
|
||||
* Increase this because we may have
|
||||
* "keep state" following this too and
|
||||
* packet storms can occur if this is
|
||||
* removed too quickly.
|
||||
*/
|
||||
if (nat->nat_age == fr_tcpclosed)
|
||||
nat->nat_age = fr_tcplastack;
|
||||
} else if (ip->ip_p == IPPROTO_UDP) {
|
||||
udphdr_t *udp = (udphdr_t *)tcp;
|
||||
|
||||
@ -886,7 +972,7 @@ fr_info_t *fin;
|
||||
csump = &ic->icmp_cksum;
|
||||
}
|
||||
if (csump) {
|
||||
if (np->in_redir == NAT_MAP)
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_incksum(csump,
|
||||
nat->nat_sumd);
|
||||
else
|
||||
@ -914,6 +1000,7 @@ void ip_natunload()
|
||||
SPLNET(s);
|
||||
(void) clear_natlist();
|
||||
(void) flush_nattable();
|
||||
(void) ap_unload();
|
||||
SPLX(s)
|
||||
MUTEX_EXIT(&ipf_nat);
|
||||
}
|
||||
@ -970,12 +1057,14 @@ u_short type;
|
||||
# if BSD >= 199306 || defined(__FreeBSD__)
|
||||
microtime((struct timeval *)&natl);
|
||||
# endif
|
||||
natl.nl_origport = nat->nat_oport;
|
||||
natl.nl_outport = nat->nat_outport;
|
||||
natl.nl_inport = nat->nat_inport;
|
||||
natl.nl_origip = nat->nat_oip;
|
||||
natl.nl_outip = nat->nat_outip;
|
||||
natl.nl_inip = nat->nat_inip;
|
||||
natl.nl_outip = nat->nat_outip;
|
||||
natl.nl_origip = nat->nat_oip;
|
||||
natl.nl_bytes = nat->nat_bytes;
|
||||
natl.nl_pkts = nat->nat_pkts;
|
||||
natl.nl_origport = nat->nat_oport;
|
||||
natl.nl_inport = nat->nat_inport;
|
||||
natl.nl_outport = nat->nat_outport;
|
||||
natl.nl_type = type;
|
||||
natl.nl_rule = -1;
|
||||
if (nat->nat_ptr) {
|
||||
|
@ -1,17 +1,21 @@
|
||||
/*
|
||||
* (C)opyright 1995 by Darren Reed.
|
||||
* (C)opyright 1995-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ip_nat.h 1.5 2/4/96
|
||||
* $Id: ip_nat.h,v 1.1.1.2 1997/04/03 10:11:19 darrenr Exp $
|
||||
* $Id: ip_nat.h,v 2.0.2.12 1997/05/24 07:35:20 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_NAT_H_
|
||||
#ifndef __IP_NAT_H__
|
||||
#define __IP_NAT_H__
|
||||
|
||||
#ifndef __IP_PROXY_H__
|
||||
#include "netinet/ip_proxy.h"
|
||||
#endif
|
||||
|
||||
#ifndef SOLARIS
|
||||
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
|
||||
#endif
|
||||
@ -44,9 +48,12 @@ typedef struct nat {
|
||||
int nat_flags;
|
||||
u_long nat_sumd;
|
||||
u_long nat_ipsumd;
|
||||
struct ipfr *nat_frag;
|
||||
struct in_addr nat_inip;
|
||||
struct in_addr nat_outip;
|
||||
struct in_addr nat_oip; /* other ip */
|
||||
U_QUAD_T nat_pkts;
|
||||
U_QUAD_T nat_bytes;
|
||||
u_short nat_oport; /* other port */
|
||||
u_short nat_inport;
|
||||
u_short nat_outport;
|
||||
@ -56,6 +63,8 @@ typedef struct nat {
|
||||
struct nat *nat_next;
|
||||
struct nat *nat_hnext[2];
|
||||
struct nat **nat_hstart[2];
|
||||
void *nat_ifp;
|
||||
int nat_dir;
|
||||
} nat_t;
|
||||
|
||||
typedef struct ipnat {
|
||||
@ -69,8 +78,12 @@ typedef struct ipnat {
|
||||
u_short in_port[2];
|
||||
struct in_addr in_in[2];
|
||||
struct in_addr in_out[2];
|
||||
struct aproxy *in_apr;
|
||||
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
|
||||
char in_ifname[IFNAMSIZ];
|
||||
char in_plabel[APR_LABELLEN]; /* proxy label */
|
||||
char in_p; /* protocol */
|
||||
u_short in_dport;
|
||||
} ipnat_t;
|
||||
|
||||
#define in_pmin in_port[0] /* Also holds static redir port */
|
||||
@ -81,11 +94,12 @@ typedef struct ipnat {
|
||||
#define in_outip in_out[0].s_addr
|
||||
#define in_outmsk in_out[1].s_addr
|
||||
|
||||
#define NAT_INBOUND 0
|
||||
#define NAT_OUTBOUND 1
|
||||
#define NAT_OUTBOUND 0
|
||||
#define NAT_INBOUND 1
|
||||
|
||||
#define NAT_MAP 0
|
||||
#define NAT_REDIRECT 1
|
||||
#define NAT_MAP 0x01
|
||||
#define NAT_REDIRECT 0x02
|
||||
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
|
||||
|
||||
#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \
|
||||
sizeof(int))
|
||||
@ -99,6 +113,7 @@ typedef struct natlookup {
|
||||
|
||||
typedef struct natstat {
|
||||
u_long ns_mapped[2];
|
||||
u_long ns_rules;
|
||||
u_long ns_added;
|
||||
u_long ns_expire;
|
||||
u_long ns_inuse;
|
||||
@ -108,10 +123,11 @@ typedef struct natstat {
|
||||
ipnat_t *ns_list;
|
||||
} natstat_t;
|
||||
|
||||
#define IPN_ANY 0
|
||||
#define IPN_TCP 1
|
||||
#define IPN_UDP 2
|
||||
#define IPN_TCPUDP 3
|
||||
#define IPN_ANY 0x00
|
||||
#define IPN_TCP 0x01
|
||||
#define IPN_UDP 0x02
|
||||
#define IPN_TCPUDP 0x03
|
||||
#define IPN_DELETE 0x04
|
||||
|
||||
|
||||
typedef struct natlog {
|
||||
@ -124,6 +140,8 @@ typedef struct natlog {
|
||||
u_short nl_inport;
|
||||
u_short nl_type;
|
||||
int nl_rule;
|
||||
U_QUAD_T nl_pkts;
|
||||
U_QUAD_T nl_bytes;
|
||||
} natlog_t;
|
||||
|
||||
|
||||
@ -132,18 +150,22 @@ typedef struct natlog {
|
||||
#define NL_EXPIRE 0xffff
|
||||
|
||||
|
||||
extern u_long fr_defnatage;
|
||||
extern nat_t *nat_table[2][NAT_SIZE];
|
||||
extern int nat_ioctl __P((caddr_t, int, int));
|
||||
extern nat_t *nat_outlookup __P((int, struct in_addr, u_short,
|
||||
extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
|
||||
extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short,
|
||||
struct in_addr, u_short));
|
||||
extern nat_t *nat_inlookup __P((int, struct in_addr, u_short,
|
||||
extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short,
|
||||
struct in_addr, u_short));
|
||||
extern nat_t *nat_lookupredir __P((natlookup_t *));
|
||||
extern nat_t *nat_lookupmapip __P((int, struct in_addr, u_short,
|
||||
extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short,
|
||||
struct in_addr, u_short));
|
||||
|
||||
extern int ip_natout __P((ip_t *, int, fr_info_t *));
|
||||
extern int ip_natin __P((ip_t *, int, fr_info_t *));
|
||||
extern void ip_natunload __P((void)), ip_natexpire __P((void));
|
||||
extern void nat_log __P((struct nat *, u_short));
|
||||
extern void fix_incksum __P((u_short *, u_long));
|
||||
extern void fix_outcksum __P((u_short *, u_long));
|
||||
#endif /* __IP_NAT_H__ */
|
||||
|
271
sys/netinet/ip_proxy.c
Normal file
271
sys/netinet/ip_proxy.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* (C)opyright 1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char rcsid[] = "$Id: ip_proxy.c,v 2.0.2.3 1997/05/24 07:36:22 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
|
||||
# define _KERNEL
|
||||
#endif
|
||||
|
||||
#if !defined(_KERNEL) && !defined(KERNEL)
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
# include <sys/systm.h>
|
||||
#endif
|
||||
#if !defined(__SVR4) && !defined(__svr4__)
|
||||
# include <sys/mbuf.h>
|
||||
#else
|
||||
# include <sys/byteorder.h>
|
||||
# include <sys/dditypes.h>
|
||||
# include <sys/stream.h>
|
||||
# include <sys/kmem.h>
|
||||
#endif
|
||||
#if __FreeBSD__ > 2
|
||||
# include <sys/queue.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#ifdef sun
|
||||
# include <net/af.h>
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_proxy.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_state.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
static ap_session_t *ap_find __P((ip_t *, tcphdr_t *));
|
||||
static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *,
|
||||
fr_info_t *, nat_t *));
|
||||
|
||||
#define AP_SESS_SIZE 53
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include "netinet/ip_ftp_pxy.c"
|
||||
#endif
|
||||
|
||||
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
|
||||
aproxy_t ap_proxies[] = {
|
||||
#ifdef IPF_FTP_PROXY
|
||||
{ "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_in, ippr_ftp_out },
|
||||
#endif
|
||||
{ "", '\0', 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
int ap_ok(ip, tcp, nat)
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
ipnat_t *nat;
|
||||
{
|
||||
aproxy_t *apr = nat->in_apr;
|
||||
u_short dport = nat->in_dport;
|
||||
|
||||
if (!apr || (apr && (apr->apr_flags & APR_DELETE)) ||
|
||||
(ip->ip_p != apr->apr_p))
|
||||
return 0;
|
||||
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ap_session_t *ap_find(ip, tcp)
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
{
|
||||
struct in_addr src = ip->ip_src, dst = ip->ip_dst;
|
||||
register u_long hv;
|
||||
register u_short sp, dp;
|
||||
register ap_session_t *aps;
|
||||
register u_char p = ip->ip_p;
|
||||
|
||||
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
|
||||
hv *= 651733;
|
||||
if (tcp) {
|
||||
sp = tcp->th_sport;
|
||||
dp = tcp->th_dport;
|
||||
hv ^= (sp + dp);
|
||||
hv *= 5;
|
||||
}
|
||||
hv %= AP_SESS_SIZE;
|
||||
|
||||
for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next)
|
||||
if ((aps->aps_p == p) &&
|
||||
IPPAIR(aps->aps_src, aps->aps_dst, src, dst)) {
|
||||
if (tcp) {
|
||||
if (PAIRS(aps->aps_sport, aps->aps_dport,
|
||||
sp, dp))
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return aps;
|
||||
}
|
||||
|
||||
static ap_session_t *ap_new_session(apr, ip, tcp, fin, nat)
|
||||
aproxy_t *apr;
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
fr_info_t *fin;
|
||||
nat_t *nat;
|
||||
{
|
||||
register ap_session_t *aps;
|
||||
u_short dport;
|
||||
u_long hv;
|
||||
|
||||
if (!apr || (apr && (apr->apr_flags & APR_DELETE)) ||
|
||||
(ip->ip_p != apr->apr_p))
|
||||
return NULL;
|
||||
dport = nat->nat_ptr->in_dport;
|
||||
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
|
||||
return NULL;
|
||||
|
||||
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
|
||||
hv *= 651733;
|
||||
if (tcp) {
|
||||
hv ^= (tcp->th_sport + tcp->th_dport);
|
||||
hv *= 5;
|
||||
}
|
||||
hv %= AP_SESS_SIZE;
|
||||
|
||||
KMALLOC(aps, ap_session_t *, sizeof(*aps));
|
||||
if (!aps)
|
||||
return NULL;
|
||||
bzero((char *)aps, sizeof(aps));
|
||||
apr->apr_ref++;
|
||||
aps->aps_apr = apr;
|
||||
aps->aps_src = ip->ip_src;
|
||||
aps->aps_dst = ip->ip_dst;
|
||||
aps->aps_p = ip->ip_p;
|
||||
aps->aps_tout = 1200; /* XXX */
|
||||
if (tcp) {
|
||||
if (ip->ip_p == IPPROTO_TCP) {
|
||||
aps->aps_seqoff = 0;
|
||||
aps->aps_ackoff = 0;
|
||||
aps->aps_state[0] = 0;
|
||||
aps->aps_state[1] = 0;
|
||||
}
|
||||
aps->aps_sport = tcp->th_sport;
|
||||
aps->aps_dport = tcp->th_dport;
|
||||
}
|
||||
aps->aps_data = NULL;
|
||||
aps->aps_psiz = 0;
|
||||
aps->aps_next = ap_sess_tab[hv];
|
||||
ap_sess_tab[hv] = aps;
|
||||
(void) (*apr->apr_init)(fin, ip, tcp, aps, nat);
|
||||
return aps;
|
||||
}
|
||||
|
||||
|
||||
int ap_check(ip, tcp, fin, nat)
|
||||
ip_t *ip;
|
||||
tcphdr_t *tcp;
|
||||
fr_info_t *fin;
|
||||
nat_t *nat;
|
||||
{
|
||||
ap_session_t *aps;
|
||||
aproxy_t *apr;
|
||||
int err;
|
||||
|
||||
if (!(fin->fin_fi.fi_fl & FI_TCPUDP))
|
||||
tcp = NULL;
|
||||
|
||||
if ((aps = ap_find(ip, tcp)) ||
|
||||
(aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) {
|
||||
if (ip->ip_p == IPPROTO_TCP)
|
||||
fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin,
|
||||
tcp->th_sport == aps->aps_sport);
|
||||
apr = aps->aps_apr;
|
||||
err = 0;
|
||||
if (fin->fin_out) {
|
||||
if (apr->apr_outpkt)
|
||||
err = (*apr->apr_outpkt)(fin, ip, tcp,
|
||||
aps, nat);
|
||||
} else {
|
||||
if (apr->apr_inpkt)
|
||||
err = (*apr->apr_inpkt)(fin, ip, tcp,
|
||||
aps, nat);
|
||||
}
|
||||
if (err == 2) {
|
||||
tcp->th_sum = fr_tcpsum(fin->fin_mp, ip, tcp);
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
aproxy_t *ap_match(pr, name)
|
||||
char pr;
|
||||
char *name;
|
||||
{
|
||||
aproxy_t *ap;
|
||||
|
||||
for (ap = ap_proxies; ap->apr_p; ap++)
|
||||
if ((ap->apr_p == pr) &&
|
||||
!strncmp(name, ap->apr_label, sizeof(ap->apr_label)))
|
||||
return ap;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void ap_free(ap)
|
||||
aproxy_t *ap;
|
||||
{
|
||||
KFREE(ap);
|
||||
}
|
||||
|
||||
|
||||
void aps_free(aps)
|
||||
ap_session_t *aps;
|
||||
{
|
||||
if (aps->aps_data && aps->aps_psiz)
|
||||
KFREES(aps->aps_data, aps->aps_psiz);
|
||||
KFREE(aps);
|
||||
}
|
||||
|
||||
|
||||
void ap_unload()
|
||||
{
|
||||
ap_session_t *aps;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AP_SESS_SIZE; i++)
|
||||
while (aps = ap_sess_tab[i]) {
|
||||
ap_sess_tab[i] = aps->aps_next;
|
||||
aps_free(aps);
|
||||
}
|
||||
}
|
89
sys/netinet/ip_proxy.h
Normal file
89
sys/netinet/ip_proxy.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* (C)opyright 1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* $Id: ip_proxy.h,v 2.0.2.2 1997/05/24 07:36:44 darrenr Exp $
|
||||
*/
|
||||
|
||||
#ifndef __IP_PROXY_H__
|
||||
#define __IP_PROXY_H__
|
||||
|
||||
#ifndef SOLARIS
|
||||
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
|
||||
#endif
|
||||
|
||||
#define APR_LABELLEN 16
|
||||
#define AP_SESS_SIZE 53
|
||||
|
||||
struct nat;
|
||||
|
||||
typedef struct ap_tcp {
|
||||
u_short apt_sport; /* source port */
|
||||
u_short apt_dport; /* destination port */
|
||||
short apt_seqoff; /* sequence # difference */
|
||||
short apt_ackoff; /* ack # difference */
|
||||
tcp_seq apt_after; /* don't change seq-off until after this */
|
||||
char apt_state[2]; /* connection state */
|
||||
} ap_tcp_t;
|
||||
|
||||
typedef struct ap_udp {
|
||||
u_short apu_sport; /* source port */
|
||||
u_short apu_dport; /* destination port */
|
||||
} ap_udp_t;
|
||||
|
||||
typedef struct ap_session {
|
||||
struct aproxy *aps_apr;
|
||||
struct in_addr aps_src; /* source IP# */
|
||||
struct in_addr aps_dst; /* destination IP# */
|
||||
u_char aps_p; /* protocol */
|
||||
union {
|
||||
struct ap_tcp apu_tcp;
|
||||
struct ap_udp apu_udp;
|
||||
} aps_un;
|
||||
u_int aps_flags;
|
||||
QUAD_T aps_bytes; /* bytes sent */
|
||||
QUAD_T aps_pkts; /* packets sent */
|
||||
time_t aps_tout; /* time left before expiring */
|
||||
void *aps_data; /* private data */
|
||||
int aps_psiz; /* size of private data */
|
||||
struct ap_session *aps_next;
|
||||
} ap_session_t ;
|
||||
|
||||
#define aps_sport aps_un.apu_tcp.apt_sport
|
||||
#define aps_dport aps_un.apu_tcp.apt_dport
|
||||
#define aps_seqoff aps_un.apu_tcp.apt_seqoff
|
||||
#define aps_ackoff aps_un.apu_tcp.apt_ackoff
|
||||
#define aps_sumoff aps_un.apu_tcp.apt_sumoff
|
||||
#define aps_state aps_un.apu_tcp.apt_state
|
||||
#define aps_after aps_un.apu_tcp.apt_after
|
||||
|
||||
|
||||
typedef struct aproxy {
|
||||
char apr_label[APR_LABELLEN]; /* Proxy label # */
|
||||
char apr_p; /* protocol */
|
||||
int apr_ref; /* +1 per rule referencing it */
|
||||
int apr_flags;
|
||||
int (* apr_init) __P((fr_info_t *, ip_t *, tcphdr_t *,
|
||||
ap_session_t *, struct nat *));
|
||||
int (* apr_inpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
|
||||
ap_session_t *, struct nat *));
|
||||
int (* apr_outpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
|
||||
ap_session_t *, struct nat *));
|
||||
} aproxy_t;
|
||||
|
||||
#define APR_DELETE 1
|
||||
|
||||
|
||||
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
|
||||
extern aproxy_t ap_proxies[];
|
||||
|
||||
extern void ap_unload __P((void));
|
||||
extern void ap_free __P((aproxy_t *));
|
||||
extern void aps_free __P((ap_session_t *));
|
||||
extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
|
||||
extern aproxy_t *ap_match __P((char, char *));
|
||||
|
||||
#endif /* __IP_PROXY_H__ */
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
#if !defined(lint) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
|
||||
static char rcsid[] = "$Id: ip_state.c,v 1.1.1.3 1997/04/03 10:11:29 darrenr Exp $";
|
||||
static char rcsid[] = "$Id: ip_state.c,v 2.0.2.12 1997/05/24 07:34:10 darrenr Exp $";
|
||||
#endif
|
||||
|
||||
#if !defined(_KERNEL) && !defined(KERNEL)
|
||||
@ -19,12 +19,11 @@ static char rcsid[] = "$Id: ip_state.c,v 1.1.1.3 1997/04/03 10:11:29 darrenr Exp
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#if defined(__FreeBSD__) && (__FreeBSD__ >= 3)
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
|
||||
# include <sys/filio.h>
|
||||
# include <sys/fcntl.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/uio.h>
|
||||
#include <sys/protosw.h>
|
||||
@ -35,6 +34,7 @@ static char rcsid[] = "$Id: ip_state.c,v 1.1.1.3 1997/04/03 10:11:29 darrenr Exp
|
||||
#if !defined(__SVR4) && !defined(__svr4__)
|
||||
# include <sys/mbuf.h>
|
||||
#else
|
||||
# include <sys/filio.h>
|
||||
# include <sys/byteorder.h>
|
||||
# include <sys/dditypes.h>
|
||||
# include <sys/stream.h>
|
||||
@ -55,9 +55,10 @@ static char rcsid[] = "$Id: ip_state.c,v 1.1.1.3 1997/04/03 10:11:29 darrenr Exp
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "ip_compat.h"
|
||||
#include "ip_fil.h"
|
||||
#include "ip_state.h"
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
#include "netinet/ip_nat.h"
|
||||
#include "netinet/ip_state.h"
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
@ -67,11 +68,8 @@ static char rcsid[] = "$Id: ip_state.c,v 1.1.1.3 1997/04/03 10:11:29 darrenr Exp
|
||||
ipstate_t *ips_table[IPSTATE_SIZE];
|
||||
int ips_num = 0;
|
||||
ips_stat_t ips_stats;
|
||||
#if SOLARIS
|
||||
#if SOLARIS && defined(_KERNEL)
|
||||
extern kmutex_t ipf_state;
|
||||
# if !defined(_KERNEL)
|
||||
#define bcopy(a,b,c) memmove(b,a,c)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -94,10 +92,27 @@ ips_stat_t *fr_statetstats()
|
||||
}
|
||||
|
||||
|
||||
#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
|
||||
(((s1) == (d2)) && ((d1) == (s2))))
|
||||
#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
|
||||
(s2).s_addr, (d2).s_addr)
|
||||
int fr_state_ioctl(data, cmd, mode)
|
||||
caddr_t data;
|
||||
int cmd;
|
||||
int mode;
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case SIOCGIPST :
|
||||
IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t));
|
||||
break;
|
||||
case FIONREAD :
|
||||
#ifdef IPFILTER_LOG
|
||||
*(int *)data = iplused[IPL_LOGSTATE];
|
||||
#endif
|
||||
break;
|
||||
default :
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new ipstate structure and hang it off the hash table.
|
||||
@ -212,6 +227,8 @@ u_int pass;
|
||||
ipstate_log(is, ISL_NEW);
|
||||
#endif
|
||||
MUTEX_EXIT(&ipf_state);
|
||||
if (fin->fin_fi.fi_fl & FI_FRAG)
|
||||
ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -346,8 +363,9 @@ fr_info_t *fin;
|
||||
is->is_pkts++;
|
||||
is->is_bytes += ip->ip_len;
|
||||
ips_stats.iss_hits++;
|
||||
pass = is->is_pass;
|
||||
MUTEX_EXIT(&ipf_state);
|
||||
return is->is_pass;
|
||||
return pass;
|
||||
}
|
||||
MUTEX_EXIT(&ipf_state);
|
||||
break;
|
||||
@ -364,10 +382,10 @@ fr_info_t *fin;
|
||||
PAIRS(sport, dport, is->is_sport, is->is_dport) &&
|
||||
IPPAIR(src, dst, is->is_src, is->is_dst))
|
||||
if (fr_tcpstate(is, fin, ip, tcp, sport)) {
|
||||
pass = is->is_pass;
|
||||
#ifdef _KERNEL
|
||||
MUTEX_EXIT(&ipf_state);
|
||||
#else
|
||||
int pass = is->is_pass;
|
||||
|
||||
if (tcp->th_flags & TCP_CLOSE) {
|
||||
*isp = is->is_next;
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* (C)opyright 1995 by Darren Reed.
|
||||
* (C)opyright 1995-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
|
||||
* $Id: ip_state.h,v 1.1.1.2 1997/04/03 10:11:33 darrenr Exp $
|
||||
* $Id: ip_state.h,v 2.0.2.9 1997/05/24 07:35:11 darrenr Exp $
|
||||
*/
|
||||
#ifndef __IP_STATE_H__
|
||||
#define __IP_STATE_H__
|
||||
@ -14,6 +14,12 @@
|
||||
#define IPSTATE_SIZE 257
|
||||
#define IPSTATE_MAX 2048 /* Maximum number of states held */
|
||||
|
||||
#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
|
||||
(((s1) == (d2)) && ((d1) == (s2))))
|
||||
#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
|
||||
(s2).s_addr, (d2).s_addr)
|
||||
|
||||
|
||||
typedef struct udpstate {
|
||||
u_short us_sport;
|
||||
u_short us_dport;
|
||||
@ -106,6 +112,14 @@ typedef struct ips_stat {
|
||||
ipstate_t **iss_table;
|
||||
} ips_stat_t;
|
||||
|
||||
|
||||
extern u_long fr_tcpidletimeout;
|
||||
extern u_long fr_tcpclosewait;
|
||||
extern u_long fr_tcplastack;
|
||||
extern u_long fr_tcptimeout;
|
||||
extern u_long fr_tcpclosed;
|
||||
extern u_long fr_udptimeout;
|
||||
extern u_long fr_icmptimeout;
|
||||
extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *,
|
||||
tcphdr_t *, u_short));
|
||||
extern ips_stat_t *fr_statetstats __P((void));
|
||||
@ -115,4 +129,5 @@ extern void fr_timeoutstate __P((void));
|
||||
extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
|
||||
extern void fr_stateunload __P((void));
|
||||
extern void ipstate_log __P((struct ipstate *, u_short));
|
||||
extern int fr_state_ioctl __P((caddr_t, int, int));
|
||||
#endif /* __IP_STATE_H__ */
|
||||
|
16
sys/netinet/ipl.h
Normal file
16
sys/netinet/ipl.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* (C)opyright 1993-1997 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*
|
||||
* @(#)ipl.h 1.21 6/5/96
|
||||
*/
|
||||
|
||||
#ifndef __IPL_H__
|
||||
#define __IPL_H__
|
||||
|
||||
#define IPL_VERSION "IP Filter v3.2alpha7"
|
||||
|
||||
#endif
|
377
sys/netinet/mln_ipl.c
Normal file
377
sys/netinet/mln_ipl.c
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
* (C)opyright 1993,1994,1995 by Darren Reed.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and due credit is given
|
||||
* to the original author and the contributors.
|
||||
*/
|
||||
/*
|
||||
* 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
|
||||
* its own major char number! Way cool patch!
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(__FreeBSD__) && (__FreeBSD__ > 1)
|
||||
# ifdef IPFILTER_LKM
|
||||
# include <osreldate.h>
|
||||
# define ACTUALLY_LKM_NOT_KERNEL
|
||||
# else
|
||||
# include <sys/osreldate.h>
|
||||
# endif
|
||||
#endif
|
||||
#include <sys/systm.h>
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
|
||||
# include <sys/conf.h>
|
||||
# include <sys/kernel.h>
|
||||
# ifdef DEVFS
|
||||
# include <sys/devfsext.h>
|
||||
# endif /*DEVFS*/
|
||||
#endif
|
||||
#include <sys/conf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/mbuf.h>
|
||||
#if BSD >= 199506
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
#if (__FreeBSD_version >= 199511)
|
||||
#include <net/if.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcpip.h>
|
||||
#endif
|
||||
#if (__FreeBSD__ > 1)
|
||||
# include <sys/sysent.h>
|
||||
#endif
|
||||
#include <sys/lkm.h>
|
||||
#include "netinet/ipl.h"
|
||||
#include "netinet/ip_compat.h"
|
||||
#include "netinet/ip_fil.h"
|
||||
|
||||
#ifndef IPL_NAME
|
||||
#define IPL_NAME "/dev/ipl"
|
||||
#endif
|
||||
#define IPL_NAT "/dev/ipnat"
|
||||
#define IPL_STATE "/dev/ipstate"
|
||||
|
||||
#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
|
||||
#define VOP_LEASE LEASE_CHECK
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
extern int lkmenodev __P((void));
|
||||
|
||||
|
||||
static int ipl_unload __P((void));
|
||||
static int ipl_load __P((void));
|
||||
static int ipl_remove __P((void));
|
||||
int xxxinit __P((struct lkm_table *, int, int));
|
||||
|
||||
|
||||
struct cdevsw ipldevsw =
|
||||
{
|
||||
iplopen, /* open */
|
||||
iplclose, /* close */
|
||||
iplread, /* read */
|
||||
(void *)nullop, /* write */
|
||||
iplioctl, /* ioctl */
|
||||
(void *)nullop, /* stop */
|
||||
(void *)nullop, /* reset */
|
||||
(void *)NULL, /* tty */
|
||||
(void *)nullop, /* select */
|
||||
(void *)nullop, /* mmap */
|
||||
NULL /* strategy */
|
||||
};
|
||||
|
||||
#ifdef SYSCTL_INT
|
||||
SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
|
||||
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
|
||||
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
|
||||
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
|
||||
SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
|
||||
&ipl_unreach, 0, "");
|
||||
SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_inited, CTLFLAG_RD,
|
||||
&ipl_inited, 0, "");
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
|
||||
int ipl_major = 0;
|
||||
|
||||
MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
|
||||
|
||||
extern struct cdevsw cdevsw[];
|
||||
extern int vd_unuseddev __P((void));
|
||||
extern int nchrdev;
|
||||
#else
|
||||
int ipl_major = CDEV_MAJOR;
|
||||
|
||||
static struct cdevsw ipl_cdevsw = {
|
||||
iplopen, iplclose, iplread, nowrite, /* 79 */
|
||||
iplioctl, nostop, noreset, nodevtotty,
|
||||
noselect, nommap, nostrategy, "ipl",
|
||||
NULL, -1
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static int iplaction __P((struct lkm_table *, int));
|
||||
|
||||
|
||||
static int iplaction(lkmtp, cmd)
|
||||
struct lkm_table *lkmtp;
|
||||
int cmd;
|
||||
{
|
||||
int i = ipl_major;
|
||||
struct lkm_dev *args = lkmtp->private.lkm_dev;
|
||||
int err = 0;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case LKM_E_LOAD :
|
||||
if (lkmexists(lkmtp))
|
||||
return EEXIST;
|
||||
|
||||
#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
|
||||
for (i = 0; i < nchrdev; i++)
|
||||
if (cdevsw[i].d_open == lkmenodev ||
|
||||
cdevsw[i].d_open == iplopen)
|
||||
break;
|
||||
if (i == nchrdev) {
|
||||
printf("IP Filter: No free cdevsw slots\n");
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
ipl_major = i;
|
||||
args->lkm_offset = i; /* slot in cdevsw[] */
|
||||
#endif
|
||||
printf("IP Filter: loaded into slot %d\n", ipl_major);
|
||||
return ipl_load();
|
||||
break;
|
||||
case LKM_E_UNLOAD :
|
||||
printf("IP Filter: unloaded from slot %d\n", ipl_major);
|
||||
return ipl_unload();
|
||||
case LKM_E_STAT :
|
||||
break;
|
||||
default:
|
||||
err = EIO;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ipl_remove __P((void))
|
||||
{
|
||||
struct nameidata nd;
|
||||
int error;
|
||||
|
||||
NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_NAME, curproc);
|
||||
if ((error = namei(&nd)))
|
||||
return (error);
|
||||
VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(nd.ni_vp);
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
|
||||
|
||||
NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_NAT, curproc);
|
||||
if ((error = namei(&nd)))
|
||||
return (error);
|
||||
VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(nd.ni_vp);
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
|
||||
|
||||
NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_STATE, curproc);
|
||||
if ((error = namei(&nd)))
|
||||
return (error);
|
||||
VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(nd.ni_vp);
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ipl_unload()
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
error = ipldetach();
|
||||
if (!error)
|
||||
error = ipl_remove();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int ipl_load()
|
||||
{
|
||||
struct nameidata nd;
|
||||
struct vattr vattr;
|
||||
int error = 0, fmode = S_IFCHR|0600;
|
||||
|
||||
error = iplattach();
|
||||
if (error)
|
||||
return error;
|
||||
(void) ipl_remove();
|
||||
|
||||
NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, IPL_NAME, curproc);
|
||||
if (error = namei(&nd))
|
||||
return error;
|
||||
if (nd.ni_vp != NULL) {
|
||||
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
||||
if (nd.ni_dvp == nd.ni_vp)
|
||||
vrele(nd.ni_dvp);
|
||||
else
|
||||
vput(nd.ni_dvp);
|
||||
vrele(nd.ni_vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_type = VCHR;
|
||||
vattr.va_mode = (fmode & 07777);
|
||||
vattr.va_rdev = ipl_major<<8;
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, IPL_NAT, curproc);
|
||||
if (error = namei(&nd))
|
||||
return error;
|
||||
if (nd.ni_vp != NULL) {
|
||||
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
||||
if (nd.ni_dvp == nd.ni_vp)
|
||||
vrele(nd.ni_dvp);
|
||||
else
|
||||
vput(nd.ni_dvp);
|
||||
vrele(nd.ni_vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_type = VCHR;
|
||||
vattr.va_mode = (fmode & 07777);
|
||||
vattr.va_rdev = (ipl_major<<8)|1;
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, IPL_STATE, curproc);
|
||||
if (error = namei(&nd))
|
||||
return error;
|
||||
if (nd.ni_vp != NULL) {
|
||||
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
||||
if (nd.ni_dvp == nd.ni_vp)
|
||||
vrele(nd.ni_dvp);
|
||||
else
|
||||
vput(nd.ni_dvp);
|
||||
vrele(nd.ni_vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_type = VCHR;
|
||||
vattr.va_mode = (fmode & 07777);
|
||||
vattr.va_rdev = (ipl_major<<8)|2;
|
||||
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
|
||||
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
|
||||
if (error)
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000)
|
||||
/*
|
||||
* strlen isn't present in 2.1.* kernels.
|
||||
*/
|
||||
size_t strlen(string)
|
||||
char *string;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
for (s = string; *s; s++)
|
||||
;
|
||||
return (size_t)(s - string);
|
||||
}
|
||||
|
||||
|
||||
int xxxinit(lkmtp, cmd, ver)
|
||||
struct lkm_table *lkmtp;
|
||||
int cmd, ver;
|
||||
{
|
||||
DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
|
||||
}
|
||||
#else
|
||||
# ifdef IPFILTER_LKM
|
||||
# include <sys/exec.h>
|
||||
|
||||
MOD_DECL(if_ipl);
|
||||
|
||||
static struct lkm_dev _module = {
|
||||
LM_DEV,
|
||||
LKM_VERSION,
|
||||
IPL_VERSION,
|
||||
CDEV_MAJOR,
|
||||
LM_DT_CHAR,
|
||||
(void *)&ipl_cdevsw
|
||||
};
|
||||
|
||||
int if_ipl(lkmtp, cmd, ver)
|
||||
struct lkm_table *lkmtp;
|
||||
int cmd, ver;
|
||||
{
|
||||
DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
|
||||
}
|
||||
# else
|
||||
|
||||
#ifdef DEVFS
|
||||
static void *ipf_devfs_token[3];
|
||||
#endif
|
||||
static ipl_devsw_installed = 0;
|
||||
|
||||
static void ipl_drvinit __P((void *unused))
|
||||
{
|
||||
dev_t dev;
|
||||
#ifdef DEVFS
|
||||
void **tp = ipf_devfs_token;
|
||||
#endif
|
||||
|
||||
if (!ipl_devsw_installed ) {
|
||||
dev = makedev(CDEV_MAJOR, 0);
|
||||
cdevsw_add(&dev, &ipl_cdevsw, NULL);
|
||||
ipl_devsw_installed = 1;
|
||||
|
||||
#ifdef DEVFS
|
||||
tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF,
|
||||
DV_CHR, 0, 0, 0600,
|
||||
"ipf", IPL_LOGIPF);
|
||||
tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT,
|
||||
DV_CHR, 0, 0, 0600,
|
||||
"ipnat", IPL_LOGNAT);
|
||||
tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE,
|
||||
DV_CHR, 0, 0, 0600,
|
||||
"ipstate", IPL_LOGSTATE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL)
|
||||
# endif /* IPFILTER_LKM */
|
||||
#endif /* _FreeBSD_version */
|
Loading…
Reference in New Issue
Block a user