lduchosal / ipnetwork

IPNetwork command line and C# library take care of complex network, IP, IPv4, IPv6, netmask, CIDR, subnet, subnetting, supernet, and supernetting calculation for .NET developers. It works with IPv4 as well as IPv6, is written in C#, has a light and clean API, and is fully unit-tested
BSD 2-Clause "Simplified" License
487 stars 99 forks source link

CIDR ranges /32 and /31 don't give correct count #109

Open BishoyDemian opened 4 years ago

BishoyDemian commented 4 years ago

CIDR ranges /32, and /31 when given to the library to parse and then querying range.Usable, I get back a (0) where the .FirstUsable and .LastUsable properties are correctly showing a valid IP Address.

image

agowa commented 4 years ago

I'd say this is intentional. Usable returns the first free address. And within a /32 there is just no address "usable", as the zero address is the netmask. It also correctly shows that there is a total of 1 IPs in the subnet (this might be what you want to use instead for your usecase). But however why First and Last Usable IP are set at all might qualify as a bug.

If usable was 1 it would lead to an inconsistency, as within /24 you also only have 254 usable addresses and not 256. It does not mean that .0 and .255 are invalid addresses, they are just not usable for devices.

lduchosal commented 4 years ago

I'd also say that this is intended behaviour.

However, having 0 usable adresses and still having FirstUsable and LastUsable other than NULL is misleading.

That would definitively break the test suite if we NULL FirstUsable and LastUsable when usable = 0.
That would definitively break the test suite if we thrown Exception on FirstUsable and LastUsable when usable = 0.

I'd vote for :

Any help would be appreciated.

fravelgue commented 4 years ago

Maybe, I don't understand correctly. But It should be an IP network with an IP Address available 192.168.1.1 (in example)

https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks

lduchosal commented 4 years ago

Thanks you fravelgue for the reference

This is what we have today : Address Mask Total Usable Network Broadcast FirstUsable LastUsable
1.0.0.1/32 255.255.255.255 1 0 1.0.0.1 1.0.0.1 1.0.0.1 1.0.0.1
1.0.0.1/31 255.255.255.254 2 0 1.0.0.1 1.0.0.2 1.0.0.1 1.0.0.2

According to : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks We should have :

Address Mask Total Usable Network Broadcast FirstUsable LastUsable Typical use
1.0.0.1/32 255.255.255.255 1 1 1.0.0.1 1.0.0.1 1.0.0.1 1.0.0.1 Host route
1.0.0.1/31 255.255.255.254 2 2 1.0.0.1 1.0.0.2 1.0.0.1 1.0.0.2 Point-to-point links (RFC 3021)

Would that be OK for everyone ?

BishoyDemian commented 4 years ago

That looks correct to me.

Thanks for looking into this.

On Aug 28, 2020 at 11:06 pm, <lduchosal (mailto:notifications@github.com)> wrote:

Thanks you fravelgue for the reference

This is what we have today :

Address

Mask

Total

Usable

Network

Broadcast

FirstUsable

LastUsable

1.0.0.1/32

255.255.255.255

1

0

1.0.0.1

1.0.0.1

1.0.0.1

1.0.0.1

1.0.0.1/31

255.255.255.254

2

0

1.0.0.1

1.0.0.2

1.0.0.1

1.0.0.2

According to : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks We should have :

Address

Mask

Total

Usable

Network

Broadcast

FirstUsable

LastUsable

Typical use

1.0.0.1/32

255.255.255.255

1

1

1.0.0.1

1.0.0.1

1.0.0.1

1.0.0.1

Host route

1.0.0.1/31

255.255.255.254

2

2

1.0.0.1

1.0.0.2

1.0.0.1

1.0.0.2

Point-to-point links (RFC 3021)

Would that be OK for everyone ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub (https://github.com/lduchosal/ipnetwork/issues/109#issuecomment-682542112), or unsubscribe (https://github.com/notifications/unsubscribe-auth/AAPUMCJN3DGX5C6VL2LWUSLSC6TWRANCNFSM4OVIMHPA).

agowa commented 4 years ago

We should have :

Address Mask Total Usable Network Broadcast FirstUsable LastUsable Typical use 1.0.0.1/32 255.255.255.255 1 1 1.0.0.1 1.0.0.1 1.0.0.1 1.0.0.1 Host route 1.0.0.1/31 255.255.255.254 2 2 1.0.0.1 1.0.0.2 1.0.0.1 1.0.0.2 Point-to-point links (RFC 3021) Would that be OK for everyone ?

No that causes weird issues when subnetting. It should be 0 usable addresses for both and FirstUsable and LastUsable should be $null The /32 network contains one address, but it is not usable, as Usable address means neither network nor broadcast. With the same reason the /31 network contains two addresses, but also none of them is usable. Instead of introducing special cases into the "Usable" attribute (e.g. /24 also only return 254 and not 256) there should be a "First" and "Last" Address attribute that ignores network and broadcast addresses and represent the boundary of the network and not of the assignable host space.

Therefore it should be: Address Mask Total Usable Network Broadcast FirstUsable LastUsable First Last
1.0.0.1/32 255.255.255.255 1 0 1.0.0.1 $null $null $null 1.0.0.1 1.0.0.1
1.0.0.1/31 255.255.255.254 2 0 1.0.0.1 1.0.0.2 $null $null 1.0.0.1 1.0.0.2

Source for that:

In common usage, the first address in a subnet, all binary zero in the host identifier, is reserved for referring to the network itself, while the last address, all binary one in the host identifier, is used as a broadcast address for the network; this reduces the number of addresses available for hosts by 2. As a result, a /31 network, with one binary digit in the host identifier, would be unusable, as such a subnet would provide no available host addresses after this reduction.

GF-Huang commented 3 years ago

This issue has a label bug and still not close. Is it still not fixed and not published to nuget?

lduchosal commented 3 years ago

Dear @GF-Huang ,

The problem is that the Usable attribute is not in sync with FirstUsable and LastUsable. @agowa338 solution seems like a good way to solve this problem with little breaking change.

I would gladly accept pull request with full unit test coverage to release a nuget version 2.6...