Search code examples
cidr

Subnet CIDR: Does the ip need be the first ip in the subnet?


When define a subnet, such as 1.2.3.0/24, it means 255 hosts in the subnet start from 1.2.3.0 to 1.2.3.255.

But what if I wrongly define the subnet with 1.2.3.64/24? Does it then mean the range is start from 1.2.3.64 to 1.2.3.255?

I could not find a formal document about this.

EDIT: in Java ipaddress lib (5.2.1), the 1.2.3.64/24 will be treated as range from 1.2.3.64 to 1.2.3.255, instead of 1.2.3.0 to 1.2.3.255!. The code is: new IPAddressString("1.2.3.64/24").getSequentialRange()

EDIT: My apology: the above description of ipaddress lib's behavior is wrong. It was other things that caused me think the the range become 1.2.3.64 to 1.2.3.255. Indeed, the

new IPAddressString("1.2.3.64/24").getSequentialRange().getLower()

is 1.2.3.64, and

new IPAddressString("1.2.3.64/24").getSequentialRange().getUpper()

is also 1.2.3.64, so I think this is a reasonable implementation!. I have no problem of that.

The

new IPAddressString("1.2.3.64/24").getAddress().toPrefixBlock().getLower()`
will be the expect one: 1.2.3.0.
And the `.getUpper()` is 1.2.3.255.
so this is the perfect way to get correct ip range.

Solution

  • There is no formal specification indicating that setting the un-fixed bits (the host bits) to 0 is a convention. However, it is common practice when describing a subnet as opposed to a single address, that you leave the host bits as zero. It is an informal convention. If you are describing a subnet, why would you set those bits to anything other than zero if they are intended to be ignored? So that is what all network engineers and most other people do, they leave the bits as zero when they are describing the full subnet, when the host can take on any value.

    The specification for something like 1.2.3.64/24 is that the network part of the address is the first 24 bits, and the host part of the address is the remaining 8 bits. So, the network is 1.2.3.0 and the host is 0.0.0.64. The specification says nothing else.

    Likewise, 1.2.3.0/24 indicates the network is 1.2.3.0 and the host is 0.0.0.0. However, like I said, when the host is 0, that is commonly used to refer to the entire subnet, meaning the host can take on any value. When people write down a string for that subnet of 255 addresses, they will write 1.2.3.0/24.

    In fact, it is unusual to see 1.2.3.0 used as a single address because many routers do not accept a host of 0.

    How you parse those things is specific to any library. Some libraries parse 1.2.3.64/24 as the whole subnet, throwing out the 0.0.0.64. Some libraries parse 1.2.3.64/24 as 1.2.3.64. Some libraries have separate methods to do one or the other.

    With the IPAddress library, the same parser parses both addresses and subnets. When it parses 1.2.3.64/24 or 1.2.3.0/24, the parser needs to decide what you mean by each. For the former, it interprets 1.2.3.64/24 as the address 1.2.3.64 with prefix length 24, because why else is the 0.0.0.64 there at all if you do not intend that 64 to mean something? Why throw it out?

    For 1.2.3.0/24, it interprets that as the whole subnet, because, like I said, a host of 0 is commonly used to refer to the entire subnet, and it is rare to use 1.2.3.0 as an address.

    However, if you wish to choose some other meaning when parsing those things, the library provides other options.

    There is no formal specification for this. In fact, there is no formal specification for a lot of the different aspects of IP addressing, a lot of it is informal and simply evolved over the years to the common practices in use.

    new IPAddressString("1.2.3.64/24").getSequentialRange() is parsed as the range "1.2.3.64 -> 1.2.3.64". Earlier versions of the library behaved differently, but that is how all the latest releases for the last few years parse it.

    Disclaimer: I am the project manager of that library.