🐛 Support range decision on stream mode

This commit is contained in:
maxlerebourg
2026-07-31 14:08:59 +02:00
parent bef5dfaadb
commit 6b0518859d
9 changed files with 301 additions and 17 deletions
+48
View File
@@ -0,0 +1,48 @@
package ip
import (
"net"
"strconv"
"strings"
)
// CIDRKeys returns all possible CIDR prefixes of an IP, from the most specific (/32 for IPv4, /128 for IPv6) to the least specific (/0).
func CIDRKeys(ipStr string) []string {
ip := net.ParseIP(ipStr)
if ip == nil {
return nil
}
ip4 := ip.To4()
if ip4 != nil {
keys := make([]string, 0, 33)
for bits := 32; bits >= 0; bits-- {
mask := net.CIDRMask(bits, 32)
n := make(net.IP, 4)
for i := 0; i < 4; i++ {
n[i] = ip4[i] & mask[i]
}
keys = append(keys, n.String()+"/"+strconv.Itoa(bits))
}
return keys
}
ip16 := ip.To16()
keys := make([]string, 0, 129)
for bits := 128; bits >= 0; bits-- {
mask := net.CIDRMask(bits, 128)
n := make(net.IP, 16)
for i := 0; i < 16; i++ {
n[i] = ip16[i] & mask[i]
}
keys = append(keys, n.String()+"/"+strconv.Itoa(bits))
}
return keys
}
// NormalizeCIDR parses a CIDR string and returns its normalized form, or an empty string if invalid.
func NormalizeCIDR(cidrStr string) string {
_, ipNet, err := net.ParseCIDR(strings.TrimSpace(cidrStr))
if err != nil {
return ""
}
return ipNet.String()
}