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.c85
1 files changed, 71 insertions, 14 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index e0a5ed5..02f075b 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.27 2000/10/26 21:20:54 darrenr Exp $";
+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>
@@ -136,6 +136,8 @@ struct frgroup *ipfgroups[3][2];
int fr_flags = IPF_LOGGING;
int fr_active = 0;
int fr_chksrc = 0;
+int fr_minttl = 3;
+int fr_minttllog = 1;
#if defined(IPFILTER_DEFAULT_BLOCK)
int fr_pass = FR_NOMATCH|FR_BLOCK;
#else
@@ -269,6 +271,40 @@ fr_info_t *fin;
switch (p)
{
+#ifdef USE_INET6
+ case IPPROTO_ICMPV6 :
+ {
+ int minicmpsz = sizeof(struct icmp6_hdr);
+ struct icmp6_hdr *icmp6;
+
+ if (fin->fin_dlen > 1) {
+ fin->fin_data[0] = *(u_short *)tcp;
+
+ icmp6 = (struct icmp6_hdr *)tcp;
+
+ switch (icmp6->icmp6_type)
+ {
+ case ICMP6_ECHO_REPLY :
+ case ICMP6_ECHO_REQUEST :
+ minicmpsz = ICMP6ERR_MINPKTLEN;
+ break;
+ case ICMP6_DST_UNREACH :
+ case ICMP6_PACKET_TOO_BIG :
+ case ICMP6_TIME_EXCEEDED :
+ case ICMP6_PARAM_PROB :
+ minicmpsz = ICMP6ERR_IPICMPHLEN;
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (!(plen >= hlen + minicmpsz))
+ fi->fi_fl |= FI_SHORT;
+
+ break;
+ }
+#endif
case IPPROTO_ICMP :
{
int minicmpsz = sizeof(struct icmp);
@@ -747,8 +783,8 @@ int out;
#endif
#ifdef _KERNEL
+ int p, len, drop = 0, logit = 0;
mb_t *mc = NULL;
- int p, len;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
@@ -802,11 +838,17 @@ int out;
break;
/* 96 - enough for complete ICMP error IP header */
case IPPROTO_ICMP:
+ plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
+ break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
-# endif
- plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
+ /*
+ * XXX does not take intermediate header
+ * into account
+ */
+ plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
break;
+# endif
}
up = MIN(hlen + plen, len);
@@ -865,22 +907,37 @@ int out;
# ifdef USE_INET6
if (v == 6) {
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
+ if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
+ ATOMIC_INCL(frstats[0].fr_badttl);
+ if (fr_minttllog)
+ logit = -2;
+ }
} else
# endif
- if (!out && fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
+ if (!out) {
+ if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
+ if (fr_chksrc == 2)
+ logit = -2;
+ } else if (ip->ip_ttl < fr_minttl) {
+ ATOMIC_INCL(frstats[0].fr_badttl);
+ if (fr_minttllog)
+ logit = -3;
+ }
+ }
+ if (drop) {
# ifdef IPFILTER_LOG
- if (fr_chksrc == 2) {
- fin->fin_group = -2;
- pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
- (void) IPLLOG(pass, ip, fin, m);
- }
+ if (logit) {
+ fin->fin_group = logit;
+ pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
+ (void) IPLLOG(pass, ip, fin, m);
+ }
# endif
# if !SOLARIS
- m_freem(m);
+ m_freem(m);
# endif
- return error;
- }
+ return error;
+ }
#endif
pass = fr_pass;
if (fin->fin_fi.fi_fl & FI_SHORT) {
@@ -1401,7 +1458,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.27 2000/10/26 21:20:54 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
OpenPOWER on IntegriCloud