Aug 272014
 

This post came about because HP (in their infinite wisdom) decided to make the web-based printer control all neat and tidy by aligning all of the IP columns and filling up the space with leading zeros. Spotted the problem yet?

Well you’re quicker than I was; although I had the advantage of knowing that something was wrong and that somebody had pasted that IP address with leading zeros, it took me a few seconds to wonder if it was just possible that leading zeros might be doing something “odd”.

The thing about IPv4 addresses (and IPv6 as well, but I’ll not be pasting in examples for those as they’re too long) is that they are not simply what we see on screen as 10.0.0.1 (or whatever). That representation is converted into a 32-bit binary number which is used as the address. As an example :-

✓ mike@pica» ping -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_req=1 ttl=255 time=0.688 ms

--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.688/0.688/0.688/0.000 ms
✓ mike@pica» ping -c 1 167772161  
PING 167772161 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_req=1 ttl=255 time=6.04 ms

--- 167772161 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.040/6.040/6.040/0.000 ms

As you can see, you do not have to use the conventional “dotted quad” representation; you can use the integer equivalent instead. You can also see why the “dotted quad” representation was invented!

To convert the “dotted quad” notation to an integer that can be used at the lowest level, certain calculations are performed. Either because of a peculiar clause in the original specifications of IPv4 addresses, or (and potentially more likely) as a side effect of one of the earliest implementations of IPv4, certain other representations are possible :-

✓ mike@pica» ping -c 1 0xa.0.0.1
PING 0xa.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_req=1 ttl=255 time=1.34 ms

--- 0xa.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.341/1.341/1.341/0.000 ms
✓ mike@pica» ping -c 1 012.0.0.1
PING 012.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_req=1 ttl=255 time=1.03 ms

--- 012.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.034/1.034/1.034/0.000 ms

As you can see, each individual octet (the numbers between the dots) can be represented in decimal (as we expect), in hexadecimal (by prepending “0x”), or most dangerously, octal (by prepending at least one “0”).

So an apparently innocuous IP address like 10.0.0.030 will actually by converted into an integer that can be converted back into a more usual 10.0.0.24 :-

✓ mike@pica» ping 10.0.0.030
PING 10.0.0.030 (10.0.0.24) 56(84) bytes of data.

There are several lessons to learn from this :-

  1. HP needs slapping with a really rotten haddock to make them realise that their printers have web interfaces that are unhelpful in the extreme.
  2. Leading zeros may be harmful, or at least may result in being slapped with a rotten haddock.
  3. Leading zeros in IP addresses indicate the use of octal and so the result may not be what you expect.
  4. Reading the screen can be helpful when diagnosing problems. It may be easy to miss, but there are clues enough to solve this little challenge even without knowing about octal.