Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Jun 2002 15:48:48 -0700 (PDT)
From:      Archie Cobbs <archie@dellroad.org>
To:        "Matthew N. Dodd" <winter@jurai.net>
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: m->m_pkthdr.header
Message-ID:  <200206072248.g57MmmE66619@arch20m.dellroad.org>
In-Reply-To: <20020607172612.G42854-100000@sasami.jurai.net> "from Matthew N. Dodd at Jun 7, 2002 05:28:21 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Matthew N. Dodd writes:
> >    - Rejigger the oltr driver to pass its "secret" information using
> >      an auxillary mbuf instead of m->m_pkthdr.header.
> >
> > Any comments/objections?
> 
> Please look at the 'kluge' that NetBSD uses.
> 
> netinet/if_arp.c:
>                         trh = (struct token_header *)M_TRHSTART(m);
> 
> net/if_token.h:
> /*
>  * This is a kludge to get at the token ring mac header and the source route
>  * information after m_adj() has been used on the mbuf.
>  * Note that m is always an mbuf with a packet header.
>  */
> #define M_TRHSTART(m) \
>         (ALIGN(((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf : &(m)->m_pktdat[0]) \
>             + sizeof (struct token_header)) - sizeof(struct token_header))

Thanks for the reference.

This kludge is only slightly better than FreeBSD's kludge and either
way it is the root of the problem. It's simply not valid to rely
on data m_adj'ed out of an mbuf always being there. If somebody
calls m_copypacket() or m_pullup(), you're out of luck.

FYI, the *real* problem I'm trying to solve is that in_arpinput()
stomps all over its mbuf without first checking M_WRITABLE(m).

The patch below would work nicely except it breaks this token ring hack.
I'm tempted to just check it in and let the token ring people fix their
own bug instead of doing it for them.

-Archie

__________________________________________________________________________
Archie Cobbs     *     Packet Design     *     http://www.packetdesign.com

--- /sys/netinet/if_ether.c	Wed Dec 26 09:36:36 2001
+++ netinet/if_ether.c	Fri Jun  7 15:43:30 2002
@@ -675,6 +675,15 @@
 		m_freem(m);
 		return;
 	}
+
+	/* Ensure the mbuf is writable before stomping on it */
+	if (!M_WRITABLE(m)) {
+		if ((m = m_pullup(m, sizeof(struct ether_arp))) == NULL)
+			return;
+		ea = mtod(m, struct ether_arp *);
+	}
+
+	/* Check the target IP address */
 	if (itaddr.s_addr == myaddr.s_addr) {
 		/* I am the target */
 		(void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206072248.g57MmmE66619>