How to Check if an IP range is valid in C#

By FoxLearn 3/20/2025 2:03:58 AM   38
If you have an IP range defined by a starting and ending IP address (e.g., from user input or a configuration file), you can validate it using the following steps:
  1. Parse and validate the IP addresses.
  2. Convert the IP addresses to byte arrays.
  3. Convert the byte arrays to integers (uint for IPv4, BigInteger for IPv6).
  4. Compare the integers: Ensure the starting IP integer is less than the ending IP integer.

Example: For IPs "192.168.0.1" and "192.168.0.11", you get the following:

StringByte ArrayInteger
Starting IP[192, 168, 0, 1]3232235521
Ending IP[192, 168, 0, 11]3232235531

By comparing the integers (3232235521 < 3232235531), we confirm the range is valid.

using System.Net;
using System.Net.Sockets;
using System.Numerics;

bool IsRangeValid(string ipRangeStart, string ipRangeEnd)
{
    if (!IPAddress.TryParse(ipRangeStart, out IPAddress startIP)
        || !IPAddress.TryParse(ipRangeEnd, out IPAddress endIP)
        || startIP.AddressFamily != endIP.AddressFamily)
    {
        return false;
    }

    byte[] startIPBytes = startIP.GetAddressBytes();
    Array.Reverse(startIPBytes);
    byte[] endIPBytes = endIP.GetAddressBytes();
    Array.Reverse(endIPBytes);

    if (startIP.AddressFamily == AddressFamily.InterNetwork)
    {
        return BitConverter.ToUInt32(startIPBytes, 0) < BitConverter.ToUInt32(endIPBytes, 0);
    }
    else
    {
        Array.Resize(ref startIPBytes, startIPBytes.Length + 1);
        Array.Resize(ref endIPBytes, endIPBytes.Length + 1);

        return new BigInteger(startIPBytes) < new BigInteger(endIPBytes);
    }
}

Testing the Validation:

using System;
using System.Collections.Generic;

var tests = new List<(string start, string end)>
{
    (start: "192.168.0.1", end: "192.168.0.11"),
    (start: "192.168.1.50", end: "192.168.2.10"),
    (start: "0000:0000:0000:0000:0000:0000:0000:0000", end: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
    (start: "abc", end: "192.168.0.11"), // Invalid IP
    (start: "192.168.0.1", end: "0000:0000:0000:0000:0000:0000:0000:0000"), // IPv4 vs IPv6
    (start: "192.168.0.11", end: "192.168.0.1"), // Invalid range
    (start: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", end: "0000:0000:0000:0000:0000:0000:0000:0000") // Invalid range
};

foreach (var testCase in tests)
{
    var rangeValid = IsRangeValid(testCase.start, testCase.end);
    Console.WriteLine($"Range: {testCase.start} - {testCase.end}. Is Valid: {rangeValid}");
}

Output:

Range: 192.168.0.1 - 192.168.0.11. Is Valid: True
Range: 192.168.1.50 - 192.168.2.10. Is Valid: True
Range: 0000:0000:0000:0000:0000:0000:0000:0000 - ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff. Is Valid: True
Range: abc - 192.168.0.11. Is Valid: False
Range: 192.168.0.1 - 0000:0000:0000:0000:0000:0000:0000:0000. Is Valid: False
Range: 192.168.0.11 - 192.168.0.1. Is Valid: False
Range: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff - 0000:0000:0000:0000:0000:0000:0000:0000. Is Valid: False

Checking if an IP Address is within a Range

Once you know that an IP range is valid, you can check if a specific IP address falls within that range. To do so:

  1. Validate the IP address.
  2. Convert all the IP addresses to byte arrays.
  3. Convert the byte arrays to integers.
  4. Check if the IP is within the range: Ensure the starting IP ≤ IP to check ≤ ending IP.
bool RangeContainsIPAddress(string ipRangeStart, string ipRangeEnd, string ipAddress)
{
    var startIP = IPAddress.Parse(ipRangeStart);
    var endIP = IPAddress.Parse(ipRangeEnd);

    if (!IPAddress.TryParse(ipAddress, out IPAddress ipAddressToCheck)
        || startIP.AddressFamily != ipAddressToCheck.AddressFamily)
    {
        return false;
    }

    byte[] startIPBytes = startIP.GetAddressBytes();
    Array.Reverse(startIPBytes);
    byte[] endIPBytes = endIP.GetAddressBytes();
    Array.Reverse(endIPBytes);
    byte[] checkIPBytes = ipAddressToCheck.GetAddressBytes();
    Array.Reverse(checkIPBytes);

    if (startIP.AddressFamily == AddressFamily.InterNetwork)
    {
        var checkIPInteger = BitConverter.ToUInt32(checkIPBytes);
        return BitConverter.ToUInt32(startIPBytes, 0) <= checkIPInteger &&
               checkIPInteger <= BitConverter.ToUInt32(endIPBytes, 0);
    }
    else
    {
        Array.Resize(ref startIPBytes, startIPBytes.Length + 1);
        Array.Resize(ref endIPBytes, endIPBytes.Length + 1);
        Array.Resize(ref checkIPBytes, checkIPBytes.Length + 1);

        var checkIPBigInteger = new BigInteger(checkIPBytes);

        return new BigInteger(startIPBytes) <= checkIPBigInteger &&
               checkIPBigInteger <= new BigInteger(endIPBytes);
    }
}

Usage:

using System;
using System.Collections.Generic;

var tests = new List<(string start, string end, string check)>
{
    (start: "192.168.0.1", end: "192.168.0.11", check: "192.168.0.5"), // in range
    (start: "192.168.0.1", end: "192.168.0.11", check: "abc"), // invalid IP
    (start: "192.168.0.1", end: "192.168.0.11", check: "192.168.0.50"), // not in range
    (start: "1111:1111:1111:1111:1111:1111:1111:1111", end: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", check: "0000:0000:0000:0000:0000:0000:0000:0001") // ip < start
};

foreach (var testCase in tests)
{
    var rangeContains = RangeContainsIPAddress(testCase.start, testCase.end, testCase.check);
    Console.WriteLine($"Does range {testCase.start} - {testCase.end} contain {testCase.check}? {rangeContains}.");
}

This code lets you verify whether an IP address is within a given range.