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:11:33 -0700
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"
In this case, protocol=AF_INET, ifnet_hdrlen(interface)=14, so I'm calling:
mbuf_outbound_finalize(mbuf=0x1d0cf000, 2, 14);
>From gdb, mbuf_walk on 0x1d0cf000 displays:
(gdb) mbuf_walk 0x1d0cf000
1: 0x1d0cf000 [len 14, type 1, total 14]
2: 0x1d0d0100 [len 193, type 1, total 207]
At the point where the error message is displayed (line 1695 of
ip_output.c, xnu-1228.12.14), a dump of "m" looks right --
(gdb) p *m
m_hdr = {
mh_next = 0x0,
mh_nextpkt = 0x0,
mh_len = 193,
mh_data = 0x1d04123c "E",
mh_type = 1,
mh_flags = 64
},
M_dat = {
MH = {
MH_pkthdr = {
len = 193,
rcvif = 0x0,
header = 0x0,
csum_flags = 4,
csum_data = 6,
reserved0 = 0x0,
vlan_tag = 0,
socket_id = 59566,
tags = {
slh_first = 0x0
}
},
But that's not what in_delayed_cksum_offset() is checking against at
line 1692 of ip_output.c -- the check is against "m0":
1692 if (ip_len != (m0->m_pkthdr.len - ip_offset)) {
(gdb) p *m0
$15 = {
m_hdr = {
mh_next = 0x1d041200,
mh_nextpkt = 0x0,
mh_len = 14,
mh_data = 0x1d0fe9f0 "",
mh_type = 1,
mh_flags = 66
},
M_dat = {
MH = {
MH_pkthdr = {
len = 207,
rcvif = 0x0,
header = 0x0,
csum_flags = 4,
csum_data = 6,
reserved0 = 0x0,
vlan_tag = 0,
socket_id = 59566,
tags = {
slh_first = 0x0
}
},
Which is going to fail because m0's length is the total length of the
mbuf list, not the length of the packet we've skipped ahead to in the
block at the top of the function (line 1652 of ip_output.c.)
So it seems like the check on line 1692:
if (ip_len != (m0->m_pkthdr.len - ip_offset))
might work if it were something like:
if (ip_len != (m->m_pkthdr.len - ip_offset))
This is just a guess since I haven't built the kernel and tested.
Thanks again for your questions and responses, and for wading through
my long posting.
regards, Brendan
On Mon, Jul 27, 2009 at 5:08 AM, Andrew Gallatin<email@hidden> wrote:
> Brendan Creane wrote:
>>
>> Greetings. My interface filter nke is seeing outbound AF_INET packets with
>> an ip_len that doesn't account for the protocol header. For example, for an
>> interface that expects the 14 byte eth header at the beginning of the
>> outbound packet, ip_len is 14 bytes less than the mbuf length. When I call
>> mbuf_outbound_finalize(), in_delayed_cksum_offset bails on processing the
>> packet and reports "in_delayed_cksum_offset: ip_len (XX) doesn't match
>> actual length YY." This seems to only happen for udp packets, not tcp
>> packets.
>> I'd prefer to not clutter up the system log with this message. My question
>> is whether I should do some packet verification before calling
>> mbuf_outbound_finalize, or if this is a problem either with the entity
>> creating the packet, or with in_delayed_cksum_offset().
>
> It might be helpful if you could post the exact message you're
> seeing from in_delayed_cksum_offset(), as well as the
> offset you're passing to mbuf_outbound_finalize(), and some
> ancillary data (like what the mbuf chain looks like, the length of
> each mbuf, and the pkthdr len). It would
> be really helpful if you could attach a raw tcpdump capture file
> with just the problematic frame.
>
> Drew
>
_______________________________________________
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