diff options
author | darrenr <darrenr@FreeBSD.org> | 2007-06-04 02:54:36 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 2007-06-04 02:54:36 +0000 |
commit | a33069b5324be7fb6d5c0a0d785bb0e10eb0aa36 (patch) | |
tree | 28d6fb710df6e0ddec4933e69ec29d2ecd78a134 /sys/contrib/ipfilter/netinet/ip_fil_freebsd.c | |
parent | 1dd4fa592dfed4984b91696b53e64e8c075f63eb (diff) | |
download | FreeBSD-src-a33069b5324be7fb6d5c0a0d785bb0e10eb0aa36.zip FreeBSD-src-a33069b5324be7fb6d5c0a0d785bb0e10eb0aa36.tar.gz |
Merge IPFilter 4.1.23 back to HEAD
See src/contrib/ipfilter/HISTORY for details of changes since 4.1.13
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_fil_freebsd.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_fil_freebsd.c | 248 |
1 files changed, 82 insertions, 166 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c index 64421e0..aeefb03 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.32 2006/03/25 13:03:01 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.46 2007/05/11 13:41:53 darrenr Exp $"; #endif #if defined(KERNEL) || defined(_KERNEL) @@ -57,11 +57,18 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.32 2006/03/25 13 #endif #include <sys/protosw.h> #include <sys/socket.h> -#include <sys/selinfo.h> +#if __FreeBSD_version >= 500043 +# include <sys/selinfo.h> +#else +# include <sys/select.h> +#endif #include <net/if.h> #if __FreeBSD_version >= 300000 # include <net/if_var.h> +# if __FreeBSD_version >= 500043 +# include <net/netisr.h> +# endif # if !defined(IPFILTER_LKM) # include "opt_ipfilter.h" # endif @@ -126,7 +133,7 @@ static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **)); # ifdef USE_MUTEXES ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; -ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ipf_frcache; +ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ipf_frcache, ipf_tokens; ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; # endif int ipf_locks_done = 0; @@ -193,7 +200,7 @@ char *s; #endif /* IPFILTER_LKM */ -int iplattach() +int ipfattach() { #ifdef USE_SPL int s; @@ -215,11 +222,9 @@ int iplattach() } MUTEX_INIT(&ipf_rw, "ipf rw mutex"); - RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex"); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); - RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock"); RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); + RWLOCK_INIT(&ipf_tokens, "ipf token rwlock"); ipf_locks_done = 1; if (fr_initialise() < 0) { @@ -326,7 +331,7 @@ pfil_error: * Disable the filter by removing the hooks from the IP input/output * stream. */ -int ipldetach() +int ipfdetach() { #ifdef USE_SPL int s; @@ -420,10 +425,8 @@ int ipldetach() if (ipf_locks_done == 1) { MUTEX_DESTROY(&ipf_timeoutlock); MUTEX_DESTROY(&ipf_rw); - RW_DESTROY(&ipf_mutex); - RW_DESTROY(&ipf_frcache); RW_DESTROY(&ipf_ipidfrag); - RW_DESTROY(&ipf_global); + RW_DESTROY(&ipf_tokens); ipf_locks_done = 0; } @@ -441,8 +444,14 @@ int iplioctl(dev, cmd, data, mode , p) # if (__FreeBSD_version >= 500024) struct thread *p; +# if (__FreeBSD_version >= 500043) +# define p_uid td_ucred->cr_ruid +# else +# define p_uid t_proc->p_cred->p_ruid +# endif # else struct proc *p; +# define p_uid p_cred->p_ruid # endif /* __FreeBSD_version >= 500024 */ # else ) @@ -456,11 +465,8 @@ ioctlcmd_t cmd; caddr_t data; int mode; { -#ifdef USE_SPL - int s; -#endif - int error = 0, unit = 0, tmp; - friostat_t fio; + int error = 0, unit = 0; + SPL_INT(s); #if (BSD >= 199306) && defined(_KERNEL) if ((securelevel >= 3) && (mode & FWRITE)) @@ -481,159 +487,16 @@ int mode; } SPL_NET(s); - if (fr_running > 0) - READ_ENTER(&ipf_global); + READ_ENTER(&ipf_global); - error = fr_ioctlswitch(unit, data, cmd, mode); + error = fr_ioctlswitch(unit, data, cmd, mode, p->p_uid, p); if (error != -1) { RWLOCK_EXIT(&ipf_global); SPL_X(s); return error; } - error = 0; - - switch (cmd) - { - case FIONREAD : -#ifdef IPFILTER_LOG - BCOPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, - sizeof(iplused[IPL_LOGIPF])); -#endif - break; - case SIOCFRENB : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - if (tmp) { - if (fr_running > 0) - error = 0; - else - error = iplattach(); - if (error == 0) - fr_running = 1; - else - (void) ipldetach(); - } else { - if (fr_running <= 0) - error = 0; - else - error = ipldetach(); - if (error == 0) - fr_running = -1; - } - } - break; - case SIOCIPFSET : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - case SIOCIPFGETNEXT : - case SIOCIPFGET : - error = fr_ipftune(cmd, data); - break; - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - BCOPYIN(data, &fr_flags, sizeof(fr_flags)); - break; - case SIOCGETFF : - BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); - break; - case SIOCFUNCL : - error = fr_resolvefunc(data); - break; - case SIOCINAFR : - case SIOCRMAFR : - case SIOCADAFR : - case SIOCZRLST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, fr_active, 1); - break; - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, 1 - fr_active, 1); - break; - case SIOCSWAPA : - if (!(mode & FWRITE)) - error = EPERM; - else { - bzero((char *)frcache, sizeof(frcache[0]) * 2); - *(u_int *)data = fr_active; - fr_active = 1 - fr_active; - } - break; - case SIOCGETFS : - fr_getstat(&fio); - error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); - break; - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = fr_zerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 4, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#ifdef USE_INET6 - case SIOCIPFL6 : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 6, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#endif - case SIOCSTLCK : - BCOPYIN(data, &tmp, sizeof(tmp)); - fr_state_lock = tmp; - fr_nat_lock = tmp; - fr_frag_lock = tmp; - fr_auth_lock = tmp; - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); - break; - case SIOCFRSYN : - if (!(mode & FWRITE)) - error = EPERM; - else { - frsync(NULL); - } - break; - default : - error = EINVAL; - break; - } - if (fr_running > 0) - if (mtx_owned(&(&ipf_global)->ipf_lk)) - RWLOCK_EXIT(&ipf_global); + RWLOCK_EXIT(&ipf_global); SPL_X(s); return error; @@ -760,6 +623,9 @@ register struct uio *uio; { u_int xmin = GET_MINOR(dev); + if (fr_running < 1) + return EIO; + if (xmin < 0) return ENXIO; @@ -796,6 +662,9 @@ dev_t dev; register struct uio *uio; { + if (fr_running < 1) + return EIO; + #ifdef IPFILTER_SYNC if (GET_MINOR(dev) == IPL_LOGSYNC) return ipfsync_write(uio); @@ -1153,7 +1022,7 @@ void # endif iplinit() { - if (iplattach() != 0) + if (ipfattach() != 0) printf("IP Filter failed to attach\n"); ip_init(); } @@ -1264,9 +1133,11 @@ frdest_t *fdp; /* * For input packets which are being "fastrouted", they won't * go back through output filtering and miss their chance to get - * NAT'd and counted. + * NAT'd and counted. Duplicated packets aren't considered to be + * part of the normal packet stream, so do not NAT them or pass + * them through stateful checking, etc. */ - if (fin->fin_out == 0) { + if ((fdp != &fr->fr_dif) && (fin->fin_out == 0)) { sifp = fin->fin_ifp; fin->fin_ifp = ifp; fin->fin_out = 1; @@ -1275,7 +1146,8 @@ frdest_t *fdp; if (!fr || !(fr->fr_flags & FR_RETMASK)) { u_32_t pass; - (void) fr_checkstate(fin, &pass); + if (fr_checkstate(fin, &pass) != NULL) + fr_statederef((ipstate_t **)&fin->fin_state); } switch (fr_checknatout(fin, NULL)) @@ -1283,6 +1155,7 @@ frdest_t *fdp; case 0 : break; case 1 : + fr_natderef((nat_t **)&fin->fin_nat); ip->ip_sum = 0; break; case -1 : @@ -1742,3 +1615,46 @@ int len; fin->fin_flx |= FI_COALESCE; return ip; } + + +int ipf_inject(fin, m) +fr_info_t *fin; +mb_t *m; +{ + int error = 0; + + if (fin->fin_out == 0) { +#if (__FreeBSD_version >= 501000) + netisr_dispatch(NETISR_IP, m); +#else + struct ifqueue *ifq; + + ifq = &ipintrq; + +# ifdef _IF_QFULL + if (_IF_QFULL(ifq)) +# else + if (IF_QFULL(ifq)) +# endif + { +# ifdef _IF_DROP + _IF_DROP(ifq); +# else + IF_DROP(ifq); +# endif + FREE_MB_T(m); + error = ENOBUFS; + } else { + IF_ENQUEUE(ifq, m); + } +#endif + } else { +#if (__FreeBSD_version >= 470102) + error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); +#else + error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); +#endif + } + + return error; +} |