Subject: Re: strangeness while using SOCK_RAW
To: None <tech-net@netbsd.org>
From: Eric Auge <eau@phear.org>
List: tech-net
Date: 02/08/2007 15:59:30
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig7D72C34079BE1F6C35CA3B58
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

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_LAST=
HDR,
  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 =3D 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 p=
rotos
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.

Eric Auge wrote:
> Hello,
>=20
> while porting openospfd to netbsd, I'm facing some voodoo
> problem that might be obvious but i can't see it.
>=20
> the application is using socket(PF_INET, SOCK_RAW, IPPROTO_OSPF)
> with
> [...]
> #define IPPROTO_OSPF             89
> [...]
>=20
> the recvfrom() return 80, while the IP header length field return 60 (o=
f
> recvfrom()'ed packet).
>=20
> 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
>=20
> 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........;....
>=20
> 0x50 (80 bytes) on the wire become suddenly 0x3c (60 bytes) when
> send to userland, while tcpdump uses bpf so the packet arrives unmodifi=
ed.
>=20
> 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 witho=
ut
> removing the header itself...
>=20
> I dont really know where to look in the kernel to check...
>=20
> any ideas ? can someone enlighten me on this ?
>=20
> Regards,
> Eric.
>=20


--------------enig7D72C34079BE1F6C35CA3B58
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (NetBSD)

iD8DBQFFyzrVSdZNA80H8MYRAhc7AKCvM+1nT7PMtbpvBfzDCUZDQlWzUQCfbdgK
CUW5flSqCZMZfOY2bdIMzrU=
=k+7V
-----END PGP SIGNATURE-----

--------------enig7D72C34079BE1F6C35CA3B58--