Table of Contents

Class IPAddressUtil

Namespace
VpnHood.Net.Toolkit.Net
Assembly
VpnHood.Net.Toolkit.dll

Provides helpers for IP addresses: comparing and converting them, finding this device's own addresses, and well-known DNS servers.

public static class IPAddressUtil
Inheritance
IPAddressUtil
Inherited Members

Properties

GoogleDnsServers

Gets Google Public DNS's addresses: 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888 and 2001:4860:4860::8844.

public static IReadOnlyList<IPAddress> GoogleDnsServers { get; }

Property Value

IReadOnlyList<IPAddress>

KidsSafeCloudflareDnsServers

Gets the addresses of Cloudflare's 1.1.1.1 for Families that blocks malware and adult content: 1.1.1.3, 1.0.0.3, 2606:4700:4700::1113 and 2606:4700:4700::1003.

public static IReadOnlyList<IPAddress> KidsSafeCloudflareDnsServers { get; }

Property Value

IReadOnlyList<IPAddress>

MaxIPv4Value

Gets the last IPv4 address, 255.255.255.255.

public static IPAddress MaxIPv4Value { get; }

Property Value

IPAddress

MaxIPv6Value

Gets the last IPv6 address, ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff.

public static IPAddress MaxIPv6Value { get; }

Property Value

IPAddress

MinIPv4Value

Gets the first IPv4 address, 0.0.0.0.

public static IPAddress MinIPv4Value { get; }

Property Value

IPAddress

MinIPv6Value

Gets the first IPv6 address, ::.

public static IPAddress MinIPv6Value { get; }

Property Value

IPAddress

ReliableDnsServers

Gets an IPv4 and an IPv6 address of GoogleDnsServers and of KidsSafeCloudflareDnsServers: 8.8.8.8, 2001:4860:4860::8888, 1.1.1.3 and 2606:4700:4700::1113.

public static IReadOnlyList<IPAddress> ReliableDnsServers { get; }

Property Value

IReadOnlyList<IPAddress>

VirtualAdapterMarkers

Gets the names that mark the hypervisor and container adapters no other device can reach: Hyper-V Virtual, vEthernet, VirtualBox, VMware, Docker and WSL.

public static IReadOnlyList<string> VirtualAdapterMarkers { get; }

Property Value

IReadOnlyList<string>

Remarks

GetLanAddresses(AddressFamily, IEnumerable<string>?) leaves out an adapter whose name or description contains one, ignoring case, and that has no gateway: one with a gateway is reachable all the same, as when a Hyper-V external switch moves the PC's own LAN address onto its vEthernet adapter. They are matched by name because the OS reports most of them as plain Ethernet; a VPN's tunnel needs no marker, being known by its type.

Hyper-V Virtual matches the host's side alone: a guest's own card is a Microsoft Hyper-V Network Adapter, on its LAN.

Methods

Anonymize(IPAddress)

Hides the host part of an address, for logs and reports.

public static IPAddress Anonymize(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

IPAddress

The address's /24 network for IPv4, such as 1.2.3.0, or its /48 for IPv6, such as 2001:db8:1::, without the scope id.

Remarks

An IPv4-mapped IPv6 address counts as IPv6, so nothing of its IPv4 address is left.

Compare(IPAddress?, IPAddress?)

Compares two addresses: an IPv4-mapped IPv6 address as its IPv4 address, every IPv4 address before every IPv6 address, then by number, with no regard to the scope id.

public static int Compare(IPAddress? ipAddress1, IPAddress? ipAddress2)

Parameters

ipAddress1 IPAddress

The first address, or null.

ipAddress2 IPAddress

The second address, or null.

Returns

int

A negative number if ipAddress1 comes first, zero if the two compare as the same address, and a positive number if it comes after. A null address comes first.

Remarks

So 10.0.0.2 and ::ffff:10.0.0.2 compare as the same address, as do fe80::1 and fe80::1%3, though Equals(object) tells each pair apart.

Compare(IpAddressValue, IpAddressValue)

Compares two addresses as Compare(IPAddress?, IPAddress?) does: an IPv4-mapped IPv6 address as its IPv4 address, every IPv4 address before every IPv6 address, then by number, with no regard to the scope id.

public static int Compare(IpAddressValue ipAddress1, IpAddressValue ipAddress2)

Parameters

ipAddress1 IpAddressValue

The first address.

ipAddress2 IpAddressValue

The second address.

Returns

int

A negative number if ipAddress1 comes first, zero if the two compare as the same address, and a positive number if it comes after.

Remarks

The default value, which holds no address, comes first, as a null address does. CompareTo(IpAddressValue) keeps an IPv4-mapped address with the IPv6 addresses instead.

Decrement(IPAddress)

Gets the address before an address.

public static IPAddress Decrement(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

IPAddress

The previous address, without the scope id; ipAddress itself when it is the first of its family.

FromBigInteger(BigInteger, AddressFamily)

Converts a number to an address of a family, as ToBigInteger(IPAddress) numbers them.

public static IPAddress FromBigInteger(BigInteger value, AddressFamily addressFamily)

Parameters

value BigInteger

The number: up to 2^32 - 1 for IPv4, up to 2^128 - 1 for IPv6.

addressFamily AddressFamily

The address family.

Returns

IPAddress

The address.

Exceptions

NotSupportedException

addressFamily is neither IPv4 nor IPv6.

ArgumentOutOfRangeException

value is negative, or above the family's last address.

FromLong(long)

Converts a number to an IPv4 address, as ToLong(IPAddress) numbers them: 0x0A000001 is 10.0.0.1.

public static IPAddress FromLong(long ipAddress)

Parameters

ipAddress long

The number. Only its low 32 bits are read.

Returns

IPAddress

The address.

GenerateUlaAddress(ushort)

Generates a random unique local IPv6 address (RFC 4193) that ends in a given value.

public static IPAddress GenerateUlaAddress(ushort lastValue)

Parameters

lastValue ushort

The address's last 16 bits.

Returns

IPAddress

An address in fd00::/8 with a random 40-bit global ID, subnet 0 and lastValue as its last 16 bits, such as fdb6:f6f2:b3c4::1001.

Remarks

The global ID comes from a cryptographic random generator, at each call.

GetAnyIpAddress(AddressFamily)

Gets the address that stands for any address of a family: 0.0.0.0 for IPv4, :: for IPv6.

public static IPAddress GetAnyIpAddress(AddressFamily addressFamily)

Parameters

addressFamily AddressFamily

The address family.

Returns

IPAddress

The address.

Exceptions

NotSupportedException

addressFamily is neither IPv4 nor IPv6.

GetDosKey(IPAddress)

Gets the key under which a server counts a client's requests, to limit a flood from one source.

public static string GetDosKey(IPAddress ip)

Parameters

ip IPAddress

The client's address.

Returns

string

An IPv4 address's text, or an IPv6 address's /64 network, such as 2001:db8:1:2::/64, as one IPv6 subscriber is given a whole /64.

Remarks

An IPv4-mapped IPv6 address counts as the IPv4 address it carries.

Exceptions

ArgumentNullException

ip is null.

GetLanAddresses(AddressFamily, IEnumerable<string>?)

Gets this device's addresses of a family that another device on the local network could dial, best guess first.

public static Task<IReadOnlyList<IPAddress>> GetLanAddresses(AddressFamily addressFamily, IEnumerable<string>? excludeAdapterMarkers = null)

Parameters

addressFamily AddressFamily

The address family: InterNetwork or InterNetworkV6.

excludeAdapterMarkers IEnumerable<string>

The names that mark an adapter no other device can reach, found in its name or description, ignoring case; null for VirtualAdapterMarkers. A marked adapter with a gateway still counts.

Returns

Task<IReadOnlyList<IPAddress>>

A task whose result is the addresses: on a phone or TV usually one, on a PC a few.

Remarks

Which network the other device is on cannot be known from here, so the order is a ranking, not proof: the address on the default route first, as the network with the internet is the one others share, then those of Wi-Fi and Ethernet adapters, then the rest. The default route's address leads only when an adapter below lists it, as a connected VPN holds the default route on Windows.

Left out: adapters that are down, loopback interfaces, VPN tunnels, mobile broadband (a carrier's address that nothing on the local network reaches), marked adapters with no gateway, and every loopback and link-local address, such as the 10.255.255.254 WSL puts on its loopback. An adapter whose state the OS hides counts.

Exceptions

NotSupportedException

addressFamily is neither IPv4 nor IPv6.

NetworkInformationException

The OS could not list the network interfaces.

GetPrimaryIpAddress(AddressFamily)

Gets the address this device sends from to reach the internet over a family: on most devices, its own address on the default route.

public static Task<IPAddress?> GetPrimaryIpAddress(AddressFamily addressFamily)

Parameters

addressFamily AddressFamily

The address family.

Returns

Task<IPAddress>

A task whose result is the address, or null when the device has no route of the family or the family is not supported.

Remarks

It connects a UDP socket to an address of KidsSafeCloudflareDnsServers and reads the local address the OS chose for it; no packet is sent. The address is private only on a private network: a device with a public address gets that. The task is complete when returned, and the method never throws.

GetPrimaryIpAddress(UdpClient)

Gets the address a UDP client's socket sends from to reach the internet: on most devices, its own address on the default route of the client's family.

public static Task<IPAddress?> GetPrimaryIpAddress(UdpClient udpClient)

Parameters

udpClient UdpClient

The client. It is connected to an address of KidsSafeCloudflareDnsServers, port 53, and stays so: pass one made for this.

Returns

Task<IPAddress>

A task whose result is the address, or null when there is no route or the client cannot connect.

Remarks

No packet is sent. The task is complete when returned, and the method never throws.

GetPrimaryIpAddresses()

Gets the addresses this device sends from to reach the internet, IPv4 then IPv6, as GetPrimaryIpAddress(AddressFamily) finds them.

public static Task<IReadOnlyList<IPAddress>> GetPrimaryIpAddresses()

Returns

Task<IReadOnlyList<IPAddress>>

A task whose result is the addresses: none, one or two.

GetPublicIpAddress(AddressFamily, string?, CancellationToken)

Gets this device's public address of a family, as web services see it.

public static Task<IPAddress?> GetPublicIpAddress(AddressFamily addressFamily, string? userAgent, CancellationToken cancellationToken)

Parameters

addressFamily AddressFamily

The address family: InterNetwork or InterNetworkV6.

userAgent string

The name the asking app gives the services in the User-Agent header, such as its package title, sent as it is; null sends VpnHood.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<IPAddress>

A task whose result is the address, or null when no service answered with one.

Remarks

It asks Cloudflare's trace page (www.cloudflare.com/cdn-cgi/trace) over a connection of the family, then, if that fails or answers with no address, my-ip.io's API for the family, each canceled after 5 seconds. A failure of both gives null.

Exceptions

OperationCanceledException

cancellationToken was canceled.

GetPublicIpAddresses(CancellationToken)

Gets this device's public addresses, IPv4 then IPv6, as GetPublicIpAddress(AddressFamily, string?, CancellationToken) finds them, with no app name.

public static Task<IReadOnlyList<IPAddress>> GetPublicIpAddresses(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<IReadOnlyList<IPAddress>>

A task whose result is the addresses found: none, one or two.

Remarks

The two lookups run one after the other; each asks up to two services, each canceled after 5 seconds.

Exceptions

OperationCanceledException

cancellationToken was canceled.

Increment(IPAddress)

Gets the address after an address.

public static IPAddress Increment(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

IPAddress

The next address, without the scope id; ipAddress itself when it is the last of its family.

IsIpv6Supported()

Determines whether this device reaches the internet over IPv6.

public static Task<bool> IsIpv6Supported()

Returns

Task<bool>

A task whose result is true if the device has an IPv6 route and an IPv6 address of ReliableDnsServers answers a ping or a DNS query; otherwise, false.

Remarks

The servers are pinged one after the other, each with Ping's default timeout of 5 seconds; where none answers, as on a network that drops ICMPv6 echo requests, each is sent a DNS query, with 2 seconds for its answer. So the answer can take 14 seconds. It never throws.

IsMaxValue(IPAddress)

Determines whether an address is the last of its family, MaxIPv4Value or MaxIPv6Value.

public static bool IsMaxValue(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

bool

true if it is; otherwise, false.

Remarks

An IPv6 address's scope id is left out of it.

IsMinValue(IPAddress)

Determines whether an address is the first of its family, MinIPv4Value or MinIPv6Value.

public static bool IsMinValue(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

bool

true if it is; otherwise, false.

Remarks

An IPv6 address's scope id is left out of it.

Max(IPAddress, IPAddress)

Returns the higher of two addresses, in Compare(IPAddress?, IPAddress?)'s order.

public static IPAddress Max(IPAddress ipAddress1, IPAddress ipAddress2)

Parameters

ipAddress1 IPAddress

The first address.

ipAddress2 IPAddress

The second address.

Returns

IPAddress

The higher address; ipAddress2 when the two compare as the same.

Min(IPAddress, IPAddress)

Returns the lower of two addresses, in Compare(IPAddress?, IPAddress?)'s order.

public static IPAddress Min(IPAddress ipAddress1, IPAddress ipAddress2)

Parameters

ipAddress1 IPAddress

The first address.

ipAddress2 IPAddress

The second address.

Returns

IPAddress

The lower address; ipAddress2 when the two compare as the same.

ToBigInteger(IPAddress)

Converts an address to its number, its first byte highest.

public static BigInteger ToBigInteger(IPAddress value)

Parameters

value IPAddress

The address.

Returns

BigInteger

The number: up to 2^32 - 1 for IPv4, up to 2^128 - 1 for IPv6. It does not hold the family, which FromBigInteger(BigInteger, AddressFamily) takes too.

ToLong(IPAddress)

Converts an IPv4 address to its number, its first byte highest: 10.0.0.1 is 0x0A000001.

public static long ToLong(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Returns

long

The number, from 0 to 4,294,967,295.

Exceptions

ArgumentException

ipAddress is not IPv4; an IPv4-mapped IPv6 address is not.

Verify(IPAddress)

Checks that an address's family is IPv4 or IPv6.

public static void Verify(IPAddress ipAddress)

Parameters

ipAddress IPAddress

The address.

Remarks

Every IPAddress is one or the other, so the check passes for any address.

Verify(AddressFamily)

Checks that a family is IPv4 or IPv6.

public static void Verify(AddressFamily addressFamily)

Parameters

addressFamily AddressFamily

The address family.

Exceptions

NotSupportedException

addressFamily is neither IPv4 nor IPv6.