Discussion:
strangeness while using SOCK_RAW
(too old to reply)
Eric Auge
2007-02-07 21:49:37 UTC
Permalink
Hello,

while porting openospfd to netbsd, I'm facing some voodoo
problem that might be obvious but i can't see it.

the application is using socket(PF_INET, SOCK_RAW, IPPROTO_OSPF)
with
[...]
#define IPPROTO_OSPF 89
[...]

the recvfrom() return 80, while the IP header length field return 60 (of
recvfrom()'ed packet).

dump from the application buffer after the recvfrom() :
0x45 0x00 0x3c 0x00 0x73 0x60 0x00 0x00 0x01 0x59 0x3a 0xe5 0x0a 0x09 0x21 0x02
0xe0 0x00 0x00 0x05 0x02 0x01 0x00 0x2c 0x0a 0x09 0x21 0x02 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x02 0x00 0x00 0x01 0x10 0x08 0x79 0x47 0xd5 0xff 0xff 0xff 0x00
0x00 0x05 0x02 0x01 0x00 0x00 0x00 0x28 0x0a 0x09 0x21 0x02 0x00 0x00 0x00 0x00
0x9b 0x5c 0x59 0x99 0xf3 0xe7 0x85 0xc6 0xe7 0xb5 0xcd 0x3b 0x09 0x7f 0xda 0xb4

tcpdump from the same packet :
0x0000: 4500 0050 7360 0000 0159 3ae5 0a09 2102 E..Ps`...Y:...!.
0x0010: e000 0005 0201 002c 0a09 2102 0000 0000 .......,..!.....
0x0020: 0000 0002 0000 0110 0879 47d5 ffff ff00 .........yG.....
0x0030: 0005 0201 0000 0028 0a09 2102 0000 0000 .......(..!.....
0x0040: 9b5c 5999 f3e7 85c6 e7b5 cd3b 097f dab4 .\Y........;....

0x50 (80 bytes) on the wire become suddenly 0x3c (60 bytes) when
send to userland, while tcpdump uses bpf so the packet arrives unmodified.

looks like the kernel is removing 20 from the length value (ip->ip_len) of the
IP header which could be the size of the IP header.
It look strange to me that it changes the size from the IP header without
removing the header itself...

I dont really know where to look in the kernel to check...

any ideas ? can someone enlighten me on this ?

Regards,
Eric.
Eric Auge
2007-02-08 14:59:30 UTC
Permalink
Re Hello,

I found out an answer to that behavior within the kernel :

the default handler for SOCK_RAW and undefined protocols
is located in :
/usr/src/sys/netinet/in_proto.c :
[...]
/* raw wildcard */
{ SOCK_RAW, &inetdomain, 0, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
rip_input, rip_output, rip_ctlinput, rip_ctloutput,
rip_usrreq,
rip_init, 0, 0, 0,
},
[...]

which reference rip_input() function.

/usr/src/sys/netinet/raw_ip.c :
[...]
/*
* XXX Compatibility: programs using raw IP expect ip_len
* XXX to have the header length subtracted, and in host order.
* XXX ip_off is also expected to be host order.
*/
ip->ip_len = ntohs(ip->ip_len) - (ip->ip_hl << 2);
NTOHS(ip->ip_off);
[...]

I don't understand this behavior and comment.

What "programs" using SOCK_RAW, IPPROTO_RAW (the behavior for undefined protos
seems to be similar to the IPPROTO_RAW one) expect the RAW IP header
len(ip->ip_len) to be substracted from the size of the IP header without ripping
off the header itself ...?

Hope someone can enlighten me.

Regards,
Eric.
Post by Eric Auge
Hello,
while porting openospfd to netbsd, I'm facing some voodoo
problem that might be obvious but i can't see it.
the application is using socket(PF_INET, SOCK_RAW, IPPROTO_OSPF)
with
[...]
#define IPPROTO_OSPF 89
[...]
the recvfrom() return 80, while the IP header length field return 60 (of
recvfrom()'ed packet).
0x45 0x00 0x3c 0x00 0x73 0x60 0x00 0x00 0x01 0x59 0x3a 0xe5 0x0a 0x09 0x21 0x02
0xe0 0x00 0x00 0x05 0x02 0x01 0x00 0x2c 0x0a 0x09 0x21 0x02 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x02 0x00 0x00 0x01 0x10 0x08 0x79 0x47 0xd5 0xff 0xff 0xff 0x00
0x00 0x05 0x02 0x01 0x00 0x00 0x00 0x28 0x0a 0x09 0x21 0x02 0x00 0x00 0x00 0x00
0x9b 0x5c 0x59 0x99 0xf3 0xe7 0x85 0xc6 0xe7 0xb5 0xcd 0x3b 0x09 0x7f 0xda 0xb4
0x0000: 4500 0050 7360 0000 0159 3ae5 0a09 2102 E..Ps`...Y:...!.
0x0010: e000 0005 0201 002c 0a09 2102 0000 0000 .......,..!.....
0x0020: 0000 0002 0000 0110 0879 47d5 ffff ff00 .........yG.....
0x0030: 0005 0201 0000 0028 0a09 2102 0000 0000 .......(..!.....
0x0040: 9b5c 5999 f3e7 85c6 e7b5 cd3b 097f dab4 .\Y........;....
0x50 (80 bytes) on the wire become suddenly 0x3c (60 bytes) when
send to userland, while tcpdump uses bpf so the packet arrives unmodified.
looks like the kernel is removing 20 from the length value (ip->ip_len) of the
IP header which could be the size of the IP header.
It look strange to me that it changes the size from the IP header without
removing the header itself...
I dont really know where to look in the kernel to check...
any ideas ? can someone enlighten me on this ?
Regards,
Eric.
Loading...