-
Notifications
You must be signed in to change notification settings - Fork 111
feat: add support for multi-octet and dash-based IP ranges #689
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -256,9 +256,9 @@ func nextSubnet(network *net.IPNet, prefixLen int) (*net.IPNet, error) { | |||||||||||
| // specific check. | ||||||||||||
| // | ||||||||||||
| // nolint:all | ||||||||||||
| func isPowerOfTwoPlusOne(x int) bool { | ||||||||||||
| return isPowerOfTwo(x - 1) | ||||||||||||
| } | ||||||||||||
| // func isPowerOfTwoPlusOne(x int) bool { | ||||||||||||
| // return isPowerOfTwo(x - 1) | ||||||||||||
| // } | ||||||||||||
|
|
||||||||||||
| // isPowerOfTwo returns if a number is a power of 2 | ||||||||||||
| func isPowerOfTwo(x int) bool { | ||||||||||||
|
|
@@ -268,11 +268,11 @@ func isPowerOfTwo(x int) bool { | |||||||||||
| // reverseIPNet reverses an ipnet slice | ||||||||||||
| // | ||||||||||||
| // nolint:all | ||||||||||||
| func reverseIPNet(ipnets []*net.IPNet) { | ||||||||||||
| for i, j := 0, len(ipnets)-1; i < j; i, j = i+1, j-1 { | ||||||||||||
| ipnets[i], ipnets[j] = ipnets[j], ipnets[i] | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| // func reverseIPNet(ipnets []*net.IPNet) { | ||||||||||||
| // for i, j := 0, len(ipnets)-1; i < j; i, j = i+1, j-1 { | ||||||||||||
| // ipnets[i], ipnets[j] = ipnets[j], ipnets[i] | ||||||||||||
| // } | ||||||||||||
| // } | ||||||||||||
|
Comment on lines
+271
to
+275
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chainRemove dead code and verify no references remain. Similar to Apply this diff to remove the dead code: -// reverseIPNet reverses an ipnet slice
-//
-// nolint:all
-// func reverseIPNet(ipnets []*net.IPNet) {
-// for i, j := 0, len(ipnets)-1; i < j; i, j = i+1, j-1 {
-// ipnets[i], ipnets[j] = ipnets[j], ipnets[i]
-// }
-// }
-Run the following script to verify 🏁 Script executed: #!/bin/bash
# Description: Search for any references to reverseIPNet in the codebase
# Search for function calls or mentions
rg -nP '\breverseIPNet\b' --type=go -C3Length of output: 370 Remove the unused The commented-out function is unreferenced; delete it entirely. --- a/cidr.go
+++ b/cidr.go
@@ -268,7 +268,0 @@
-// reverseIPNet reverses an ipnet slice
-//
-// nolint:all
-// func reverseIPNet(ipnets []*net.IPNet) {
-// for i, j := 0, len(ipnets)-1; i < j; i, j = i+1, j-1 {
-// ipnets[i], ipnets[j] = ipnets[j], ipnets[i]
-// }
-// }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||
|
|
||||||||||||
| // IPAddresses returns all the IP addresses in a CIDR | ||||||||||||
| func IPAddresses(cidr string) ([]string, error) { | ||||||||||||
|
|
||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -419,8 +419,28 @@ func process(wg *sync.WaitGroup, chancidr, outputchan chan string) { | |
| } | ||
|
|
||
| for _, cidr := range cidrsToProcess { | ||
| // Add IPs into ipRangeList which are passed as input. Example - "192.168.0.0-192.168.0.5" | ||
|
|
||
| if strings.Contains(cidr, "-") { | ||
| // Try to parse as multi-octet range | ||
| if strings.Count(cidr, ".") == 3 { | ||
| ips, err := mapcidr.ExpandIPPattern(cidr) | ||
| if err != nil { | ||
| gologger.Fatal().Msgf("%s\n", err) | ||
| } | ||
|
|
||
| for _, ip := range ips { | ||
| ipCidr := ip.String() + "/32" | ||
| if options.Aggregate || options.Shuffle || hasSort || options.AggregateApprox || options.Count { | ||
| _, ipnet, _ := net.ParseCIDR(ipCidr) | ||
| allCidrs = append(allCidrs, ipnet) | ||
| } else { | ||
| commonFunc(ipCidr, outputchan) | ||
| } | ||
| } | ||
| continue | ||
| } | ||
|
|
||
|
Comment on lines
421
to
+442
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apply MatchIP/FilterIP to expanded IPs in aggregate/sort/shuffle/count paths; also guard against ip:port and check ParseCIDR error Currently, expanded IPs bypass the per‑IP Match/Filter logic when any of aggregate/sort/shuffle/aggregate‑approx/count are enabled, which changes semantics vs. non‑expanded inputs. This can leak filtered IPs into outputs. Also, avoid treating ip:port strings as multi‑octet patterns and harden ParseCIDR error handling. Apply this diff: - // Try to parse as multi-octet range
- if strings.Count(cidr, ".") == 3 {
+ // Try to parse as multi-octet range (IPv4 only; avoid ip:port or CIDR-with-slash here)
+ if strings.Count(cidr, ".") == 3 && !strings.Contains(cidr, ":") && !strings.Contains(cidr, "/") {
ips, err := mapcidr.ExpandIPPattern(cidr)
if err != nil {
gologger.Fatal().Msgf("%s\n", err)
}
- for _, ip := range ips {
- ipCidr := ip.String() + "/32"
+ for _, ip := range ips {
+ ipStr := ip.String()
+ // Maintain parity with commonFunc filtering for expanded IPs
+ if len(matchIPSet) > 0 {
+ if _, ok := matchIPSet[ipStr]; !ok {
+ continue
+ }
+ } else if len(filterIPSet) > 0 {
+ if _, ok := filterIPSet[ipStr]; ok {
+ continue
+ }
+ }
+ ipCidr := ipStr + "/32"
if options.Aggregate || options.Shuffle || hasSort || options.AggregateApprox || options.Count {
- _, ipnet, _ := net.ParseCIDR(ipCidr)
- allCidrs = append(allCidrs, ipnet)
+ if _, ipnet, err := net.ParseCIDR(ipCidr); err != nil {
+ gologger.Fatal().Msgf("%s\n", err)
+ } else {
+ allCidrs = append(allCidrs, ipnet)
+ }
} else {
commonFunc(ipCidr, outputchan)
}
}
continue
}Add the following helper initialization inside process(), once, just after the var block and before the main loop (reuse prepareIPsFromCidrFlagList): // Precompute exact-match sets for expanded IP filtering parity
matchIPSet := map[string]struct{}{}
filterIPSet := map[string]struct{}{}
if options.MatchIP != nil {
for _, ip := range prepareIPsFromCidrFlagList(options.MatchIP) {
matchIPSet[ip] = struct{}{}
}
}
if options.FilterIP != nil {
for _, ip := range prepareIPsFromCidrFlagList(options.FilterIP) {
filterIPSet[ip] = struct{}{}
}
}🤖 Prompt for AI Agents |
||
| // Add IPs into ipRangeList which are passed as input. Example - "192.168.0.0-192.168.0.5" | ||
| var ipRange []net.IP | ||
| for _, ipstr := range strings.Split(cidr, "-") { | ||
| ipRange = append(ipRange, net.ParseIP(ipstr)) | ||
|
|
@@ -452,8 +472,8 @@ func process(wg *sync.WaitGroup, chancidr, outputchan chan string) { | |
| continue | ||
| } | ||
|
|
||
| // In case of coalesce/shuffle we need to know all the cidrs and aggregate them by calling the proper function | ||
| if options.Aggregate || options.Shuffle || hasSort || options.AggregateApprox || options.Count { | ||
| // In case of coalesce/shuffle we need to know all the cidrs and aggregate them by calling the proper function | ||
| _ = ranger.Add(cidr) | ||
| allCidrs = append(allCidrs, pCidr) | ||
| } else { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Remove dead code instead of commenting it out.
While the documentation explaining why this function is obsolete is excellent, commented-out code should be deleted entirely. Version control preserves the history if needed.
Apply this diff to remove the dead code:
📝 Committable suggestion
🤖 Prompt for AI Agents