Vivek
Vivek

Reputation: 9

Generate IP which lie in between start and end values of IPv6

I needed to generate all the IP(s) which lie in between a given start and end IP in case of IPv6.

For Example Say start IP is 2001:db8:85a3:42:1000:8a2e:370:7334 and End IP is 2001:db8:85a3:42:1000:8a2e:370:7336.

I need to get all IP that lie in between.

Regards

Upvotes: 0

Views: 113

Answers (1)

xanatos
xanatos

Reputation: 111870

You could:

public static IEnumerable<IPAddress> FromTo(IPAddress from, IPAddress to)
{
    if (from == null || to == null)
    {
        throw new ArgumentNullException(from == null ? "from" : "to");
    }

    if (from.AddressFamily != to.AddressFamily)
    {
        throw new ArgumentException("from/to");
    }

    long scopeId;

    // ScopeId can be used only for IPv6
    if (from.AddressFamily == AddressFamily.InterNetworkV6)
    {
        if (from.ScopeId != to.ScopeId)
        {
            throw new ArgumentException("from/to");
        }

        scopeId = from.ScopeId;
    }
    else
    {
        scopeId = 0;
    }

    byte[] bytesFrom = from.GetAddressBytes();
    byte[] bytesTo = to.GetAddressBytes();

    while (true)
    {
        int cmp = Compare(bytesFrom, bytesTo);

        if (cmp > 0)
        {
            break;
        }

        if (scopeId != 0)
        {
            // This constructor can be used only for IPv6
            yield return new IPAddress(bytesFrom, scopeId);
        }
        else
        {
            yield return new IPAddress(bytesFrom);
        }

        // Second check to handle case 255.255.255.255-255.255.255.255
        if (cmp == 0)
        {
            break;
        }

        Increment(bytesFrom);
    }
}

private static int Compare(byte[] x, byte[] y)
{
    for (int i = 0; i < x.Length; i++)
    {
        int ret = x[i].CompareTo(y[i]);

        if (ret != 0)
        {
            return ret;
        }
    }

    return 0;
}

private static void Increment(byte[] x)
{
    for (int i = x.Length - 1; i >= 0; i--)
    {
        if (x[i] != 0xFF)
        {
            x[i]++;
            return;
        }

        x[i] = 0;
    }
}

and then:

var addr1 = IPAddress.Parse("2001:db8:85a3:42:1000:8a2e:370:7334");
var addr2 = IPAddress.Parse("2001:db8:85a3:42:1000:8a2e:371:7336");

foreach (IPAddress addr in FromTo(addr1, addr2))
{
    Console.WriteLine(addr);
}

Note that, as written, the code is compatible with both IPv4, IPv6 and IPv6 with Scope Id (like 2001:db8:85a3:42:1000:8a2e:370:7334%100)

Upvotes: 1

Related Questions