Ethereal-dev: Re: [Ethereal-dev] Validating IPs?

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxx>
Date: Fri, 28 Jan 2005 00:24:25 -0800
Alex Kirk wrote:
Basically, I've got a field in a quasi-fixed-length piece that can either be an
IP address, or a little-endian int that tells me how many IP address pairs
follow. What I want to be able to do is distinguish between that single IP
address and the int that indicates I have a bunch of IP addresses to process.

What does the recipient of one of those packets do to determine whether the field is a count or an IP address? Either

1) there has to be something in the packet itself that specifies whether the field is an IP address or count;

2) there has to have been something in previous traffic, or in some configuration file, or some other form of negotiation beforehand to specify whether the field is an IP address or count;

3) the recipient has to use some heuristic to determine whether it's an IP address or count;

or something such as that.

If it's 1) the dissector should look at the same item.

If it's 2), you might try having a configuration item for this, or have a heuristic to dtermine which it is.

If it's 3), the dissector should use the same heuristic (but a protocol *requiring* a heuristic that doesn't give a certain result is a bit broken).

As the int is in little-endian byte order, a heuristic that would *probably* work would be to check whether the third and fourth of the four bytes of the int are zero - if so, it's probably a little-endian count of IP address pairs in the packet, while, if they're not zero, it's probably not a little-endian count of IP address pairs in the packet (as that'd mean there'd be more than 65536 pairs).

At least according to RFC 1122, not 32-bit values are proper *unicast* IP addresses; section 3.3.2.2 says:

            IP addresses are not permitted to have the value 0 or -1 for
            any of the <Host-number>, <Network-number>, or <Subnet-
            number> fields (except in the special cases listed above).
            This implies that each of these fields will be at least two
            bits long.

("-1" meaning "all bits set").  The only exceptions cited with zeroes are

            (a)  { 0, 0 }

                 This host on this network.  MUST NOT be sent, except as
                 a source address as part of an initialization procedure
                 by which the host learns its own IP address.

                 See also Section 3.3.6 for a non-standard use of {0,0}.

            (b)  { 0, <Host-number> }

                 Specified host on this network.  It MUST NOT be sent,
                 except as a source address as part of an initialization
                 procedure by which the host learns its full IP address.

which don't correspond to host IP addresses - they're just values to use when you have to send an IP packet but you don't yet know your IP address.

As such, if the IP address is in network byte order, *and* the little-endian integer isn't likely to have a value > 65535, a heuristic checking whether the third and fourth bytes in the address (which correspond to the *upper* 16 bits of the little-endian integer, and to the *lower* 16 bits of the IP address) are zero will probably get the right answer most of the time.

However, if your dissector has to perform a heuristic such as this, that would make me suspect that either

1) the protocol was misdesigned (i.e., the designer or designers didn't think about how to distinguish between an IP address and an IP address pair count, in which case perhaps they fell back on a heuristic such the one cited);

2) there's some on-the-wire negotiation done before those packets are sent that determines whether the subsequent packets have addresses or a set of address pairs;

3) there's some out-of-band negotiation done (e.g., the maintainers of the two sites talking over the telephone, and configuring their sites accordingly) that determines whether the subsequent packets have addresses or a set of address pairs.