IPv4 leading zeroes and weird interface behaviour
Hello, is there - by standard - a definition on how to represent an IPv4 address? I have (for example) the IP address "73.0.255.229", which can IMHO also be written as "073.000.255.229" as the leading zeroes are not giving any changes to the binary representation of this address. Am I right on this? But: When I lookup this IP address on https://stat.ripe.net/073.000.255.229 the first octet is internally getting swapped to "59". This can be explained, if you take "073" as an octal value and convert it to a decimal value. It is definitely a octal-to-decimal conversion thing, as for example also the value "010" is getting replaced by "8" and so on. Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged? This weird conversion also happens inside the "geoiplookup" tool by MaxMind and I'm not sure if I'm going to be the moron in this story or if I found the same bug inside multiple softwares at once ;-) Thanks and greetings from Wuppertal Max
Historically, C uses a 0 to precede an octal number, 0x to precede a decimal, and 0b for binary. Leading zeroes are otherwise stripped in numerical representation. Since 0x is not accepted, I'd call it a bug and request that the numbers always get treated as decimal, regardless of leading zeros. There's probably some downstream library making the anachronistic assumption. On Wed, Oct 25, 2017 at 1:45 PM, Max Grobecker < max.grobecker@ml.grobecker.info> wrote:
Hello,
is there - by standard - a definition on how to represent an IPv4 address?
I have (for example) the IP address "73.0.255.229", which can IMHO also be written as "073.000.255.229" as the leading zeroes are not giving any changes to the binary representation of this address. Am I right on this?
But: When I lookup this IP address on https://stat.ripe.net/073.000. 255.229 the first octet is internally getting swapped to "59". This can be explained, if you take "073" as an octal value and convert it to a decimal value. It is definitely a octal-to-decimal conversion thing, as for example also the value "010" is getting replaced by "8" and so on.
Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged?
This weird conversion also happens inside the "geoiplookup" tool by MaxMind and I'm not sure if I'm going to be the moron in this story or if I found the same bug inside multiple softwares at once ;-)
Thanks and greetings from Wuppertal Max
It was warned before on this IETF draft, but it was never published: <https://www.ietf.org/archive/id/draft-main-ipaddr-text-rep-02.txt> Hugo On 13:54 25/10, Phillip Remaker wrote:
Historically, C uses a 0 to precede an octal number, 0x to precede a decimal, and 0b for binary. Leading zeroes are otherwise stripped in numerical representation.
Since 0x is not accepted, I'd call it a bug and request that the numbers always get treated as decimal, regardless of leading zeros.
There's probably some downstream library making the anachronistic assumption.
On Wed, Oct 25, 2017 at 1:45 PM, Max Grobecker < max.grobecker@ml.grobecker.info> wrote:
Hello,
is there - by standard - a definition on how to represent an IPv4 address?
I have (for example) the IP address "73.0.255.229", which can IMHO also be written as "073.000.255.229" as the leading zeroes are not giving any changes to the binary representation of this address. Am I right on this?
But: When I lookup this IP address on https://stat.ripe.net/073.000. 255.229 the first octet is internally getting swapped to "59". This can be explained, if you take "073" as an octal value and convert it to a decimal value. It is definitely a octal-to-decimal conversion thing, as for example also the value "010" is getting replaced by "8" and so on.
Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged?
This weird conversion also happens inside the "geoiplookup" tool by MaxMind and I'm not sure if I'm going to be the moron in this story or if I found the same bug inside multiple softwares at once ;-)
Thanks and greetings from Wuppertal Max
On 2017-10-25 13:54:46 -0700, Phillip Remaker wrote:
Historically, C uses a 0 to precede an octal number, 0x to precede a decimal, and 0b for binary.
0b for binary is not C. It is used by some other languages, though (e.g. Perl).
Since 0x is not accepted,
That depends on the tool: % ping 0x8f.0x82.0x10.0x8 PING 0x8f.0x82.0x10.0x8 (143.130.16.8) 56(84) bytes of data. 64 bytes from 143.130.16.8: icmp_seq=1 ttl=55 time=8.37 ms 64 bytes from 143.130.16.8: icmp_seq=2 ttl=55 time=8.26 ms ... % ping -V ping utility, iputils-s20161105
There's probably some downstream library making the anachronistic assumption.
Possibly gethostbyname in the libc, but I haven't tested that. At least interpreting numbers with leading zeroes as octal is traditional on unix-like OSs (I probably first noticed that on Ultrix around 1990). I don't know why anyone thought this was a good idea. I wouldn't expect anyone to rely on it, but apparently nobody dares to get rid of that "feature". hp -- _ | Peter J. Holzer | we build much bigger, better disasters now |_|_) | | because we have much more sophisticated | | | hjp@hjp.at | management tools. __/ | http://www.hjp.at/ | -- Ross Anderson <https://www.edge.org/>
On 2017/10/25 23:16 , Peter J. Holzer wrote:
Possibly gethostbyname in the libc, but I haven't tested that. At least interpreting numbers with leading zeroes as octal is traditional on unix-like OSs (I probably first noticed that on Ultrix around 1990). I don't know why anyone thought this was a good idea. I wouldn't expect anyone to rely on it, but apparently nobody dares to get rid of that "feature".
Technically it is C feature. If you call, for example, strtol with the third argument (base) equal to 0, then it will parse numbers just like a C compiler. In many contexts is is convenient if you can just type a hex number by prefixing the number with 0x. Unfortunately, this use of strtol is so common, that it gets used even in a context where it doesn't make sense, such as parsing an IPv4 address. However, the way IPv4 addresses are parsed is completely weird. This is from the inet_aton manual page: Values specified using the `.' notation take one of the following forms: a.b.c.d a.b.c a.b a When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address. Note that when an Internet address is viewed as a 32-bit integer quantity on the VAX the bytes referred to above appear as ``d.c.b.a''. That is, VAX bytes are ordered from right to left. When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right-most two bytes of the network address. This makes the three part address format convenient for speci- fying Class B network addresses as ``128.net.host''. When a two part address is supplied, the last part is interpreted as a 24-bit quantity and placed in the right most three bytes of the network address. This makes the two part address format convenient for specify- ing Class A network addresses as ``net.host''. When only one part is given, the value is stored directly in the network address without any byte rearrangement. All numbers supplied as ``parts'' in a `.' notation may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; other- wise, the number is interpreted as decimal).
On Wed, 25 Oct 2017 22:45:42 +0200 Max Grobecker <max.grobecker@ml.grobecker.info> wrote:
But: When I lookup this IP address on https://stat.ripe.net/073.000.255.229 the first octet is internally getting swapped to "59". This can be explained, if you take "073" as an octal value and convert it to a decimal value. It is definitely a octal-to-decimal conversion thing, as for example also the value "010" is getting replaced by "8" and so on.
Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged?
This weird conversion also happens inside the "geoiplookup" tool by MaxMind and I'm not sure if I'm going to be the moron in this story or if I found the same bug inside multiple softwares at once ;-)
There are many ways to write an IP address, and yes, leading zeroes mean the octal form. Even basic utilities like "ping" use this conversion: $ ping 010.020.030.040 PING 010.020.030.040 (8.16.24.32) 56(84) bytes of data. ^C --- 010.020.030.040 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms Another way is to give a full 32-bit number as integer: $ ping 728374928 PING 728374928 (43.106.30.144) 56(84) bytes of data. ^C --- 728374928 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1015ms Or you can skip zeroes (almost like in IPv6): $ ping 10.9 PING 10.9 (10.0.0.9) 56(84) bytes of data. ^C --- 10.9 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1015ms So what you found is not a bug, but a common behavior. I'm sure all of this is described in great detail in some 40 year old RFC. -- With respect, Roman
Max Grobecker wrote:
Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged?
It was never defined in the rfcs, but by rfc convention, leading zeros should probably be interpreted as decimal (e.g. rfc790). The problem is, inet_aton() interprets leading zeros as octal, and on any operating system which uses the bsd socket library, the address may get converted into octal, or may not, depending on whether the program is using inet_aton(), which assumes octal if there are leading zeros, or getaddrinfo(), which will interpret as decimal in all cases, because POSIX was a bit more careful about the definition. In other words, you have no idea a priori what someone else's code will do, so unless you're ok about your output being interpreted as random garbage, you should avoid zero-padding at all costs. Nick
Hi Max, On RIPEstat having leading zeros in the octets is a very uncommon query pattern but since this behaviour is an inconsistency in the parsing for prefixes and IP addresses, it has been changed so that leading zeros are ignored. This change affects IP addresses and IP ranges. Hth, Christian On 25/10/2017 22:45, Max Grobecker wrote:
Hello,
is there - by standard - a definition on how to represent an IPv4 address?
I have (for example) the IP address "73.0.255.229", which can IMHO also be written as "073.000.255.229" as the leading zeroes are not giving any changes to the binary representation of this address. Am I right on this?
But: When I lookup this IP address on https://stat.ripe.net/073.000.255.229 the first octet is internally getting swapped to "59". This can be explained, if you take "073" as an octal value and convert it to a decimal value. It is definitely a octal-to-decimal conversion thing, as for example also the value "010" is getting replaced by "8" and so on.
Now I'm puzzled: Of course, writing IPv4 octets with leading zeroes is not very common. But: Is it officially prohibited or discouraged?
This weird conversion also happens inside the "geoiplookup" tool by MaxMind and I'm not sure if I'm going to be the moron in this story or if I found the same bug inside multiple softwares at once ;-)
Thanks and greetings from Wuppertal Max
participants (8)
-
Christian Teuschel
-
Hugo Salgado-Hernández
-
Max Grobecker
-
Nick Hilliard
-
Peter J. Holzer
-
Philip Homburg
-
Phillip Remaker
-
Roman Mamedov