Skip to content

Bitvantage.InternetProtocol.IPNetworkExtensions 1.1.0

Choose a tag to compare

@Bitvantage Bitvantage released this 12 Nov 12:58
· 2 commits to main since this release

Adds subnet sizing, variable-length subnet masking (VLSM) allocation, and ContainsStrict, an address test that gives the same answer on every version of .NET. The release only adds members, so code written for 1.0.0 builds unchanged.

dotnet add package Bitvantage.InternetProtocol.IPNetworkExtensions --version 1.1.0

Address planning

  • IPNetwork.GetPrefixLengthForAddresses gives the longest prefix length whose networks hold a number of addresses. It counts every address, where GetPrefixLengthForHosts leaves out the ones a host can't use, which differ between IPv4 and IPv6: 256 addresses need a /24 or a /120, and 256 hosts a /23 or a /119.
  • IPNetwork.GetPrefixLengthForSubnets sizes a network for a number of subnets of one prefix length, such as 300 /64s, which need a /55, or for one subnet of each of several prefix lengths, such as a /23, a /24 and a /26, which need a /22.
  • AllocateSubnets and TryAllocateSubnets lay out a VLSM plan inside a network, around any networks already allocated, and return the subnets in the order requested. Each subnet goes in the smallest free block that holds it, so the subnets fit whenever any arrangement of them fits. A subnet never moves once it is placed, so a plan grows by passing back the subnets it already has.
var block = IPNetwork.ParseStrict("10.0.0.0/22");
var vlans = block.AllocateSubnets([26, 24, 23]);   // 10.0.0.0/26, 10.0.1.0/24, 10.0.2.0/23
var added = block.AllocateSubnets([25], vlans);    // 10.0.0.128/25

IPv4-mapped addresses

  • ContainsStrict tests whether an address is in a network while keeping IPv4 and IPv6 apart, as the subnet and supernet tests do, with the same answer on every version of .NET. The built-in IPNetwork.Contains keeps them apart on .NET 8 and maps IPv4-mapped IPv6 addresses such as ::ffff:10.1.2.3 to IPv4 from .NET 9 on. On .NET 9 and .NET 10 it also tests them wrongly against IPv6 networks (dotnet/runtime#131861, fixed in .NET 11), so the public client ::ffff:1.2.3.4 is in fc00::/7, one of the private networks.
  • Unmap() on a network converts an IPv4-mapped IPv6 network, such as ::ffff:10.0.0.0/104, to the IPv4 network 10.0.0.0/8. It is the network form of IPAddress.Unmap.

Fixes

  • The migration guide mapped NetworkPrefix.Contains(IPAddress) to the built-in IPNetwork.Contains. NetworkPrefix kept IPv4 and IPv6 apart and the built-in does not from .NET 9 on, so code migrated that way compiles but can match an IPv4-mapped address against IPv4 networks. The guide now maps it to ContainsStrict. If you migrated from NetworkPrefix with 1.0.0, check your calls to Contains(IPAddress).

See the changelog and the README for more.