package geodb import ( "net" "net/http" "strings" ) // Utilities function func GetRequesterIP(r *http.Request) string { ip := r.Header.Get("X-Forwarded-For") if ip == "" { ip = r.Header.Get("X-Real-IP") if ip == "" { ip = strings.Split(r.RemoteAddr, ":")[0] } } return ip } // Match the IP address with a wildcard string func MatchIpWildcard(ipAddress, wildcard string) bool { // Split IP address and wildcard into octets ipOctets := strings.Split(ipAddress, ".") wildcardOctets := strings.Split(wildcard, ".") // Check that both have 4 octets if len(ipOctets) != 4 || len(wildcardOctets) != 4 { return false } // Check each octet to see if it matches the wildcard or is an exact match for i := 0; i < 4; i++ { if wildcardOctets[i] == "*" { continue } if ipOctets[i] != wildcardOctets[i] { return false } } return true } // Match ip address with CIDR func MatchIpCIDR(ip string, cidr string) bool { // parse the CIDR string _, cidrnet, err := net.ParseCIDR(cidr) if err != nil { return false } // parse the IP address ipAddr := net.ParseIP(ip) // check if the IP address is within the CIDR range return cidrnet.Contains(ipAddr) } // Check if a ip is private IP range func IsPrivateIP(ipStr string) bool { ip := net.ParseIP(ipStr) if ip == nil { return false } // Check for IPv4 private address ranges if ip.To4() != nil { privateIPv4Ranges := []string{ "10.0.0.0/8", // 10.0.0.0 - 10.255.255.255 "172.16.0.0/12", // 172.16.0.0 - 172.31.255.255 "192.168.0.0/16", // 192.168.0.0 - 192.168.255.255 "169.254.0.0/16", // 169.254.0.0 - 169.254.255.255 (link-local addresses) } for _, network := range privateIPv4Ranges { _, privateNet, _ := net.ParseCIDR(network) if privateNet.Contains(ip) { return true } } } else { // Check for IPv6 private address ranges privateIPv6Ranges := []string{ "fc00::/7", // Unique local addresses "fe80::/10", // Link-local addresses } for _, network := range privateIPv6Ranges { _, privateNet, _ := net.ParseCIDR(network) if privateNet.Contains(ip) { return true } } } return false }