Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netmpls do some rudimentary checks on ip4 header before ...



details:   https://anonhg.NetBSD.org/src/rev/eb4b30446cc5
branches:  trunk
changeset: 756050:eb4b30446cc5
user:      kefren <kefren%NetBSD.org@localhost>
date:      Mon Jul 05 09:54:26 2010 +0000

description:
do some rudimentary checks on ip4 header before passing packet to
mpls_icmp_error

diffstat:

 sys/netmpls/mpls_ttl.c |  56 +++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 49 insertions(+), 7 deletions(-)

diffs (93 lines):

diff -r 09c024a0bffc -r eb4b30446cc5 sys/netmpls/mpls_ttl.c
--- a/sys/netmpls/mpls_ttl.c    Mon Jul 05 06:54:48 2010 +0000
+++ b/sys/netmpls/mpls_ttl.c    Mon Jul 05 09:54:26 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mpls_ttl.c,v 1.2 2010/07/02 12:25:54 kefren Exp $ */
+/*     $NetBSD: mpls_ttl.c,v 1.3 2010/07/05 09:54:26 kefren Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpls_ttl.c,v 1.2 2010/07/02 12:25:54 kefren Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpls_ttl.c,v 1.3 2010/07/05 09:54:26 kefren Exp $");
 
 #include "opt_inet.h"
 #include "opt_mpls.h"
@@ -160,10 +160,12 @@
        union mpls_shim ms;
 } __packed;
 
-static void mpls_icmp_error(struct mbuf*, int, int, n_long, int, union mpls_shim *);
+static void mpls_icmp_error(struct mbuf *, int, int, n_long, int,
+       union mpls_shim *);
+static bool ip4_check(struct mbuf *);
 
 /*
- * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
+ * Reference: http://tools.ietf.org/html/rfc4950
  * This should be in sync with icmp_error() in sys/netinet/ip_icmp.c
  */
 
@@ -326,6 +328,45 @@
 
 }
 
+static bool
+ip4_check(struct mbuf *m)
+{
+       struct ip *iph;
+       int hlen, len;
+
+       if (m->m_len < sizeof(struct ip) &&
+           (m = m_pullup(m, sizeof(struct ip))) == NULL)
+               return false;
+
+       iph = mtod(m, struct ip *);
+
+       if (iph->ip_v != IPVERSION)
+               goto freeit;
+       hlen = iph->ip_hl << 2;
+       if (hlen < sizeof(struct ip))
+               goto freeit;
+       if (hlen > m->m_len) {
+               if ((m = m_pullup(m, hlen)) == NULL)
+                       return false;
+               iph = mtod(m, struct ip *);
+       }
+       if (IN_MULTICAST(iph->ip_src.s_addr) ||
+           (ntohl(iph->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
+           (ntohl(iph->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
+           in_cksum(m, hlen) != 0)
+               goto freeit;
+
+       len = ntohs(iph->ip_len);
+       if (len < hlen || m->m_pkthdr.len < len)
+               goto freeit;
+
+       return true;
+freeit:
+       m_freem(m);
+       return false;
+
+}
+
 #endif /* INET */
 
 struct mbuf *
@@ -368,9 +409,10 @@
                        bossh.s_addr = ntohl(mtod(m, union mpls_shim *)->s_addr);
                        m_adj(m, sizeof(union mpls_shim));
                }
-
-               mpls_icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS,
-                   0, 0, &top_shim);
+               
+               if (ip4_check(m) == true)
+                       mpls_icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS,
+                           0, 0, &top_shim);
 #else
                m_freem(m);
 #endif



Home | Main Index | Thread Index | Old Index