Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 05 Aug 2011 19:29:42 +0200
From:      Andre Oppermann <andre@freebsd.org>
To:        Matthew Cini Sarreo <mcins1@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: ESP Raw Socket: Returned IP packet incorrect
Message-ID:  <4E3C2886.9070100@freebsd.org>
In-Reply-To: <CAFj3ReT6mmT6ScWf-FBT-1%2BF8z9PWHyFj-R7haWvaV-bq=42PQ@mail.gmail.com>
References:  <CAFj3ReT6mmT6ScWf-FBT-1%2BF8z9PWHyFj-R7haWvaV-bq=42PQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 11.07.2011 17:26, Matthew Cini Sarreo wrote:
> Hello all;
>
> I have recently encountered a problem when using raw sockets on FreeBSD 8
> (8.0-RELEASE) when using ESP raw sockets.
>
> I have created a raw esp socket using:
> socket(AF_INET, SOCK_RAW, 50);
> which works fine. However, when there is a packet on the socket, recvfrom()
> returns a packet where the length bytes in the IP header are incorrect; they
> are swapped (MSB is placed in the LSB and vice-versa)
>
> tcpdump shows the following:
>
> tcpdump: listening on le0, link-type EN10MB (Ethernet), capture size 96
> bytes
> 15:00:53.993810 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ESP
> (50), length 120)
>      10.0.251.228>  10.0.252.231: ESP(spi=0xa0534f17,seq=0x3), length 100
>          0x0000:  4500 0078 0000 4000 4032 2d88 0a00 fbe4
>          0x0010:  0a00 fce7 a053 4f17 0000 0003 6885 8abd
>          0x0020:  2222 5ded 44dc 842f 3081 8fa3 bde4 2265
>          0x0030:  7438 2bf4 049c 664b 7dc4 44ef 1f6f 5e7d
>          0x0040:  b8c1 482f 8c3b f488 a19a 3d9a d5fe ed9d
>          0x0050:  b1c2
>
>
> However, recvfrom() returns the following buffer:
> 4500 6400 0000 0040 4032 2D88 0A00 FBE4
> 0A00 FCE7 A053 4F17 0000 0003 6885 8ABD
> 2222 5DED 44DC 842F 3081 8FA3 BDE4 2265
> 7438 2BF4 049C 664B 7DC4 44EF 1F6F 5E7D
> B8C1 482F 8C3B F488 A19A 3D9A D5FE ED9D
> B1C2
>
> As it is easy to see, the length is not correct (bytes 2 and 3 are 0x6400
> instead of 0x0064) and it does not correspond to the value returned by
> recvfrom().
>
> Is this a known issue? Am I missing some options for raw sockets that are
> required for FreeBSD? I have attempted this on a socket to a TUN interface
> (not with an ESP socket) and the buffer had the proper length; it seems to
> only happen with ESP. This code runs fine on multiple Linux distributions
> and on Windows; it was only noticed with FreeBSD. Could it be that there is
> some other ESP application running and interfering (I have not installed
> any; don't know if there are by default and I'm quite new to any of the
> BSDs)?

The problem is with all raw sockets.  Contrary to the statement in ip(4)
"Incoming packets are received with IP header and options intact" and other
popular OSes the ip_len field in the IP header has the IP header length
already deducted (line 770 in ip_input.c).  For normal in-kernel implemented
protocols this is fine but raw sockets it is clearly wrong.  The fix is
pretty easy and just adds the header length back in raw_input() in raw_ip.c.

Please test this patch:
  http://people.freebsd.org/~andre/raw_ip-header-length-20110805.diff

-- 
Andre



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E3C2886.9070100>