Re: mbuf_outbound_finalize() reports packet length is less than mbuf length
Re: mbuf_outbound_finalize() reports packet length is less than mbuf length
- Subject: Re: mbuf_outbound_finalize() reports packet length is less than mbuf length
- From: Brendan Creane <email@hidden>
- Date: Mon, 27 Jul 2009 10:37:06 -0700
I think the host order ip_len bug is fixed in xnu-1228.12.14, at line
1682 of ip_output.c, it's trying both the network and host order of
ip_len:
/*
* We could be in the context of an IP or interface filter; in the
* former case, ip_len would be in host (correct) order while for
* the latter it would be in network order. Because of this, we
* attempt to interpret the length field by comparing it against
* the actual packet length. If the comparison fails, byte swap
* the length and check again. If it still fails, then the packet
* is bogus and we give up.
*/
ip_len = ip->ip_len;
if (ip_len != (m0->m_pkthdr.len - ip_offset)) {
ip_len = SWAP16(ip_len);
if (ip_len != (m0->m_pkthdr.len - ip_offset)) {
printf("in_delayed_cksum_offset: ip_len %d (%d) "
"doesn't match actual length %d\n", ip->ip_len,
ip_len, (m0->m_pkthdr.len - ip_offset));
return;
}
}
regards, Brendan
On Mon, Jul 27, 2009 at 10:25 AM, Kevin Brock<email@hidden> wrote:
> Brendan Creane wrote:
>>
>> Thanks for your response Drew. My code fragment is:
>>
>> /*============================================*/
>> errno_t
>> drv::Filter::enet_output_func(ifnet_t interface, protocol_family_t
>> protocol, mbuf_t *first_buf)
>> {
>> if (protocol != AF_INET && protocol != AF_UNSPEC)
>> return KERN_SUCCESS;
>>
>> mbuf_t m = *first_buf;
>>
>> // check whether we've seen this packet previously
>> if (check_mbuf_tag(m, OUTBOUND_DONE))
>> return KERN_SUCCESS;
>>
>> mbuf_outbound_finalize(m, protocol, ifnet_hdrlen(interface));
>> // process the packet ...
>> /*============================================*/
>>
>> The exact message from in_delayed_cksum_offset() is:
>> "in_delayed_cksum_offset: ip_len 49408 (193) doesn't match actual length
>> 207"
>>
>>
>
> You need to byte swap the IP length field. mbuf_outbound_finalize does its
> length calculations in host byte order, not network byte order.
> This bug's been in there for a *long* time, and they still haven't bothered
> to document or fix it...
>
> Here's the code that works for me (I've cut out error checking for brevity):
>
> struct ip* ip_hdr = get_ip_ptr(mbuf, ip_offset);
> ip_hdr->ip_len = htons(ip_hdr->ip_len);
> mbuf_outbound_finalize(mbuf, AF_INET, ip_offset);
> // Get it again in case things were reorganized?
> ip_hdr = get_ip_ptr(mbuf, ip_offset);
> ip_hdr->ip_len = htons(ip_hdr->ip_len);
>
> Where get_ip_ptr is my own function that gets the pointer to the IP header,
> and the protocol in my case is always AF_INET...
>
> Kevin
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden