summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/fil.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ipfilter/netinet/fil.c')
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c144
1 files changed, 75 insertions, 69 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index 02f075b..c4cd2e0 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -1,15 +1,8 @@
/*
- * Copyright (C) 1993-2000 by Darren Reed.
+ * Copyright (C) 1993-2001 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.
+ * See the IPFILTER.LICENCE file for details on licencing.
*/
-#if !defined(lint)
-static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $";
-#endif
-
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -100,6 +93,11 @@ static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darr
#endif
#include "netinet/ipl.h"
+#if !defined(lint)
+static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $";
+#endif
+
#ifndef _KERNEL
# include "ipf.h"
# include "ipt.h"
@@ -115,12 +113,6 @@ extern int opts;
# if SOLARIS || defined(__sgi)
extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat;
extern kmutex_t ipf_rw;
-# endif
-# if SOLARIS
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \
- ip, qif)
-# else /* SOLARIS */
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
# endif /* SOLARIS || __sgi */
#endif /* _KERNEL */
@@ -226,7 +218,7 @@ fr_info_t *fin;
if (v == 4) {
fin->fin_id = ip->ip_id;
fi->fi_tos = ip->ip_tos;
- off = (ip->ip_off & IP_OFFMASK) << 3;
+ off = (ip->ip_off & IP_OFFMASK);
tcp = (tcphdr_t *)((char *)ip + hlen);
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
fi->fi_src.i6[1] = 0;
@@ -239,7 +231,7 @@ fr_info_t *fin;
fi->fi_daddr = ip->ip_dst.s_addr;
p = ip->ip_p;
fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
- if (ip->ip_off & 0x3fff)
+ if (ip->ip_off & (IP_MF|IP_OFFMASK))
fi->fi_fl |= FI_FRAG;
plen = ip->ip_len;
fin->fin_dlen = plen - hlen;
@@ -260,6 +252,7 @@ fr_info_t *fin;
fi->fi_fl = 0;
plen = ntohs(ip6->ip6_plen);
fin->fin_dlen = plen;
+ plen += sizeof(*ip6);
}
#endif
else
@@ -268,6 +261,7 @@ fr_info_t *fin;
fin->fin_off = off;
fin->fin_plen = plen;
fin->fin_dp = (void *)tcp;
+ off <<= 3;
switch (p)
{
@@ -315,25 +309,34 @@ fr_info_t *fin;
icmp = (icmphdr_t *)tcp;
- if (icmp->icmp_type == ICMP_ECHOREPLY ||
- icmp->icmp_type == ICMP_ECHO)
+ switch (icmp->icmp_type)
+ {
+ case ICMP_ECHOREPLY :
+ case ICMP_ECHO :
+ /* Router discovery messages - RFC 1256 */
+ case ICMP_ROUTERADVERT :
+ case ICMP_ROUTERSOLICIT :
minicmpsz = ICMP_MINLEN;
-
+ break;
/*
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
* 3*timestamp(3*4)
*/
- else if (icmp->icmp_type == ICMP_TSTAMP ||
- icmp->icmp_type == ICMP_TSTAMPREPLY)
+ case ICMP_TSTAMP :
+ case ICMP_TSTAMPREPLY :
minicmpsz = 20;
-
+ break;
/*
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
* mask(4)
*/
- else if (icmp->icmp_type == ICMP_MASKREQ ||
- icmp->icmp_type == ICMP_MASKREPLY)
+ case ICMP_MASKREQ :
+ case ICMP_MASKREPLY :
minicmpsz = 12;
+ break;
+ default :
+ break;
+ }
}
if ((!(plen >= hlen + minicmpsz) && !off) ||
@@ -522,7 +525,7 @@ fr_info_t *fin;
* satisfy the "short" class too).
*/
if (err && (fin->fin_fi.fi_p == IPPROTO_TCP)) {
- if (fin->fin_fi.fi_fl & FI_SHORT)
+ if (fin->fin_fl & FI_SHORT)
return !(ft->ftu_tcpf | ft->ftu_tcpfm);
/*
* Match the flags ? If not, abort this match.
@@ -557,10 +560,7 @@ void *m;
fin->fin_fr = NULL;
fin->fin_rule = 0;
fin->fin_group = 0;
- if (fin->fin_v == 4)
- off = ip->ip_off & IP_OFFMASK;
- else
- off = 0;
+ off = fin->fin_off;
pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
@@ -787,7 +787,7 @@ int out;
mb_t *mc = NULL;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
- char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
+ char hbuf[128];
# endif
int up;
@@ -812,6 +812,9 @@ int out;
# ifdef USE_INET6
if (v == 6) {
len = ntohs(((ip6_t*)ip)->ip6_plen);
+ if (!len)
+ return -1; /* potential jumbo gram */
+ len += sizeof(ip6_t);
p = ((ip6_t *)ip)->ip6_nxt;
} else
# endif
@@ -820,7 +823,8 @@ int out;
len = ip->ip_len;
}
- if ((p == IPPROTO_TCP || p == IPPROTO_UDP || p == IPPROTO_ICMP
+ if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
+ (v == 4 && p == IPPROTO_ICMP)
# ifdef USE_INET6
|| (v == 6 && p == IPPROTO_ICMPV6)
# endif
@@ -889,13 +893,6 @@ int out;
# endif
#endif /* _KERNEL */
- /*
- * Be careful here: ip_id is in network byte order when called
- * from ip_output()
- */
- if ((out) && (v == 4))
- ip->ip_id = ntohs(ip->ip_id);
-
changed = 0;
fin->fin_ifp = ifp;
fin->fin_v = v;
@@ -940,15 +937,12 @@ int out;
}
#endif
pass = fr_pass;
- if (fin->fin_fi.fi_fl & FI_SHORT) {
+ if (fin->fin_fl & FI_SHORT) {
ATOMIC_INCL(frstats[out].fr_short);
}
READ_ENTER(&ipf_mutex);
- if (fin->fin_fi.fi_fl & FI_SHORT)
- ATOMIC_INCL(frstats[out].fr_short);
-
/*
* Check auth now. This, combined with the check below to see if apass
* is 0 is to ensure that we don't count the packet twice, which can
@@ -972,8 +966,18 @@ int out;
}
}
- if (apass || (!(fr = ipfr_knownfrag(ip, fin)) &&
- !(fr = fr_checkstate(ip, fin)))) {
+ if (!apass) {
+ if ((fin->fin_fl & FI_FRAG) == FI_FRAG)
+ fr = ipfr_knownfrag(ip, fin);
+ if (!fr && !(fin->fin_fl & FI_SHORT))
+ fr = fr_checkstate(ip, fin);
+ if (fr != NULL)
+ pass = fr->fr_flags;
+ if (fr && (pass & FR_LOGFIRST))
+ pass &= ~(FR_LOGFIRST|FR_LOG);
+ }
+
+ if (apass || !fr) {
/*
* If a packet is found in the auth table, then skip checking
* the access lists for permission but we do need to consider
@@ -1008,22 +1012,26 @@ int out;
ATOMIC_INCL(frstats[out].fr_nom);
}
}
- fr = fin->fin_fr;
} else
pass = apass;
+ fr = fin->fin_fr;
/*
* If we fail to add a packet to the authorization queue,
* then we drop the packet later. However, if it was added
* then pretend we've dropped it already.
*/
- if ((pass & FR_AUTH))
- if (fr_newauth((mb_t *)m, fin, ip) != 0)
+ if ((pass & FR_AUTH)) {
+ if (fr_newauth((mb_t *)m, fin, ip) != 0) {
#ifdef _KERNEL
m = *mp = NULL;
#else
;
#endif
+ error = 0;
+ } else
+ error = ENOSPC;
+ }
if (pass & FR_PREAUTH) {
READ_ENTER(&ipf_auth);
@@ -1038,7 +1046,7 @@ int out;
fin->fin_fr = fr;
if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) {
- if (fin->fin_fi.fi_fl & FI_FRAG) {
+ if (fin->fin_fl & FI_FRAG) {
if (ipfr_newfrag(ip, fin, pass) == -1) {
ATOMIC_INCL(frstats[out].fr_bnfr);
} else {
@@ -1116,9 +1124,6 @@ logit:
}
#endif /* IPFILTER_LOG */
- if ((out) && (v == 4))
- ip->ip_id = htons(ip->ip_id);
-
#ifdef _KERNEL
/*
* Only allow FR_DUP to work if a rule matched - it makes no sense to
@@ -1160,7 +1165,7 @@ logit:
send_icmp_err(ip, ICMP_UNREACH, fin, dst);
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ !(fin->fin_fl & FI_SHORT)) {
if (send_reset(ip, fin) == 0) {
ATOMIC_INCL(frstats[1].fr_ret);
}
@@ -1173,7 +1178,7 @@ logit:
verbose("- forged ICMP unreachable sent\n");
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
+ !(fin->fin_fl & FI_SHORT)) {
verbose("- TCP RST sent\n");
ATOMIC_INCL(frstats[1].fr_ret);
}
@@ -1202,15 +1207,17 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(m, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(mc, fin, &fr->fr_dif);
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (void) ipfr_fastroute(m, mp, fin, fdp);
+
+ if (mc != NULL)
+ (void) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
}
- if (!(pass & FR_PASS) && m)
+
+ if (!(pass & FR_PASS) && m) {
m_freem(m);
+ m = *mp = NULL;
+ }
# ifdef __sgi
else if (changed && up && m)
m_copyback(m, 0, up, hbuf);
@@ -1221,12 +1228,11 @@ logit:
frdest_t *fdp = &fr->fr_tif;
if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(ip, m, mp, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(ip, mc, mp, fin, &fr->fr_dif);
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ (void) ipfr_fastroute(ip, m, mp, fin, fdp);
+
+ if (mc != NULL)
+ (void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
}
# endif /* !SOLARIS */
return (pass & FR_PASS) ? 0 : error;
@@ -1458,7 +1464,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.39 2001/07/18 13:30:32 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1907,7 +1913,7 @@ void frsync()
ip_statesync(ifp);
}
ip_natsync((struct ifnet *)-1);
-# endif
+# endif /* !SOLARIS */
WRITE_ENTER(&ipf_mutex);
frsynclist(ipacct[0][fr_active]);
OpenPOWER on IntegriCloud