Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find next valid IP Address (IPv4 and IPv6) #111

Open
ChrisLynchHPE opened this issue Jul 23, 2020 · 3 comments
Open

Find next valid IP Address (IPv4 and IPv6) #111

ChrisLynchHPE opened this issue Jul 23, 2020 · 3 comments

Comments

@ChrisLynchHPE
Copy link

I love your C# class here. Extremely useful. However, there is a missing piece in this class library that would be extremely helpful: get the next valid IP address. Is this something that you have thought about adding? I have a helper method I was able to come up with for IPv4 addresses that works really well. But IPv6 addresses are proving to be difficult to work with.

@agowa
Copy link

agowa commented Aug 19, 2020

You could just use the subnet feature e.g. subnet the given prefix into /32 for ipv4 only or /128 for version independence.
[System.Net.IPNetwork]'::ffff:192.168.1.20/128' iterate over the list and use the element right after the one you had.

Alternatively

An ipversion independent version would look like this, all it needs is some basic binary math:

#powershell

$ipaddress = [System.Net.IPAddress]"192.168.2.1"

# We need to increment the byte array, but because of the endian we cannot just do "i++"
# instead we would either need to reverse the byte order add one and than reverse the order again
# or we simply workaround it by adding single ip on top, so we avoid conversion.
# This works because we basically convert the "1" to the other endian,
# for addition the distributive (and commutative) property applies and the byte order reversals cancel each other out.
$oneIP = [bigint]([System.Net.IPAddress]"::1").GetAddressBytes()

$nextIP = [System.Net.IPAddress]([bigint]($ipaddress.MapToIPv6().GetAddressBytes()) + $oneIP).ToByteArray()

$displayAddress = ($nextIP.IsIPv4MappedToIPv6) ? $nextIP.MapToIPv4().IPAddressToString : $nextIP.IPAddressToString
Write-Host "Next usable ip is: $displayAddress"

When dealing with ipv4 and ipv6 addresses it is always easier to just convert the ipv4 to the ipv6 mapped version. Think of IPv6 as the superclass of IPv4.

You can always convert IPv4 addresses to IPv6 addresses. In fact, I tend to always handle them as ipv6 internally and the frontend has to deal with converting the mapped addresses if necessary. That way I get cleaner code and a unified code path. Which also makes it way easier to debug.

@ChrisLynchHPE
Copy link
Author

Thanks for responding. I actually was able to find a solution to this. I extended the IPNetwork class to add a new method IncrementAddress() that would allow one to provide the starting address, and indicate how many to increment by.

# example
$StartingAddress = '192.168.1.1'
$Increment = 23
[System.Net.IPNetwork]::IncrementAddress($StartingAddress , $Increment)

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 33663168
IPAddressToString  : 192.168.1.2

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 50440384
IPAddressToString  : 192.168.1.3

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 67217600
IPAddressToString  : 192.168.1.4

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 83994816
IPAddressToString  : 192.168.1.5

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 100772032
IPAddressToString  : 192.168.1.6

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 117549248
IPAddressToString  : 192.168.1.7

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 134326464
IPAddressToString  : 192.168.1.8

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 151103680
IPAddressToString  : 192.168.1.9

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 167880896
IPAddressToString  : 192.168.1.10

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 184658112
IPAddressToString  : 192.168.1.11

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 201435328
IPAddressToString  : 192.168.1.12

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 218212544
IPAddressToString  : 192.168.1.13

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 234989760
IPAddressToString  : 192.168.1.14

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 251766976
IPAddressToString  : 192.168.1.15

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 268544192
IPAddressToString  : 192.168.1.16

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 285321408
IPAddressToString  : 192.168.1.17

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 302098624
IPAddressToString  : 192.168.1.18

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 318875840
IPAddressToString  : 192.168.1.19

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 335653056
IPAddressToString  : 192.168.1.20

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 352430272
IPAddressToString  : 192.168.1.21

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 369207488
IPAddressToString  : 192.168.1.22

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 385984704
IPAddressToString  : 192.168.1.23

AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
Address            : 402761920
IPAddressToString  : 192.168.1.24

It also handles IPv6 addresses with the same method. Would you see any value of adding this into your class library? If so, I can generate a PR for you to review.

@lduchosal
Copy link
Owner

I would definitvely appreciate contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants