Hi, in .NET8 you have added IpNetwork struct. It allows to check if given IpAddress is within given network. Until .NET8 we had to relay on external library that provided such type. This great you provided your own implementation since it is over 34 times more efficient than its opensource competitor additionally almost zero allocations are made when constructing this instance or checking if it contains given IpAddress :+1: .
However it seems you type is very constrained for now we miss additional features like:
1) possibility to calculate Network for given IpAddress and PrefixLength
2) possibility to calculate Broadcast for given IpNetwork
3) possibility to check if one IpNetwork contains another IpNetwork
Do you plan such functionalities in any form in upcoming releases also does my proposals make sens when it comes to logic of such contains and broadcast address calculations ?
API Proposal
1) Possibility to calculate Network for given IpAddress and PrefixLength:
public static IPAddress CalculateNetwork(IPAddress baseAddress, int prefixLength)
{
if (baseAddress.AddressFamily == AddressFamily.InterNetwork)
{
// The cast to long ensures that the mask becomes 0 for the case where 'prefixLength == 0'.
uint mask = (uint)((long)uint.MaxValue << (32 - prefixLength));
if (BitConverter.IsLittleEndian)
{
mask = BinaryPrimitives.ReverseEndianness(mask);
return new IPAddress(baseAddress.PrivateAddress & mask);
}
else
{
UInt128 value = default;
baseAddress.TryWriteBytes(MemoryMarshal.AsBytes(new Span<UInt128>(ref value)), out int bytesWritten);
Debug.Assert(bytesWritten == IPAddressParserStatics.IPv6AddressBytes);
if (prefixLength == 0)
{
return new IPAddress(UInt128.Zero);
UInt128 mask = UInt128.MaxValue << (128 - prefixLength);
if (BitConverter.IsLittleEndian)
{
mask = BinaryPrimitives.ReverseEndianness(mask);
return new IPAddress(value & mask);
}
}
2) Possibility to calculate Broadcast for given IpNetwork:
Since BaseAddress is Network as I understand it than you could calculate BroadcastAddress on demand using such approach. If you consider it better it could be calculated upfront in ctor.
public IPAddress BroadcastAddress
{
get
{
if (BaseAddress.AddressFamily == AddressFamily.InterNetwork)
{
// The cast to long ensures that the mask becomes 0 for the case where 'prefixLength == 0'.
uint mask = (uint)((long)uint.MaxValue << (32 - PrefixLength));
if (BitConverter.IsLittleEndian)
{
mask = BinaryPrimitives.ReverseEndianness(mask);
return new IPAddress(BaseAddress.PrivateAddress + ~mask);
}
else
{
UInt128 value = default;
BaseAddress.TryWriteBytes(MemoryMarshal.AsBytes(new Span<UInt128>(ref value)), out int bytesWritten);
Debug.Assert(bytesWritten == IPAddressParserStatics.IPv6AddressBytes);
if (PrefixLength == 0)
{
return new IPAddress(UInt128.MaxValue);
UInt128 mask = UInt128.MaxValue << (128 - PrefixLength);
if (BitConverter.IsLittleEndian)
{
mask = BinaryPrimitives.ReverseEndianness(mask);
return IPAddress(value + ~mask);
}
}
}
3) Possibility to check if one IpNetwork contains another IpNetwork:
Given we have Network address and Broadcast address we can check if network is subset of current network with such approach.
public bool Contains(IPNetwork network) => Contains(network.BaseAddress) && Contains(network.BroadcastAddress);
API Usage
public void UsageSample(IPNetwork subnet)
{
// finds our network address is "10.0.0.0"
var networkAddress = IPNetwork.CalculateNetwork(IPAddress.Parse("10.0.0.2"), 8);
var network = new IPNetwork(networkAddress, 8);
if (network.Contains(subnet))
{
// this is subnet of our network - do some work
}
}
Background and motivation
Hi, in .NET8 you have added
IpNetwork
struct. It allows to check if givenIpAddress
is within given network. Until .NET8 we had to relay on external library that provided such type. This great you provided your own implementation since it is over 34 times more efficient than its opensource competitor additionally almost zero allocations are made when constructing this instance or checking if it contains givenIpAddress
:+1: .However it seems you type is very constrained for now we miss additional features like: 1) possibility to calculate
Network
for givenIpAddress
andPrefixLength
2) possibility to calculateBroadcast
for givenIpNetwork
3) possibility to check if oneIpNetwork
contains anotherIpNetwork
Do you plan such functionalities in any form in upcoming releases also does my proposals make sens when it comes to logic of such contains and broadcast address calculations ?
API Proposal
1) Possibility to calculate
Network
for givenIpAddress
andPrefixLength
:You already have that logic in code I believe you just do not expose it, you could of course extract common part to private method for both (https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs#L205-L236).
2) Possibility to calculate
Broadcast
for givenIpNetwork
:Since
BaseAddress
isNetwork
as I understand it than you could calculate BroadcastAddress on demand using such approach. If you consider it better it could be calculated upfront in ctor.3) Possibility to check if one
IpNetwork
contains anotherIpNetwork
:Given we have Network address and Broadcast address we can check if network is subset of current network with such approach.
API Usage
Alternative Designs
No response
Risks
No response