36

I am working on a change in a Java EE application that would authenticate based on the user's IP address using ServletRequest.getRemoteAddr. We store IP address ranges (FROM_IP and TO_IP) in a database and the system would authenticate only if a user's IP address falls in a range.

Now, testers have pointed out that digit 0 (zero) should not be allowed in FROM_IP and TO_IP values (in any place). Note that this is an Internet facing application, and so we will get only public IP addresses.

Are testers right in suggesting that validation? Why can't we have zero in the range value such as in 167.23.0.1 - 167.23.255.255?

Ritesh
  • 471
  • 1
  • 8
  • 10
  • 11
    And here's the obligatory link to the [How Does Subnetting Work?](http://serverfault.com/questions/49765/how-does-subnetting-work) question. –  Jul 16 '11 at 00:33
  • 8
    I find it surprising that your testers bring this up, when an IPv6 address can contain a dozen 0's. P.S. you really should make your IP address field fit IPv6 addresses if it's not too late. You'll save yourself headaches in the future. – Mark Henderson Jul 16 '11 at 02:42
  • 2
    127.0.0.1 has two zeros? – John Smith Jul 16 '11 at 16:09
  • 127.0.0.1 will never be received by an Internet application. The application would get IP addresses assigned by ISP and they can be looked up in any online tool such as http://whatismyipaddress.com/. – Ritesh Jul 16 '11 at 16:31
  • 1
    By the way, my own IP address showing up on http://whatismyipaddress.com/ has 0 in it (67.xx.0.xx) – Ritesh Jul 16 '11 at 16:39
  • 1
    Similar question here: [Is X.Y.Z.0 a valid IP address?](http://serverfault.com/questions/10985/is-x-y-z-0-a-valid-ip-address) – splattne Aug 12 '11 at 06:14

6 Answers6

73

No, they are completely incorrect.

In fact, this is a valid IP address: 192.168.24.0

As is 167.23.0.1.

Separation of the IP address into dotted segments is a purely human convenience for display. It's a lot easier to remember 192.168.1.42 than 3232235818.

What matters to computers is the separation (netmask). It's not valid to have an host address with the host section of the address set entirely to 0 or 1.

So, 192.168.24.0 as long as the netmask is such that some bits get set in the host part. See the following calculations:


michael@challenger:~$ ipcalc 192.168.24.0/16
Address:   192.168.24.0         11000000.10101000. 00011000.00000000
Netmask:   255.255.0.0 = 16     11111111.11111111. 00000000.00000000
Wildcard:  0.0.255.255          00000000.00000000. 11111111.11111111
=>
Network:   192.168.0.0/16       11000000.10101000. 00000000.00000000
HostMin:   192.168.0.1          11000000.10101000. 00000000.00000001
HostMax:   192.168.255.254      11000000.10101000. 11111111.11111110
Broadcast: 192.168.255.255      11000000.10101000. 11111111.11111111
Hosts/Net: 65534                 Class C, Private Internet

In this case, the address part (right side) has 2 bits set. This is a valid host address in the 192.168.0.0/16 subnet.


michael@challenger:~$ ipcalc 192.168.24.255/16
Address:   192.168.24.255       11000000.10101000. 00011000.11111111
Netmask:   255.255.0.0 = 16     11111111.11111111. 00000000.00000000
Wildcard:  0.0.255.255          00000000.00000000. 11111111.11111111
=>
Network:   192.168.0.0/16       11000000.10101000. 00000000.00000000
HostMin:   192.168.0.1          11000000.10101000. 00000000.00000001
HostMax:   192.168.255.254      11000000.10101000. 11111111.11111110
Broadcast: 192.168.255.255      11000000.10101000. 11111111.11111111
Hosts/Net: 65534                 Class C, Private Internet

In this case, the address part has 10 bits set and 6 bits unset. This is another valid host address in the same subnet.


michael@challenger:~$ ipcalc 192.168.24.0/24
Address:   192.168.24.0         11000000.10101000.00011000. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.24.0/24      11000000.10101000.00011000. 00000000
HostMin:   192.168.24.1         11000000.10101000.00011000. 00000001
HostMax:   192.168.24.254       11000000.10101000.00011000. 11111110
Broadcast: 192.168.24.255       11000000.10101000.00011000. 11111111
Hosts/Net: 254                   Class C, Private Internet

In this case, the address part has zero bits set. This is not a valid host address in the 192.168.24.0/24 network.

MikeyB
  • 38,725
  • 10
  • 102
  • 186
  • 12
    I'll jump onto this answer, which is correct, to add an additional point: the "dotted quad" format for IP addresses, while canonical, is not the only representation format. Try the command `ping 2130706432`, or `ping 017700000001` (yes, even on Windows). You may find yourself surprised by the results. – BMDan Jul 16 '11 at 00:38
  • Cool ;) @BMDan - I think it should be `ping 2130706433` though :) – Mark Henderson Jul 16 '11 at 02:41
  • 5
    http://1076000524 :) – jweyrich Jul 16 '11 at 05:07
  • 1
    While what is said here is indeed true, it is also unfortunately the case that there are a huge number of user interfaces that think a trailing zero (or 255) is bad, regardless of prefix length. – Theobroma Cacao Jul 17 '11 at 06:23
  • @Theobroma Cacao Could you please shade some more light on this? What happens when a user interface thinks that a trailing 0 or 255 is bad? – Ritesh Jul 17 '11 at 12:52
  • @Ritesh: If the interface rejects an entry with a 0 then you cannot use some of the IPs on the network. – Zan Lynx Jul 17 '11 at 17:00
  • @BMDan: Yeah, I alluded to that in my text but forgot to explicitly point out this "unexpected" behaviour. Some OSes also used to overflow parts of the quad - for example `192.168.0.257` would get interpreted as `192.168.1.1`. I can't remember exactly which would do so (XP did I think) and my Linux and Win7 boxes just reject it as an invalid hostname. – MikeyB Jul 18 '11 at 01:30
  • 2
    `192.168.0.257` is incorrect, but `192.168.257` is a correct representation of `192.168.1.1` (as is `192.11010305`). See `inet_aton(3)`. – BMDan Jul 19 '11 at 02:07
  • They are not "completely" incorrect. When the first RFC about IP addresses came out it was indeed forbidden to have a zero in the IP address. It was only allowed later on. That's why you had to set "ip subnet-zero" on Cisco routers. More info about it here: http://www.petri.co.il/csc_ip_subnet_zero.htm – Raffael Luthiger Jul 29 '11 at 22:19
  • 1
    Even Windows XP's networking stack had issues with .255 addresses. Serving websites from XP would cause anyone with an address ending in .255 to be unable to access the site. – Chris Thorpe Jul 29 '11 at 23:07
  • 3
    @Raffael: subnet zero was actually a holdover from the classfull routing days. When you had, say, a Class B network (129.97.0.0/16) the zero subnet would be any network with bits 17→X all set to zero (where X is the length of the subnet). So the network 129.97.0.0/24 would be a zero subnet and disallowed in the early days. Nowadays (thankfully) we use CIDR and don't worry about that. – MikeyB Jul 30 '11 at 00:15
  • 1
    @MikeyB: I know that it is outdated. I just wanted to say that the testers probably do have outdated documentation. So in my point of view they are not totally incorrect but only outdated. And this extra information could help the person who was asking to give a better answer to the testers. Because he can explain them better why they are probably wrong. – Raffael Luthiger Jul 30 '11 at 09:51
  • @Raffael: I was clarifying your point a bit - even in the early days it was still valid to have a zero. It was just not allowed to use the 'zero subnet'. 10.0.100.100/24 would have been valid. – MikeyB Jul 30 '11 at 12:19
18

Unless I'm misunderstanding, your testers are dead wrong. Valid IP addresses can certainly have a 0 in them.

EEAA
  • 108,414
  • 18
  • 172
  • 242
13

In general: No, it doesn't matter if there is a 0 in the address or not.

However, there is a grain of truth in what your testers are saying. In some cases old or broken network equipment will not work correctly on addresses with 0 in the last octests. This is due to the old classfull routing rules. In Classfull routing, you can tell the netmask from the first octet of the address. If the equipment still follows classfull routing rules it is likely to handle an address like 200.100.1.0/16 incorrectly.

pehrs
  • 8,749
  • 29
  • 46
4

Let's say you need 510 IP adresses in one range and your network adress is 192.1.1.0, you would have a /23 subnet, of which one of your host IP's is a .0 IP address, your testers are wrong if the .0 address is a host address. If you have a /24 network it would be right to say it was wrong.

Lucas Kauffman
  • 16,818
  • 9
  • 57
  • 92
3

To provide a very simple answer: One or more zeros in an ip address are perfectly valid for host addresses as long as those addresses are not the network or broadcast address.

Network and broadcast addresses are valid ip addresses, they're just not usable by hosts.

joeqwerty
  • 108,377
  • 6
  • 80
  • 171
  • 1
    what about a broadcast address of X.Y.0.255? – Random832 Jul 16 '11 at 04:38
  • 2
    You can use the network address for a host, and doing so was once a common test of "leetness". Thankfully, though, it has since fallen well out of vogue. In a similar vein, RFC 3021 permits the use of both "broadcast" *and* "network" addresses in a /31, though the terms are arguably somewhat inapplicable when you're only dealing with two hosts to begin with. – BMDan Jul 19 '11 at 02:13
2

If the network range contains more than 256 IPv4 addresses, some of them will contain one or more zeros. As IPv4 addresses are classless you can use sipcalc to verify.

user@linux:~ # sipcalc 10.1.0.0/8 | grep "Usable range"
Usable range            - 10.0.0.1 - 10.255.255.254

user@linux:~ # sipcalc 10.0.0.1/8 | grep "Usable range"
Usable range            - 10.0.0.1 - 10.255.255.254

user@linux:~ # sipcalc 10.0.1.0/8 | grep "Usable range"
Usable range            - 10.0.0.1 - 10.255.255.254