Subject: Re: strangeness while using SOCK_RAW
To: Eric Auge <eau@phear.org>
From: Brian Buhrow <buhrow@lothlorien.nfbcal.org>
List: tech-kern
Date: 02/09/2007 11:04:33
	Hello.  Well, I'm not sure why the choice was made, but I see that
FreeBSD and NetBSD both set the ip header len equal to the size of the
packet, minus the IP header itself, but recvfrom() returns the total number
of bytes delivered, including the ip header.  I bet this is historical
behavior, and I'm pretty sure it works this way across all the BSD socket
implementations, including SunOS4 and Solaris, and even sysVish
environments like SCO OpenServer.  If OpenBSD changed this behavior,
then they're the exception.  However, as far as I can tell, most modern
versions of *nix return the actual bytes delivered in the return value of
recvfrom, but the ip_len field in the returned header only reflects the
size of the packet, minus the header.  A bit strange, I agree, but that's
how it appears to work.

Hope that helps.
-Brian
On Feb 9,  6:58pm, Eric Auge wrote:
} Subject: Re: strangeness while using SOCK_RAW
} This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
} --------------enig0380B9FE5FAC750A7B98F1D6
} Content-Type: text/plain; charset=ISO-8859-1
} Content-Transfer-Encoding: quoted-printable
} 
} Hello Brian,
} 
} I didn't say I needed to change something in the kernel,
} OpenOSPFD is already ported and works perfectly (as said in my previous m=
} ail),
} if you read carefully what the problem is you will understand what
} my question is.
} 
} Thanks anyway,
} Regards,
} Eric.
} 
} Brian Buhrow wrote:
} > 	Hello.  If it helps, here is some user-space code I'm using under
} > NetBSD and FreeBSD which uses raw sockets.  With raw sockets, you get t=
} he
} > IP header from the kernel on reception, but it's not required that you
} > provide a full header on transmission.  In fact, you can't, unless you =
} use
} > the setsockopt, IP_HDRINCL, to tell the kernel that you, the user, will=
} 
} > provide the full IP header for packets you send.  Even then, the kernel=
} 
} > will calculate the checksum for you, and set the len field on the packe=
} t
} > before it puts it on the wire.
} > 	I very much doubt you need to change things in the kernel to get
} > openospfd to run under NetBSD, and things should be pretty close to wor=
} king
} > with no changes at all to the application code.
} >=20
} > Here are my snippets.
} >=20
} > I hope they help.
} >=20
} > [code to send data to the network]
} > 	bzero(&sin, sizeof(sin));
} > 	sin.sin_family =3D AF_INET;
} > 	sinlen =3D sizeof(sin);
} > 	intlen =3D sizeof(int);
} > [...]
} > 			if (sendto(tunnelsock, inbuf, bytesread, 0,=20
} > 			(struct sockaddr *)&sin, sinlen) !=3D bytesread) {
} > 				syslog(LOG_CRIT,"function: sendto: %m");
} > 			}
} >=20
} > [...]
} >=20
} > [Code to receive data from the network using raw sockets]
} > 		bzero(&sin, sizeof(sin));
} > 		sin.sin_family =3D AF_INET;
} > 		sin.sin_addr.s_addr =3D htonl(INADDR_ANY);
} > 		sin.sin_port =3D htons(0);
} > 		sinlen =3D sizeof(sin);
} > 		if (bind(tunnelsock, (struct socaddr *)&sin, sinlen) < 0) {
} > 			syslog(LOG_CRIT,"overlan: bind: %m");
} > 			return(1); /*Should never happen*/
} > 		}
} > 	sinlen =3D sizeof(sin);
} > 	bytesread =3D recvfrom(tunnelsock, inbuf, 3000, 0, &sin, &sinlen);
} > 	if (bytesread < 0) {
} > 		syslog(LOG_CRIT,"function: %m");
} > 		return(1); /*Should never happen*/
} > 	}
} > 	inlen =3D bytesread - sizeof(struct ip);
} > 	indata =3D inbuf + sizeof(struct ip);
} >  [...]
} >=20
} 
} 
} --------------enig0380B9FE5FAC750A7B98F1D6
} 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)
} 
} iD8DBQFFzLZHSdZNA80H8MYRAm0mAJ41EBmP8xYgm/MDf+3zIcH4QV0fUgCdHqWO
} 15RTvtRPf2/uTguarJzcQz8=
} =Phx3
} -----END PGP SIGNATURE-----
} 
} --------------enig0380B9FE5FAC750A7B98F1D6--
} 
>-- End of excerpt from Eric Auge