package common import ( "io" "net" "net/http" "strings" ) var rfc1918 = []string{ "0.0.0.0/8", "10.0.0.0/8", "192.168.0.0/16", "172.16.0.0/12", } var excludes []*net.IPNet func pullbogons() ([]string, error) { res, err := http.Get("https://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt") if err != nil { return nil, err } if res.StatusCode == 404 { return nil, err } defer res.Body.Close() b := new(strings.Builder) _, _ = io.Copy(b, res.Body) raw := b.String() parts := strings.Split(raw, "\n") var bogons []string for _, r := range parts { if strings.Contains(r, "#") || !strings.Contains(r, "/") { continue } bogons = append(bogons, r) } return bogons, nil } func parseranges(ranges []string) error { for _, r := range ranges { _, ipnet, err := net.ParseCIDR(r) if err != nil { return err } excludes = append(excludes, ipnet) } return nil } func validcidr(cidr string) bool { _, _, err := net.ParseCIDR(cidr) if err != nil { return false } return true } func broadcast(ipnet *net.IPNet) net.IP { ip := ipnet.IP.To4() mask := ipnet.Mask for i := range ip { ip[i] |= ^mask[i] } return ip } func issmaller(submask, supermask net.IPMask) bool { for i := range submask { if submask[i] < supermask[i] { return false } } return true } func issubnet(subnet, supernet *net.IPNet) bool { if !supernet.Contains(subnet.IP) { return false } if !issmaller(subnet.Mask, supernet.Mask) { return false } bc := broadcast(subnet) return supernet.Contains(bc) } func ipexcluded(ip string) bool { ip_ := net.ParseIP(ip) for _, ex := range excludes { if ex.Contains(ip_) { return true } } return false } func cidrexcluded(cidr string) bool { _, argnet, _ := net.ParseCIDR(cidr) for _, ex := range excludes { if issubnet(argnet, ex) { return true } } return false } func SetExcludes() { if bogons, err := pullbogons(); err == nil && len(bogons) > 4 { if err = parseranges(bogons); err == nil { return } } info("error parsing bogon ranges, using rfc1918 defaults") _ = parseranges(rfc1918) }