diff options
author | Guido van Rooij <guido@FreeBSD.org> | 2006-08-16 11:51:32 +0000 |
---|---|---|
committer | Guido van Rooij <guido@FreeBSD.org> | 2006-08-16 11:51:32 +0000 |
commit | 0be1832174307c242b42db3dac9d7e762f0c693b (patch) | |
tree | 4b016f8ad91729ff411fb356068d1ae475e0bd91 /sys/contrib/ipfilter/netinet/fil.c | |
parent | fc79eaf127b2927f108bf1971bfb850f7dabea63 (diff) | |
download | src-0be1832174307c242b42db3dac9d7e762f0c693b.tar.gz src-0be1832174307c242b42db3dac9d7e762f0c693b.zip |
Import IP Filter 4.1.13
Notes
Notes:
svn path=/vendor-sys/ipfilter/dist/; revision=161351
Diffstat (limited to 'sys/contrib/ipfilter/netinet/fil.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/fil.c | 210 |
1 files changed, 102 insertions, 108 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index c8c1b55074f4..8f911e6043c2 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -137,7 +137,7 @@ struct file; #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $"; #endif #ifndef _KERNEL @@ -145,12 +145,6 @@ static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 dar # include "ipt.h" # include "bpf-ipf.h" extern int opts; - -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr -#else /* #ifndef _KERNEL */ -# define FR_VERBOSE(verb_pr) -# define FR_DEBUG(verb_pr) #endif /* _KERNEL */ @@ -1972,24 +1966,23 @@ u_32_t pass; * it, except for increasing the hit counter. */ if ((passt & FR_CALLNOW) != 0) { + frentry_t *frs; + ATOMIC_INC64(fr->fr_hits); if ((fr->fr_func != NULL) && - (fr->fr_func != (ipfunc_t)-1)) { - frentry_t *frs; + (fr->fr_func == (ipfunc_t)-1)) + continue; - frs = fin->fin_fr; - fin->fin_fr = fr; - fr = (*fr->fr_func)(fin, &passt); - if (fr == NULL) { - fin->fin_fr = frs; - continue; - } - passt = fr->fr_flags; - fin->fin_fr = fr; - } - } else { + frs = fin->fin_fr; fin->fin_fr = fr; + fr = (*fr->fr_func)(fin, &passt); + if (fr == NULL) { + fin->fin_fr = frs; + continue; + } + passt = fr->fr_flags; } + fin->fin_fr = fr; #ifdef IPFILTER_LOG /* @@ -2021,18 +2014,20 @@ u_32_t pass; (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); if (fr->fr_grp != NULL) { fin->fin_fr = *fr->fr_grp; - pass = fr_scanlist(fin, pass); + passt = fr_scanlist(fin, pass); if (fin->fin_fr == NULL) { fin->fin_rule = rulen; (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); fin->fin_fr = fr; + passt = pass; } if (fin->fin_flx & FI_DONTCACHE) logged = 1; + pass = passt; } - if (pass & FR_QUICK) { + if (passt & FR_QUICK) { /* * Finally, if we've asked to track state for this * packet, set it up. Add state for "quick" rules @@ -2044,6 +2039,7 @@ u_32_t pass; !(fin->fin_flx & FI_STATE)) { int out = fin->fin_out; + fin->fin_fr = fr; if (fr_addstate(fin, NULL, 0) != NULL) { ATOMIC_INCL(frstats[out].fr_ads); } else { @@ -2193,7 +2189,8 @@ u_32_t *passp; if (FR_ISAUTH(pass)) { if (fr_newauth(fin->fin_m, fin) != 0) { #ifdef _KERNEL - fin->fin_m = *fin->fin_mp = NULL; + if ((pass & FR_RETMASK) == 0) + fin->fin_m = *fin->fin_mp = NULL; #else ; #endif @@ -2233,21 +2230,6 @@ u_32_t *passp; } } - /* - * Finally, if we've asked to track state for this packet, set it up. - */ - if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) { - if (fr_addstate(fin, NULL, 0) != NULL) { - ATOMIC_INCL(frstats[out].fr_ads); - } else { - ATOMIC_INCL(frstats[out].fr_bads); - if (FR_ISPASS(pass)) { - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } - } - } - fr = fin->fin_fr; if (passp != NULL) @@ -2313,8 +2295,6 @@ int out; #ifdef USE_INET6 ip6_t *ip6; #endif - SPL_INT(s); - /* * The first part of fr_check() deals with making sure that what goes * into the filtering engine makes some sense. Information about the @@ -2328,6 +2308,8 @@ int out; if ((u_int)ip & 0x3) return 2; +# else + SPL_INT(s); # endif READ_ENTER(&ipf_global); @@ -2493,6 +2475,23 @@ int out; if ((pass & FR_NOMATCH) || (fr == NULL)) fr = fr_firewall(fin, &pass); + /* + * If we've asked to track state for this packet, set it up. + * Here rather than fr_firewall because fr_checkauth may decide + * to return a packet for "keep state" + */ + if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) { + if (fr_addstate(fin, NULL, 0) != NULL) { + ATOMIC_INCL(frstats[out].fr_ads); + } else { + ATOMIC_INCL(frstats[out].fr_bads); + if (FR_ISPASS(pass)) { + pass &= ~FR_CMDMASK; + pass |= FR_BLOCK; + } + } + } + fin->fin_fr = fr; /* @@ -2547,7 +2546,7 @@ int out; RWLOCK_EXIT(&ipf_mutex); - if (pass & (FR_RETRST|FR_RETICMP)) { + if ((pass & FR_RETMASK) != 0) { /* * Should we return an ICMP packet to indicate error * status passing through the packet filter ? @@ -2573,6 +2572,14 @@ int out; ATOMIC_INCL(frstats[1].fr_ret); } } + + /* + * When using return-* with auth rules, the auth code + * takes over disposing of this packet. + */ + if (FR_ISAUTH(pass) && (fin->fin_m != NULL)) { + fin->fin_m = *fin->fin_mp = NULL; + } } else { if (pass & FR_RETRST) fin->fin_error = ECONNRESET; @@ -2786,10 +2793,10 @@ int len; /* */ /* Expects ip_len to be in host byte order when called. */ /* ------------------------------------------------------------------------ */ -u_short fr_cksum(m, ip, l4proto, l4hdr) +u_short fr_cksum(m, ip, l4proto, l4hdr, l3len) mb_t *m; ip_t *ip; -int l4proto; +int l4proto, l3len; void *l4hdr; { u_short *sp, slen, sumsave, l4hlen, *csump; @@ -2814,7 +2821,7 @@ void *l4hdr; if (IP_V(ip) == 4) { #endif hlen = IP_HL(ip) << 2; - slen = ip->ip_len - hlen; + slen = l3len - hlen; sum = htons((u_short)l4proto); sum += htons(slen); sp = (u_short *)&ip->ip_src; @@ -2826,9 +2833,9 @@ void *l4hdr; } else if (IP_V(ip) == 6) { ip6 = (ip6_t *)ip; hlen = sizeof(*ip6); - slen = ntohs(ip6->ip6_plen); + slen = ntohs(l3len); sum = htons((u_short)l4proto); - sum += htons(slen); + sum += slen; sp = (u_short *)&ip6->ip6_src; sum += *sp++; /* ip6_src */ sum += *sp++; @@ -3059,7 +3066,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $ + * $Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -3472,7 +3479,7 @@ int proto, flags; char *memstr(src, dst, slen, dlen) const char *src; char *dst; -int slen, dlen; +size_t slen, dlen; { char *s = NULL; @@ -3760,13 +3767,7 @@ size_t size; caddr_t ca; int err; -# if SOLARIS - err = COPYIN(dst, (caddr_t)&ca, sizeof(ca)); - if (err != 0) - return err; -# else bcopy(dst, (caddr_t)&ca, sizeof(ca)); -# endif err = COPYOUT(src, ca, size); return err; } @@ -4886,7 +4887,7 @@ ipftq_t *ifq; ifq->ifq_next->ifq_pnext = ifq->ifq_pnext; MUTEX_DESTROY(&ifq->ifq_lock); - fr_userifqs--; + ATOMIC_DEC(fr_userifqs); KFREE(ifq); } @@ -4908,8 +4909,6 @@ ipftqent_t *tqe; ipftq_t *ifq; ifq = tqe->tqe_ifq; - if (ifq == NULL) - return; MUTEX_ENTER(&ifq->ifq_lock); @@ -4981,24 +4980,21 @@ ipftqent_t *tqe; tqe->tqe_die = fr_ticks + ifq->ifq_ttl; MUTEX_ENTER(&ifq->ifq_lock); - if (tqe->tqe_next == NULL) { /* at the end already ? */ - MUTEX_EXIT(&ifq->ifq_lock); - return; - } - - /* - * Remove from list - */ - *tqe->tqe_pnext = tqe->tqe_next; - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; + if (tqe->tqe_next != NULL) { /* at the end already ? */ + /* + * Remove from list + */ + *tqe->tqe_pnext = tqe->tqe_next; + tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - /* - * Make it the last entry. - */ - tqe->tqe_next = NULL; - tqe->tqe_pnext = ifq->ifq_tail; - *ifq->ifq_tail = tqe; - ifq->ifq_tail = &tqe->tqe_next; + /* + * Make it the last entry. + */ + tqe->tqe_next = NULL; + tqe->tqe_pnext = ifq->ifq_tail; + *ifq->ifq_tail = tqe; + ifq->ifq_tail = &tqe->tqe_next; + } MUTEX_EXIT(&ifq->ifq_lock); } @@ -5050,46 +5046,44 @@ ipftq_t *oifq, *nifq; * Is the operation here going to be a no-op ? */ MUTEX_ENTER(&oifq->ifq_lock); - if (oifq == nifq && *oifq->ifq_tail == tqe) { - MUTEX_EXIT(&oifq->ifq_lock); - return; - } + if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) { + /* + * Remove from the old queue + */ + *tqe->tqe_pnext = tqe->tqe_next; + if (tqe->tqe_next) + tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; + else + oifq->ifq_tail = tqe->tqe_pnext; + tqe->tqe_next = NULL; - /* - * Remove from the old queue - */ - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else - oifq->ifq_tail = tqe->tqe_pnext; - tqe->tqe_next = NULL; + /* + * If we're moving from one queue to another, release the + * lock on the old queue and get a lock on the new queue. + * For user defined queues, if we're moving off it, call + * delete in case it can now be freed. + */ + if (oifq != nifq) { + tqe->tqe_ifq = NULL; - /* - * If we're moving from one queue to another, release the lock on the - * old queue and get a lock on the new queue. For user defined queues, - * if we're moving off it, call delete in case it can now be freed. - */ - if (oifq != nifq) { - tqe->tqe_ifq = NULL; + (void) fr_deletetimeoutqueue(oifq); - (void) fr_deletetimeoutqueue(oifq); + MUTEX_EXIT(&oifq->ifq_lock); - MUTEX_EXIT(&oifq->ifq_lock); + MUTEX_ENTER(&nifq->ifq_lock); - MUTEX_ENTER(&nifq->ifq_lock); + tqe->tqe_ifq = nifq; + nifq->ifq_ref++; + } - tqe->tqe_ifq = nifq; - nifq->ifq_ref++; + /* + * Add to the bottom of the new queue + */ + tqe->tqe_die = fr_ticks + nifq->ifq_ttl; + tqe->tqe_pnext = nifq->ifq_tail; + *nifq->ifq_tail = tqe; + nifq->ifq_tail = &tqe->tqe_next; } - - /* - * Add to the bottom of the new queue - */ - tqe->tqe_die = fr_ticks + nifq->ifq_ttl; - tqe->tqe_pnext = nifq->ifq_tail; - *nifq->ifq_tail = tqe; - nifq->ifq_tail = &tqe->tqe_next; MUTEX_EXIT(&nifq->ifq_lock); } @@ -5573,7 +5567,7 @@ fr_info_t *fin; if (dosum) sum = fr_cksum(fin->fin_m, fin->fin_ip, - fin->fin_p, fin->fin_dp); + fin->fin_p, fin->fin_dp, fin->fin_plen); #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) } #endif |