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.