Subject: Re: Raw socket functionality
To: None <jeremy@broder.com>
From: Geir Inge Jensen <Geir.I.Jensen@runit.sintef.no>
List: current-users
Date: 03/16/1998 15:42:33
On 13 Mar, Jeremy Cooper wrote:
> 
> 
> On Fri, 13 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. [ ... ]
>> 
>> However, the packet that finally reaches the network has IPPROTO_RAW in
>> its IP-header! Can I change this functionality?
> 
> IPPROTO_RAW notifies the IP protocol stack that to send IP packets with a
> protocol field of ``RAW'' (as opposed to TCP, UDP, or ICMP), instead of
> ``RAW IP Packets'' as you are assuming.  Note this distinction carefully.
> 
> If you truly want to manufacture your own IP packets with headers
> included, you must make a call to setsockopt() to toggle the IP_HDRINCL
> flag on the socket before you use it.
> 
>   int state = 1;
>   setsockopt(sockfd, 0, IP_HDRINCL, &state, sizeof(state))

Thanks, both to you and the other who responded to me. It works, but
not as expected. I thought I could feed the socket with a raw IP
header, but that is not the case. If you, for instance, use network
byte order on the ip-length field, NetBSD will return with EINVAL
because the length of the packet does not match the length-field I fed
the socket with. If I use native byte order on the field, everything
goes well. But then I thought, this should not work at all, because now
my ip-checksum field would be wrong. However, after examining the code,
it seems that NetBSD changes the byte order of the relevant fields, and
computes its own checksum of the packet before it is sent. That is not
my perception of a _raw_ packet. Maybe this is how it is supposed to
work :)

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?

(I also tried IPPROTO_IP, with IP_RECVIF socket option, but that got my
kernel into a loop...)

 - Geir Inge.