Reputation: 9
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
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