Recently, someone came to me with the problem that some remote IOT-devices received a broken configuration where the first octet of their IP-address was changed to 0 (i.e. from 192.168.0.4 to 0.168.0.4). Because of the location of these devices it was very impractical to go and change the configuration on the device itself, so I was asked if I could figure out a way to fix the configuration by remote.

The devices have a configuration command to set the IP-address, so changing the address by remote was not the problem. However, how are we going to talk to these devices? I only had access to a Windows machine in the same subnet as the devices.

I set up a little test lab with a misconfigured device to see how I could tackle this. I sniffed the network communication with Wireshark to see if the devices were still communicating, and luckely, they were. So the TCP/IP-stack in the device adopted its 0.x.x.x address and was using it instead of stopping the network all together, this was good news.

Trying the Windows route

First attempt was to try and talk to the devices from Windows. A ping from outside the 0.x.x.x subnet was already giving discouraging results; Windows’s TCP/IP-stack would not accept the address:

C:\Users\Thomas>ping 0.168.0.4

Pinging 0.168.0.4 with 32 bytes of data:
PING: transmit failed. General failure.
PING: transmit failed. General failure.

Trying to configure an IP-address on the machine in the 0.x.x.x subnet confirmed that this was not going to work in Windows: 0 is not a valid entry.

Linux then?

Linux does allow me to configure an IP-address in the 0.x.x.x range, so that was encouraging at first:

~# ifconfig eth0 inet 0.168.0.5 netmask 255.0.0.0
~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 0.168.0.5  netmask 255.0.0.0  broadcast 0.255.255.255
        ether 08:00:27:d4:35:1d  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0x80400000-80420000

But again; no traffic possible to the network:

~# ping 0.168.0.4
connect: Invalid argument
~# telnet 0.168.0.4
Trying 0.168.0.4...
telnet: Unable to connect to remote host: Invalid argument

FreeBSD to the rescue!

At this point I was considering hooking up a custom IOT-device to the network through tunneling in order to just send the correct configuration packets, but of course there are OSes other than Windows and Linux, so I gave FreeBSD a try. Surprisingly, FreeBSD allowed me to configure an IP-address in 0.x.x.x and also connect to the ‘lost’ device!

# ifconfig em0 inet 0.168.0.5 netmask 255.0.0.0
# ifconfig em0
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=b<RXCSUM,TXCSUM,VLAN_MTU>
        inet 0.168.0.5 netmask 0xff000000 broadcast 0.255.255.255
        ether 08:00:27:d4:35:1d
        media: Ethernet autoselect (1000baseTX <full-duplex>)
        status: active
# ping 0.168.0.4
PING 0.168.0.4 (0.168.0.4): 56 data bytes
64 bytes from 0.168.0.4: icmp_seq=0 ttl=255 time=1.137 ms
64 bytes from 0.168.0.4: icmp_seq=1 ttl=255 time=1.122 ms
^C
--- 0.168.0.4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.122/1.129/1.137/0.013 ms
# telnet 0.168.0.4
Trying 0.168.0.4...
Connected to 0.168.0.4.
Escape character is '^]'.

In the end, booting a FreeBSD Live CD on VirtualBox on the remote Windows system and netcatting a few configuration commands to the affected devices fixed the IP-configuration on the devices without a time consuming (and costly) trip to physically access the devices.

What’s so special about 0.0.0.0/8?

RFC6890 designates the 0.0.0.0/8 block as a reserved block with a description of ‘this host on this network’. It is only valid as a source address, not as a destination. Section 3.2.1.3 of RFC1122 further specifies that this address must not be used to send from and that it is intended for use as a broadcast address.

It appears Linux and Windows are following these standards more strictly than FreeBSD does. I could not find any further info on the reason for this difference in networking stack implementation. In this case, I was happy I found this difference and was able to restore the lost devices to their correct IP-addresses.