-
Notifications
You must be signed in to change notification settings - Fork 99
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
Feature request: IPNetwork Subtract #56
Comments
TrySubstractNetwork is really slow, we need to find a fast algorithm to substract two big subnets. |
Not sure, it's same requirement. But I'm using RangeTree [1] to store ranges of IPs, and searching for IPs in it. |
Thanks for pointing this out. I'll have a look when time permits. |
Rather than trying to subtract ip address via range, I found that adding subnet via binary elimination might be faster. The idea is to split network into two until all the split networks are free of the subtract target. These subnets can be farther split to subtract multiple networks. Finally the split parts free from subtract networks can be joined together. |
I don't know why one wants to subtract IP addresses, but it could easily be done using something like this: #powershell
$minuend = ([System.Net.IPAddress]"192.168.2.27").MapToIPv6()
$subtrahend = ([System.Net.IPAddress]"0.0.2.0").MapToIPv6()
$difference = [System.Net.IPAddress]([bigint]($minuend.GetAddressBytes()) - [bigint]($subtrahend.GetAddressBytes())).ToByteArray()
$displayAddress = ($difference.IsIPv4MappedToIPv6) ? $difference.MapToIPv4().IPAddressToString : $difference.IPAddressToString
Write-Host "Next usable ip is: $displayAddress" |
0.0.0.0/0 - 10.0.0.1/32 = [
] |
Exactly. This is how it's supposed to be done and can be very fast since all you do is split recursively. I have implemented the algorithm here (disclaimer, stating the obvious: author here). For an example: var network = NetworkHelper.Parse("192.168.0.0/16");
var desired = NetworkHelper.Parse("192.168.10.16/28");
var result = network.Extract(desired);
// Result:
// 192.168.0.0/21
// 192.168.8.0/23
// 192.168.10.0/28
// 192.168.10.16/28
// 192.168.10.32/27
// 192.168.10.64/26
// 192.168.10.128/25
// 192.168.11.0/24
// 192.168.12.0/22
// 192.168.16.0/20
// 192.168.32.0/19
// 192.168.64.0/18
// 192.168.128.0/17 You can also pass "0.0.0.0/28" to 'extract' any /28 from the given network. Works with IPv6 as well. What may help is using a visual subnet calculator like this one (no affiliation) to help visualize the concept. @lduchosal's exampe would be done as: var network = NetworkHelper.Parse("0.0.0.0/0");
var desired = NetworkHelper.Parse("10.0.0.1/32");
var result = network.Extract(desired);
var resulttext = string.Join("\n", result.Select(n => $"{n.Prefix}/{n.PrefixLength}")); |
@RobThree thanks, I'll dig into your proposal. |
Looking at the source code, I see a method called:
TrySubstractNetwork
. I attempted to use a slightly modified version of this function and it was extremely slow.I am trying to take two lists
IncludedRanages
andExcludedRanges
and have something consolidate adjacent and overlapping ranges/networks. Is this something easily added?The text was updated successfully, but these errors were encountered: