Re: UDP sockets and IPv4 header fields

This is a discussion on Re: UDP sockets and IPv4 header fields within the Linux Networking forums, part of the Linux Forums category; Spoon wrote: > sock = socket(PF_INET, SOCK_DGRAM, 0); > > I receive UDP datagrams with recvfrom() or recvmsg(). > > ...


Go Back   Usenet Forums > Linux Forums > Linux Networking

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 01-15-2007
Spoon
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

Spoon wrote:

> sock = socket(PF_INET, SOCK_DGRAM, 0);
>
> I receive UDP datagrams with recvfrom() or recvmsg().
>
> Is there a way to know the contents of the IPv4 header encapsulating
> a specific UDP datagram?
>
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Version| IHL |Type of Service| Total Length |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> | Identification |Flags| Fragment Offset |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> | Time to Live | Protocol | Header Checksum |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> | Source Address |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> | Destination Address |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> | Options | Padding |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>
> For a given UDP datagram, is there a way to know...
>
> o what the ToS was set to?
> o what the Identification field was set to?
> o what the TTL has become?
> Protocol should be 17.
> Source Address is easy (struct sockaddr in recvfrom)
>
> I've read about raw sockets in Linux, but my understanding is that one
> specifies the protocol one wishes to receive. In other words, I would
> receive e.g. all UDP datagrams on this socket. I only want the UDP
> datagrams sent to a specific port, but there is not notion of port at
> the IP level.


(Added comp.os.linux.networking to the mix.)

Any suggestion?

Regards.
Reply With Quote
  #2 (permalink)  
Old 01-15-2007
Mike Playle
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

On Mon, 15 Jan 2007 17:33:53 +0100, Spoon wrote:

> Spoon wrote:
>
>> sock = socket(PF_INET, SOCK_DGRAM, 0);
>>
>> I receive UDP datagrams with recvfrom() or recvmsg().
>>
>> Is there a way to know the contents of the IPv4 header encapsulating
>> a specific UDP datagram?


'man 7 ip' describes some socket options which might interest you.

>> For a given UDP datagram, is there a way to know...
>>
>> o what the ToS was set to?


IP_RECVTOS

>> o what the Identification field was set to?


This value identifies the separate pieces of a fragmented packet;
defragmentation takes place before you get the packet, so I'm not
sure that this field has any meaning once the packet has been
reassembled.

>> o what the TTL has become?


IP_RECVTTL

Mike
Reply With Quote
  #3 (permalink)  
Old 02-06-2007
Spoon
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

Mike Playle wrote:

> On Mon, 15 Jan 2007 17:33:53 +0100, Spoon wrote:
>
>>> sock = socket(PF_INET, SOCK_DGRAM, 0);
>>>
>>> I receive UDP datagrams with recvfrom() or recvmsg().
>>>
>>> Is there a way to know the contents of the IPv4 header encapsulating
>>> a specific UDP datagram?

>
> 'man 7 ip' describes some socket options which might interest you.
>
>>> For a given UDP datagram, is there a way to know...
>>>
>>> o what the ToS was set to?

>
> IP_RECVTOS
>
>>> o what the Identification field was set to?

>
> This value identifies the separate pieces of a fragmented packet;
> defragmentation takes place before you get the packet, so I'm not
> sure that this field has any meaning once the packet has been
> reassembled.


I'd like to use the Identification field as a sequence number, to detect
lost packets in a stream of UDP packets, without adding any data in the
UDP payload. Do I need a raw socket to get access to that field?
Reply With Quote
  #4 (permalink)  
Old 02-06-2007
Rick Jones
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

In comp.unix.programmer Spoon <devnull@localhost.com> wrote:
> I'd like to use the Identification field as a sequence number, to
> detect lost packets in a stream of UDP packets, without adding any
> data in the UDP payload. Do I need a raw socket to get access to
> that field?


Probably. You want to make sure that you aren't overlapping with
other traffic between the IP address pairs in question.

You should also keep in mind that the IP ID field in IPv4
is only 16 bits, and if you send your packets at a particularly large
high enough rate can wrap very quickly.

Given that a user of UDP must assume that his datagrams can be
duplicated and delayed, you would want to make sure that you didn't
send more than 65535 datagrams in the length of time you can be
statistically certain that any previous UDP datagram in an IP datagram
with that same ID has "left the network." Otherwise, you become
vulnerable to seeing an OLD datagram and thinking it is current.

That length of time would include the time it takes for IP fragment
reassembly to time-out on your receiver. Further issues involving IP
possibly reassembling fragments from different datagrams (again
related to how quickly the measly 16 bit ID field can wrap) may be
involved as well.

Given the above, and the observation that the IP ID wasn't really
(IIRC) meant to be "seen" outside of IP you probably should find some
way to include a (larger) sequence number in the UDP datagram itself.

rick jones
--
web2.0 n, the dot.com reunion tour...
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
Reply With Quote
  #5 (permalink)  
Old 02-07-2007
Spoon
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

Rick Jones wrote:

> Spoon wrote:
>
>> I'd like to use the Identification field as a sequence number, to
>> detect lost packets in a stream of UDP packets, without adding any
>> data in the UDP payload. Do I need a raw socket to get access to
>> that field?

>
> Probably. You want to make sure that you aren't overlapping with
> other traffic between the IP address pairs in question.


I don't understand this sentence. Could you rephrase please?

> You should also keep in mind that the IP ID field in IPv4
> is only 16 bits, and if you send your packets at a particularly large
> high enough rate can wrap very quickly.


This is true whether I plan to give the ID field a special meaning or
not, so I'm not quite sure what to make of your statement :-)

> Given that a user of UDP must assume that his datagrams can be
> duplicated and delayed, you would want to make sure that you didn't
> send more than 65535 datagrams in the length of time you can be
> statistically certain that any previous UDP datagram in an IP datagram
> with that same ID has "left the network." Otherwise, you become
> vulnerable to seeing an OLD datagram and thinking it is current.


As far as I understand, if the IP packets are not fragmented, then the
ID field is mostly ignored. Is this a misconception?

http://en.wikipedia.org/wiki/IPv4 states:

This field is an identification field and is primarily used for uniquely
identifying fragments of an original IP datagram. Some experimental work
has suggested using the ID field for other purposes, such as for adding
packet-tracing information to datagrams in order to help trace back
datagrams with spoofed source addresses.

> That length of time would include the time it takes for IP fragment
> reassembly to time-out on your receiver. Further issues involving IP
> possibly reassembling fragments from different datagrams (again
> related to how quickly the measly 16 bit ID field can wrap) may be
> involved as well.


Again, the issue exists whether I give the ID field a special meaning or
not. I suppose users of UDP just live with it. A work-around might be to
set the DF flag and handle ICMP errors in the application.

> Given the above, and the observation that the IP ID wasn't really
> (IIRC) meant to be "seen" outside of IP you probably should find some
> way to include a (larger) sequence number in the UDP datagram itself.


I need a side-channel because I have to provide information to a custom
application while remaining compatible with legacy systems that provide
no extension mechanisms.

Perhaps I could use an IP option? I'll take a look at RFC 791.

Regards.
Reply With Quote
  #6 (permalink)  
Old 02-07-2007
Rick Jones
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

In comp.unix.programmer Spoon <devnull@localhost.com> wrote:
> Rick Jones wrote:
>> Probably. You want to make sure that you aren't overlapping with
>> other traffic between the IP address pairs in question.


> I don't understand this sentence. Could you rephrase please?


IP stacks have some lattitude when it comes to picking the IP ID for a
given datagram - some keep a global counter which increases for any IP
datagram they send regardless of source/destination pair. Others may
have an IP ID generator per route.

So, if there is any other traffic, or traffic to/from the IP pair
between which you are communicating, they can use some of the IP ID's
you might be looking for and perhaps cause you to have a false
positive on packet loss.

>> You should also keep in mind that the IP ID field in IPv4 is only
>> 16 bits, and if you send your packets at a particularly large high
>> enough rate can wrap very quickly.


> This is true whether I plan to give the ID field a special meaning
> or not, so I'm not quite sure what to make of your statement :-)


True, but except for the case of IP fragmentation, nothing else tries
to assign any meaning to the IP ID field, so its wrapping is of no
concern to them.

>> Given that a user of UDP must assume that his datagrams can be
>> duplicated and delayed, you would want to make sure that you didn't
>> send more than 65535 datagrams in the length of time you can be
>> statistically certain that any previous UDP datagram in an IP
>> datagram with that same ID has "left the network." Otherwise, you
>> become vulnerable to seeing an OLD datagram and thinking it is
>> current.


> As far as I understand, if the IP packets are not fragmented, then
> the ID field is mostly ignored. Is this a misconception?


> http://en.wikipedia.org/wiki/IPv4 states:


> This field is an identification field and is primarily used for
> uniquely identifying fragments of an original IP datagram. Some
> experimental work has suggested using the ID field for other
> purposes, such as for adding packet-tracing information to datagrams
> in order to help trace back datagrams with spoofed source addresses.


That is substantially correct. In the long ago, it might have also
been used by applications making use of raw IP services.

>> That length of time would include the time it takes for IP fragment
>> reassembly to time-out on your receiver. Further issues involving
>> IP possibly reassembling fragments from different datagrams (again
>> related to how quickly the measly 16 bit ID field can wrap) may be
>> involved as well.


> Again, the issue exists whether I give the ID field a special
> meaning or not. I suppose users of UDP just live with it.


Many folks don't even know about it. In theory the UDP checksum
should protect them from the resulting "frankengrams."

> A work-around might be to set the DF flag and handle ICMP errors in
> the application.


If you even ever see the ICMP messages coming back. Some sites chose
to filter them in the belief it makes their situation more secure.

>> Given the above, and the observation that the IP ID wasn't really
>> (IIRC) meant to be "seen" outside of IP you probably should find
>> some way to include a (larger) sequence number in the UDP datagram
>> itself.


> I need a side-channel because I have to provide information to a
> custom application while remaining compatible with legacy systems
> that provide no extension mechanisms.


Is it possible to put new front-ends in front of the legacy systems?

> Perhaps I could use an IP option? I'll take a look at RFC 791.


Similarly, firewalls and the like often will take a dim view of the
presence of IP options. They go to lengths to preclude side-channels
in the first place.

If you can live with the IP ID appearing to jump in value - ie that
you may not see a contiguous, monotonically increasing IP ID then you
can I suppose give it a try. Bear in mind though that nothing in the
specs (IIRC) actually requires that the IP ID be monotonically
increasing - only that it shouldn't be reused for the maximum packet
lifetime between a pair of local/remote IP and I suspect protocol
(eg UDP, TCP etc)

rick jones
--
Wisdom Teeth are impacted, people are affected by the effects of events.
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
Reply With Quote
  #7 (permalink)  
Old 02-09-2007
Spoon
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

Rick Jones wrote:

> Spoon wrote:
>
>> Rick Jones wrote:
>>
>>> Probably. You want to make sure that you aren't overlapping with
>>> other traffic between the IP address pairs in question.

>>
>> I don't understand this sentence. Could you rephrase please?

>
> IP stacks have some latitude when it comes to picking the IP ID for a
> given datagram - some keep a global counter which increases for any IP
> datagram they send regardless of source/destination pair. Others may
> have an IP ID generator per route.
>
> So, if there is any other traffic, or traffic to/from the IP pair
> between which you are communicating, they can use some of the IP ID's
> you might be looking for and perhaps cause you to have a false
> positive on packet loss.


Thanks for pointing that out. (My OS is Linux 2.6.)

I've written a test program to create two UDP sockets, one second apart,
and connect them to the same remote host. Then, in a loop, I send two
packets through sock1, and one packet through sock2, with 5 seconds
between packets. I launch three instances of that program.

Instance 1
sock1
local port = 1077
initial IP ID = 62546
sock2
local port = 1078
initial IP ID = 62648

Instance 2
sock1
local port = 1079
initial IP ID = 64830
sock2
local port = 1080
initial IP ID = 64931

Instance 3
sock1
local port = 1081
initial IP ID = 776
sock2
local port = 1082
initial IP ID = 877

I'll examine the Linux source code, but it appears that the initial ID
is a function of the time when the socket is created or connected. The
ID field is incremented by 1 for each packet sent through a socket.

I ran tcpdump -nvvv -i eth0 port 40000

$ grep "\.1077" dump | cut -d' ' -f-10
12:17:40.563635 IP (tos 0x0, ttl 1, id 62546,
12:17:45.573006 IP (tos 0x0, ttl 1, id 62547,
12:17:55.591842 IP (tos 0x0, ttl 1, id 62548,
12:18:00.601264 IP (tos 0x0, ttl 1, id 62549,
12:18:10.620132 IP (tos 0x0, ttl 1, id 62550,
12:18:15.629520 IP (tos 0x0, ttl 1, id 62551,
12:18:25.648386 IP (tos 0x0, ttl 1, id 62552,
12:18:30.657779 IP (tos 0x0, ttl 1, id 62553,
12:18:40.686611 IP (tos 0x0, ttl 1, id 62554,
12:18:45.696031 IP (tos 0x0, ttl 1, id 62555,
12:18:55.714867 IP (tos 0x0, ttl 1, id 62556,
12:19:00.724288 IP (tos 0x0, ttl 1, id 62557,
12:19:10.743128 IP (tos 0x0, ttl 1, id 62558,
12:19:15.752549 IP (tos 0x0, ttl 1, id 62559,
12:19:25.771417 IP (tos 0x0, ttl 1, id 62560,
12:19:30.780803 IP (tos 0x0, ttl 1, id 62561,

$ grep "\.1078" dump | cut -d' ' -f-10
12:17:50.582424 IP (tos 0x0, ttl 1, id 62648,
12:18:05.610684 IP (tos 0x0, ttl 1, id 62649,
12:18:20.638938 IP (tos 0x0, ttl 1, id 62650,
12:18:35.667203 IP (tos 0x0, ttl 1, id 62651,
12:18:50.705452 IP (tos 0x0, ttl 1, id 62652,
12:19:05.733707 IP (tos 0x0, ttl 1, id 62653,
12:19:20.761965 IP (tos 0x0, ttl 1, id 62654,
12:19:35.790221 IP (tos 0x0, ttl 1, id 62655,

$ grep "\.1081" dump | cut -d' ' -f-10
12:18:18.209456 IP (tos 0x0, ttl 1, id 776,
12:18:23.218639 IP (tos 0x0, ttl 1, id 777,
12:18:33.237500 IP (tos 0x0, ttl 1, id 778,
12:18:38.246899 IP (tos 0x0, ttl 1, id 779,
12:18:48.275733 IP (tos 0x0, ttl 1, id 780,
12:18:53.285351 IP (tos 0x0, ttl 1, id 781,
12:19:03.303991 IP (tos 0x0, ttl 1, id 782,
12:19:08.313409 IP (tos 0x0, ttl 1, id 783,
12:19:18.332249 IP (tos 0x0, ttl 1, id 784,
12:19:23.341671 IP (tos 0x0, ttl 1, id 785,
12:19:33.360502 IP (tos 0x0, ttl 1, id 786,

>>> You should also keep in mind that the IP ID field in IPv4 is only
>>> 16 bits, and if you send your packets at a particularly large high
>>> enough rate can wrap very quickly.

>>
>> This is true whether I plan to give the ID field a special meaning
>> or not, so I'm not quite sure what to make of your statement :-)

>
> True, but except for the case of IP fragmentation, nothing else tries
> to assign any meaning to the IP ID field, so its wrapping is of no
> concern to them.


Point taken.

>>> Given that a user of UDP must assume that his datagrams can be
>>> duplicated and delayed, you would want to make sure that you didn't
>>> send more than 65535 datagrams in the length of time you can be
>>> statistically certain that any previous UDP datagram in an IP
>>> datagram with that same ID has "left the network." Otherwise, you
>>> become vulnerable to seeing an OLD datagram and thinking it is
>>> current.

>>
>> As far as I understand, if the IP packets are not fragmented, then
>> the ID field is mostly ignored. Is this a misconception?
>>
>> http://en.wikipedia.org/wiki/IPv4 states:
>>
>> This field is an identification field and is primarily used for
>> uniquely identifying fragments of an original IP datagram. Some
>> experimental work has suggested using the ID field for other
>> purposes, such as for adding packet-tracing information to datagrams
>> in order to help trace back datagrams with spoofed source addresses.

>
> That is substantially correct. In the long ago, it might have also
> been used by applications making use of raw IP services.
>
>>> That length of time would include the time it takes for IP fragment
>>> reassembly to time-out on your receiver. Further issues involving
>>> IP possibly reassembling fragments from different datagrams (again
>>> related to how quickly the measly 16 bit ID field can wrap) may be
>>> involved as well.

>
>> Again, the issue exists whether I give the ID field a special
>> meaning or not. I suppose users of UDP just live with it.

>
> Many folks don't even know about it. In theory the UDP checksum
> should protect them from the resulting "frankengrams."


I like that concept! :-)

>> A work-around might be to set the DF flag and handle ICMP errors in
>> the application.

>
> If you even ever see the ICMP messages coming back. Some sites chose
> to filter them in the belief it makes their situation more secure.


I've noticed that, by default, the "Don't Fragment" bit is set.

>>> Given the above, and the observation that the IP ID wasn't really
>>> (IIRC) meant to be "seen" outside of IP you probably should find
>>> some way to include a (larger) sequence number in the UDP datagram
>>> itself.

>>
>> I need a side-channel because I have to provide information to a
>> custom application while remaining compatible with legacy systems
>> that provide no extension mechanisms.

>
> Is it possible to put new front-ends in front of the legacy systems?


I'm afraid not.

>> Perhaps I could use an IP option? I'll take a look at RFC 791.

>
> Similarly, firewalls and the like often will take a dim view of the
> presence of IP options. They go to lengths to preclude side-channels
> in the first place.


Are firewalls known to drop packets with an experimental IP option?
Or would they just strip the option?

http://www.iana.org/assignments/ip-parameters

Copy Class Number Value Name Reference
---- ----- ------ ----- ------------------------------- ------------
0 0 30 30 EXP - RFC3692-style Experiment (**) [RFC4727]
0 2 30 94 EXP - RFC3692-style Experiment (**) [RFC4727]
1 0 30 158 EXP - RFC3692-style Experiment (**) [RFC4727]
1 2 30 222 EXP - RFC3692-style Experiment (**) [RFC4727]

> If you can live with the IP ID appearing to jump in value - ie that
> you may not see a contiguous, monotonically increasing IP ID then you
> can I suppose give it a try. Bear in mind though that nothing in the
> specs (IIRC) actually requires that the IP ID be monotonically
> increasing - only that it shouldn't be reused for the maximum packet
> lifetime between a pair of local/remote IP and I suspect protocol
> (eg UDP, TCP etc)


The IP stack in Linux seems to behave as I had hoped :-)

Here's my test program.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <string.h> // memset
#define ZERO(type, var) type var; memset(&var, 0, sizeof var)

int init_socket(void)
{
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket"); exit(1);
}
ZERO(struct sockaddr_in, addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(40000);
inet_aton("239.1.1.1", &addr.sin_addr);
if (connect(sock, (struct sockaddr *)&addr, sizeof addr) != 0)
{
perror("connect"); exit(2);
}
return sock;
}

#define SOCK_COUNT 2
#define PACKET_COUNT 20
#define PACKET_SIZE 100
char buf[PACKET_SIZE];

int main(int argc, char **argv)
{
int i, sock[SOCK_COUNT];

for (i=0; i < SOCK_COUNT; ++i)
{
sock[i] = init_socket();
sleep(1);
}

for (i=0; i < PACKET_COUNT; ++i)
{
if (send(sock[0], buf, argc, 0) < 0) perror("send");
sleep(5);
if (send(sock[0], buf, argc, 0) < 0) perror("send");
sleep(5);
if (send(sock[1], buf, argc, 0) < 0) perror("send");
sleep(5);
}

return 0;
}

Regards.
Reply With Quote
  #8 (permalink)  
Old 02-09-2007
Rick Jones
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

In comp.os.linux.networking Spoon <devnull@localhost.com> wrote:
> Thanks for pointing that out. (My OS is Linux 2.6.)


That leaves a great deal of ambiguity :)

> I've written a test program to create two UDP sockets, one second apart,
> and connect them to the same remote host. Then, in a loop, I send two
> packets through sock1, and one packet through sock2, with 5 seconds
> between packets. I launch three instances of that program.


> Instance 1
> sock1
> local port = 1077
> initial IP ID = 62546
> sock2
> local port = 1078
> initial IP ID = 62648


> ...


> I'll examine the Linux source code, but it appears that the initial
> ID is a function of the time when the socket is created or
> connected. The ID field is incremented by 1 for each packet sent
> through a socket.


I wouldn't expect the ID to be a function of the socket - at least not
directly. It should only be a function of the
source/destination/protocol tuple.

> I ran tcpdump -nvvv -i eth0 port 40000


> $ grep "\.1077" dump | cut -d' ' -f-10
> 12:17:40.563635 IP (tos 0x0, ttl 1, id 62546,
> 12:17:45.573006 IP (tos 0x0, ttl 1, id 62547,
> 12:17:55.591842 IP (tos 0x0, ttl 1, id 62548,
> 12:18:00.601264 IP (tos 0x0, ttl 1, id 62549,
> 12:18:10.620132 IP (tos 0x0, ttl 1, id 62550,
> 12:18:15.629520 IP (tos 0x0, ttl 1, id 62551,
> 12:18:25.648386 IP (tos 0x0, ttl 1, id 62552,
> 12:18:30.657779 IP (tos 0x0, ttl 1, id 62553,
> 12:18:40.686611 IP (tos 0x0, ttl 1, id 62554,
> 12:18:45.696031 IP (tos 0x0, ttl 1, id 62555,
> 12:18:55.714867 IP (tos 0x0, ttl 1, id 62556,
> 12:19:00.724288 IP (tos 0x0, ttl 1, id 62557,
> 12:19:10.743128 IP (tos 0x0, ttl 1, id 62558,
> 12:19:15.752549 IP (tos 0x0, ttl 1, id 62559,
> 12:19:25.771417 IP (tos 0x0, ttl 1, id 62560,
> 12:19:30.780803 IP (tos 0x0, ttl 1, id 62561,


> $ grep "\.1078" dump | cut -d' ' -f-10
> 12:17:50.582424 IP (tos 0x0, ttl 1, id 62648,
> 12:18:05.610684 IP (tos 0x0, ttl 1, id 62649,
> 12:18:20.638938 IP (tos 0x0, ttl 1, id 62650,
> 12:18:35.667203 IP (tos 0x0, ttl 1, id 62651,
> 12:18:50.705452 IP (tos 0x0, ttl 1, id 62652,
> 12:19:05.733707 IP (tos 0x0, ttl 1, id 62653,
> 12:19:20.761965 IP (tos 0x0, ttl 1, id 62654,
> 12:19:35.790221 IP (tos 0x0, ttl 1, id 62655,


The spread of IP IDs shouldn't be happening there if those are between
the same src/dst IP address pair. IE there is supposed to be _one_ IP
ID space between any src/dst/prot tuple, not per socket. I suspect
that if one were to mention that to the kernel networking folks they
might say "Yeah, but the DF bit is set, so it doesn't matter."
Strictly speaking they are correct - the IP ID is only used in
fragmentation, and strictly speaking anything which fragments an IP
datagram with the DF bit set is broken, but I still don't like it - it
feels "brittle" to me. Maybe that is me being too "belt and
susppenders" maybe not.

It is also not a behaviuor you can count-on to be present in other
stacks.

> Are firewalls known to drop packets with an experimental IP option?
> Or would they just strip the option?


Firewalls are by their very nature _supposed_ to be paranoid. That
means that _at best_ they might strip the option, and could indeed
even just drop the datagram entirely.

> The IP stack in Linux seems to behave as I had hoped :-)


Today. Given the behaviour is not required, or even suggested, by the
RFC's governing IP, there is a certain element of risk counting on it
to continue to behave that way in the future. And you definitely
cannot count on it to behave that way on other platforms. Caveat
programmor as it were.

rick jones
--
oxymoron n, commuter in a gas-guzzling luxury SUV with an American flag
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
Reply With Quote
  #9 (permalink)  
Old 02-14-2007
Spoon
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

Rick Jones wrote:

> Spoon wrote:
>
>> My OS is Linux 2.6.

>
> That leaves a great deal of ambiguity :)


I've been experimenting with the latest 2.6.20 kernel.
2.6.0 behaves the same way.
Why do you say ambiguity?

>> I've written a test program to create two UDP sockets, one second apart,
>> and connect them to the same remote host. Then, in a loop, I send two
>> packets through sock1, and one packet through sock2, with 5 seconds
>> between packets. I launch three instances of that program.
>>
>> Instance 1
>> sock1
>> local port = 1077
>> initial IP ID = 62546
>> sock2
>> local port = 1078
>> initial IP ID = 62648
>>
>> I'll examine the Linux source code, but it appears that the initial
>> ID is a function of the time when the socket is created or
>> connected. The ID field is incremented by 1 for each packet sent
>> through a socket.

>
> I wouldn't expect the ID to be a function of the socket - at least not
> directly. It should only be a function of the
> source/destination/protocol tuple.


In Linux 2.6, the ID field is initialized to jiffies when the UDP socket
is connected.

cf. udp_connect() in linux-2.6.0/net/ipv4/udp.c
or ip4_datagram_connect() in linux-2.6.20/net/ipv4/datagram.c

> The spread of IP IDs shouldn't be happening there if those are between
> the same src/dst IP address pair. IE there is supposed to be _one_ IP
> ID space between any src/dst/prot tuple, not per socket. I suspect
> that if one were to mention that to the kernel networking folks they
> might say "Yeah, but the DF bit is set, so it doesn't matter."
> Strictly speaking they are correct - the IP ID is only used in
> fragmentation, and strictly speaking anything which fragments an IP
> datagram with the DF bit set is broken, but I still don't like it - it
> feels "brittle" to me. Maybe that is me being too "belt and
> suspenders" maybe not.


cf. ip_select_ident() in include/net/ip.h

static inline void ip_select_ident(...)
{
if (iph->frag_off & htons(IP_DF)) {
/* This is only to work around buggy Windows95/2000
* VJ compression implementations. If the ID field
* does not change, they drop every other packet in
* a TCP stream using header compression.
*/
iph->id = (sk && inet_sk(sk)->daddr) ?
htons(inet_sk(sk)->id++) : 0;
} else
__ip_select_ident(iph, dst, 0);
}

The ID field is incremented by one.

> It is also not a behaviour you can count-on to be present in other
> stacks.


I can always write my own IP header.

>> The IP stack in Linux seems to behave as I had hoped :-)

>
> Today. Given the behaviour is not required, or even suggested, by the
> RFC's governing IP, there is a certain element of risk counting on it
> to continue to behave that way in the future. And you definitely
> cannot count on it to behave that way on other platforms. Caveat
> programmor as it were.


Thanks for pointing that out. As I've stated above, I can always write
my own IP header.

Regards.
Reply With Quote
  #10 (permalink)  
Old 02-14-2007
Rick Jones
 
Posts: n/a
Default Re: UDP sockets and IPv4 header fields

In comp.os.linux.networking Spoon <devnull@localhost.com> wrote:
> Rick Jones wrote:
>> Spoon wrote:
>>> My OS is Linux 2.6.

>> That leaves a great deal of ambiguity :)


> I've been experimenting with the latest 2.6.20 kernel. > 2.6.0

behaves the same way. > Why do you say ambiguity?

Because the Linux 2.6 kernel, while perhaps maintaining this
particular behavior, is not "static" wrt all of its behaviour. It
continues to evolve.

>> It is also not a behaviour you can count-on to be present in other
>> stacks.


> I can always write my own IP header.


Which may need to have a different IP address than the host stack, so
you may have to run your very own little UDP/IP stack and run it
either over an interface in promiscuous mode, or an interface of its
very own where you can bind the IP and ARP SAPs directly.

>> Today. Given the behaviour is not required, or even suggested, by
>> the RFC's governing IP, there is a certain element of risk counting
>> on it to continue to behave that way in the future. And you
>> definitely cannot count on it to behave that way on other
>> platforms. Caveat programmor as it were.


> Thanks for pointing that out. As I've stated above, I can always write
> my own IP header.


I thought you had a legacy side with which you had to communicate?

rick jones
--
web2.0 n, the dot.com reunion tour...
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT +1. The time now is 02:55 PM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0