Subject: Re: Raw socket functionality
To: Jeremy Cooper <jeremy@broder.com>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-net
Date: 03/16/1998 17:44:06
>[ moved from current-users ]
   [moved from tech-kern]

Jeremy Cooper writes:

>On Mon, 16 Mar 1998, Geir Inge Jensen wrote:
>
>> >> How is IPPROTO_RAW supposed to work? I thought that I could send raw ip
>> >> packets unchanged to the network. [ ... ]
>> >
>> >   int state = 1;
>> >   setsockopt(sockfd, 0, IP_HDRINCL, &state, sizeof(state))
>> 

>Addressing your first point [network vs. host ordering], the kernel does
>indeed need the header to be provided in host byte order.  The conversion
>from host to network order occurs at the very end of IP output processing,
>of which, IPPROTO_RAW processing is before.  That's the way life is.

This is pretty much a bug, possibly an oversight from CSRG moving to
big-endian machines.  Extant Code that uses SOCK_RAW kludges around
it.  There's been no consensus amongst the *BSD camps about fixing it,
or it would've been fixed two, three years ago. 

At least little-endian kernels now check for insane (byteswapped) IP
lengths and no longer panic.


>> I have yet another problem. How am I supposed to read raw tcp packets
>> through a socket? I tried with 
>> 
>>   socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
>> 
>> and I got all ICMP packets delivered to my address. However, with
>> IPPROTO_TCP, my code does not receive anything. I thought it
>> would receive all IP packets with the protocol set to tcp. Is this
>> possible to achieve?

No. Not easily. If you want to wiretap an existing protocol, as
opposed to implementing a new protocol, then BPF is likely to be an
easier route.  

What exactly is it you're trying to do?  Re-implement TCP (or a
protocol layered on top of TCP) in userspace or something like that?
That runs into all sorts of problems: the in-kernel protocol _is_
going to generate responses to packets which it thinks belong to it,
*will* reset your userspace TCP connections (for which it has no
state), etc., etc.


>>I'm begining to see that your needs are straining the capacity of
>>SOCK_RAW sockets.  If you want to really generate and receive raw packets,
>>you should consider using BPF.  SOCK_RAW isn't completely intuitive, and
>>wasn't made for this kind of behavior.

Um, actually, if memory serves, the 4BSD documentation says SOCK_RAW
was intended pretty much exactly to give as close as possible a match
to the in-kernel environment, for doing (prototype) development of
things like routing protocols in userspace. But when the namespace (IP
protocols, TCP ports, etc) collide with an existing in-kernel
implementation, this Just Doesnt WOrk Very Well, and wiretapping with
BPF is probably easier.  

But-- depending on the application-- using a raw socket for output can
stil be useful: it means you can let the kernel do IP routing
decisions and ARP for you.

These issues really belong on tech-net, so I changed the CC: accordingly.