Print this page
9832 Original bug discovered as 9560 has friends IPv4 packets coming in as IPv6 creating chaos
Reviewed by: Robert Mustacchi <rm@joyent.com>

@@ -20,10 +20,12 @@
  */
 
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2019, Joyent, Inc.
  */
 
 #include <sys/strsun.h>
 #include <sys/sdt.h>
 #include <sys/mac.h>

@@ -1952,10 +1954,12 @@
 
         switch (sap) {
         case ETHERTYPE_IP: {
                 ipha_t  *ipha = (ipha_t *)l3_start;
 
+                if (IPH_HDR_VERSION(ipha) != IPV4_VERSION)
+                        return (EINVAL);
                 if (PKT_TOO_SMALL(s, l3_start + IP_SIMPLE_HDR_LENGTH))
                         return (ENOBUFS);
 
                 l3info->l3_hdrsize = IPH_HDR_LENGTH(ipha);
                 l3info->l3_protocol = ipha->ipha_protocol;

@@ -1967,15 +1971,20 @@
         case ETHERTYPE_IPV6: {
                 ip6_t           *ip6h = (ip6_t *)l3_start;
                 ip6_frag_t      *frag = NULL;
                 uint16_t        ip6_hdrlen;
                 uint8_t         nexthdr;
+                int             errno;
 
-                if (!mac_ip_hdr_length_v6(ip6h, s->fs_mp->b_wptr, &ip6_hdrlen,
-                    &nexthdr, &frag)) {
-                        return (ENOBUFS);
-                }
+                errno = mac_ip_hdr_length_v6(ip6h, s->fs_mp->b_wptr,
+                    &ip6_hdrlen, &nexthdr, &frag);
+                /*
+                 * ENOBUFS is not ENOSPC, but the semantics are the
+                 * same for this caller.
+                 */
+                if (errno != 0)
+                        return (errno == ENOSPC ? ENOBUFS : errno);
                 l3info->l3_hdrsize = ip6_hdrlen;
                 l3info->l3_protocol = nexthdr;
                 l3info->l3_version = IPV6_VERSION;
                 l3info->l3_fragmented = (frag != NULL);
                 break;