package util import ( "net/netip" "strings" ) // ParseNetPrefixes parses a list of IP addresses and CIDR ranges, e.g. for a // list of trusted proxies. Entries are trimmed and blank ones skipped. A CIDR // range is masked to its network address (10.1.2.3/8 becomes 10.0.0.0/8), and // an address becomes a prefix holding only that address, with an IPv4-mapped // IPv6 address (::ffff:1.2.3.4) unmapped to IPv4. The first entry that can't // be parsed returns an error naming it. func ParseNetPrefixes(list []string) ([]netip.Prefix, error) { prefixes := make([]netip.Prefix, 0, len(list)) for _, entry := range list { entry = strings.TrimSpace(entry) if entry == "" { continue } if strings.Contains(entry, "/") { prefix, err := netip.ParsePrefix(entry) if err != nil { return nil, err } prefixes = append(prefixes, prefix.Masked()) continue } addr, err := netip.ParseAddr(entry) if err != nil { return nil, err } addr = addr.Unmap() prefixes = append(prefixes, netip.PrefixFrom(addr, addr.BitLen())) } return prefixes, nil }