Re: UDP sockets and IPv4 header fields - Networking

This is a discussion on Re: UDP sockets and IPv4 header fields - Networking ; 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? > > ...

+ Reply to Thread
Results 1 to 13 of 13

Thread: Re: UDP sockets and IPv4 header fields

  1. 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.

  2. 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

  3. 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?

  4. Re: UDP sockets and IPv4 header fields

    In comp.unix.programmer 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.

    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...

  5. 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.

  6. Re: UDP sockets and IPv4 header fields

    In comp.unix.programmer 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 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...

  7. 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
    #include
    #include
    #include
    #include
    #include

    #include // 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.

  8. Re: UDP sockets and IPv4 header fields

    In comp.os.linux.networking Spoon 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...

  9. 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.

  10. Re: UDP sockets and IPv4 header fields

    In comp.os.linux.networking Spoon 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...

  11. Re: UDP sockets and IPv4 header fields

    Rick Jones wrote:

    > Spoon 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.


    Point taken. However, since I have the source, I may be able to keep the
    behavior I want, even if it is changed in later kernels :-)

    >>> 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.


    I don't understand this statement.

    >>> 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?


    The receiver may be either a legacy system which does not expect any
    extra information, or a new system which needs the extra information for
    diagnostics.

    If the sender provides the extra information in the IP header (e.g. in
    the ID field, or within IP options) then the legacy system is happy (its
    IP stack ignores the information) and the new system is happy (it can
    find the extra information with a little more work).

    I think I can add an IP_RECVID socket option. New systems would then be
    able to call getsockopt(IP_RECVID, ...) to retrieve the ID field of the
    last datagram. What do you think?

    Regards.

  12. Re: UDP sockets and IPv4 header fields

    Spoon wrote:

    > I think I can add an IP_RECVID socket option. New systems would then be
    > able to call getsockopt(IP_RECVID, ...) to retrieve the ID field of the
    > last datagram. What do you think?


    I think I meant an ioctl call (e.g. SIOCGSTAMP).

  13. Re: UDP sockets and IPv4 header fields

    >> 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.


    > I don't understand this statement.


    When traffic arrives at the host, if it is for an IP address known to
    the "real" stack then likely as not it will be consumed by the "real"
    stack rather than arrive at your (raw?) socket.

    > I think I can add an IP_RECVID socket option. New systems would then
    > be able to call getsockopt(IP_RECVID, ...) to retrieve the ID field
    > of the last datagram. What do you think?


    With source, almost anything is possible.

    rick jones
    --
    oxymoron n, Hummer H2 with California Save Our Coasts and Oceans plates
    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 to Thread