Skip to content

Releases

Bitvantage.InternetProtocol.IPNetworkExtensions 1.1.1

Choose a tag to compare

@Bitvantage Bitvantage released this 12 Nov 15:14

IPNetwork.GetPrefixLengthForSubnets now gives an answer for an empty list instead of throwing, like the other sizing methods do for zero. Nothing else changes, so code written for 1.1.0 builds unchanged.

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

Changed

  • IPNetwork.GetPrefixLengthForSubnets gives a host network, /32 or /128, for an empty list of prefix lengths, where 1.1.0 threw an ArgumentException. That matches GetPrefixLengthForAddresses and GetPrefixLengthForHosts, which give a host network for zero, and the host network holds the empty plan, which AllocateSubnets accepts. A plan built from a list that filters down to nothing now flows through sizing and allocation without a special case.
IPNetwork.GetPrefixLengthForSubnets(IPVersion.IPv4, []);   // 32
IPNetwork.GetPrefixLengthForSubnets(IPVersion.IPv6, []);   // 128

See the changelog for more.

Bitvantage.InternetProtocol.IPNetworkExtensions 1.1.0

Choose a tag to compare

@Bitvantage Bitvantage released this 12 Nov 12:58

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.

Bitvantage.InternetProtocol.IPNetworkExtensions 1.0.0

Choose a tag to compare

@Bitvantage Bitvantage released this 11 Nov 18:57

First release of Bitvantage.InternetProtocol.IPNetworkExtensions: C# 14 extension members for .NET's built-in
System.Net.IPNetwork and IPAddress that add CIDR, subnet and supernet math. It targets .NET 8 and .NET 10 and is
licensed under MIT.

dotnet add package Bitvantage.InternetProtocol.IPNetworkExtensions

The extension members need C# 14, which comes with the .NET 10 SDK. A .NET 10 project has it already; a .NET 8 or
.NET 9 project turns it on with <LangVersion>14</LangVersion>.

Breaking changes from Bitvantage.InternetProtocol.NetworkPrefix

This package succeeds Bitvantage.InternetProtocol.NetworkPrefix 2.0.0. The
migration guide maps
every member and lists every change; the main ones are:

  • The NetworkPrefix class is gone. Its members are extension members on IPNetwork, in the same
    Bitvantage.InternetProtocol namespace, and the containment methods take .NET's set names: IsSubnetOf,
    IsSupernetOf, IsProperSubnetOf and IsProperSupernetOf.
  • ParseStrict accepts only standard dotted-decimal IPv4, so 010.0.0.0/8, which IPAddress reads as octal
    8.0.0.0/8, and shorthand such as 10.0.0/24 are rejected.
  • Parsing no longer looks up host names; IPNetwork.Resolve and ResolveAsync do.
  • Sorting needs IPNetwork.Comparer, since IPNetwork does not implement IComparable.
  • NetworkPrefixJsonConverter is replaced by IPNetworkJsonConverter, and XML serialization is no longer supported.
  • Exclude follows set semantics and returns a sorted list, Summarize returns the sorted minimal set, IPv6 host
    ranges and counts include the last address, and Allocation follows the IANA special-purpose registries.

Features

  • Masks and host ranges: network and wildcard masks, first and last host, host and address counts, and enumeration.
  • Subnet and supernet tests, overlap, splitting, halves, supernets and complementary networks.
  • Set operations on lists of networks: Summarize, Intersect, Exclude and GetRanges.
  • Address ranges: the fewest networks that cover a range, and parsing of text such as 10.0.0.1-10.0.0.9.
  • Address planning: free subnets of a given length with AvailableSubnets, and offsets within a network.
  • Classification by IANA allocation and by class, and the networks of an allocation, such as the private networks.
  • Reverse DNS names and zones, including zones of networks that are not on a label boundary.
  • IPAddress members: strict parsing, comparison, arithmetic, classification, Unmap for IPv4-mapped addresses and
    the expanded IPv6 form.
  • JSON converters for IPNetwork and IPAddress, which also work as dictionary keys and with source-generated
    serialization, and type converters so that configuration binding reads networks and addresses instead of silently
    leaving them empty.
  • Compatible with trimming and native AOT, with Source Link and a symbol package.

Fixes

Compared with NetworkPrefix 2.0.0:

  • Converting an IPv4 address wrote 16 bytes into a 4 byte array, past its end.
  • TryParse threw for an out-of-range prefix length or a mask with gaps, rather than returning false.
  • Text with leading whitespace or extra separators parsed as a /0, and a mask of the other IP version was accepted.
  • GetContainingNetwork returned the IPv4 0.0.0.0/0 for an IPv6 /0.
  • Summarize threw on duplicates or on a network listed with both of its halves, and kept covered networks.
  • Enumerating addresses or hosts never ended at the top of the IPv6 space, and Split(128) of ::/0 overflowed.
  • Allocation reported reserved blocks, and networks that take in special-purpose space, as Global.

See the changelog and the
README for more.