// ContainsIpAddress performs a binary search on the networkList to // find a network containing the candidate IP address. func (list networkList) ContainsIpAddress(addr net.IP) bool { // Search criteria // // The following conditions are satisfied when address_IP is in the network: // 1. address_IP ^ network_mask == network_IP ^ network_mask // 2. address_IP >= network_IP. // We are also assuming that network ranges do not overlap. // // For an ascending array of networks, the sort.Search returns the smallest // index idx for which condition network_IP > address_IP is satisfied, so we // are checking whether or not adrress_IP belongs to the network[idx-1]. // Edge conditions check // // idx == 0 means that address_IP is lesser than the first (smallest) network_IP // thus never satisfies search condition 2. // idx == array_length means that address_IP is larger than the last (largest) // network_IP so we need to check the last element for condition 1. addrValue := binary.BigEndian.Uint32(addr.To4()) index := sort.Search(len(list), func(i int) bool { networkValue := binary.BigEndian.Uint32(list[i].IP) return networkValue > addrValue }) return index > 0 && list[index-1].IP.Equal(addr.Mask(list[index-1].Mask)) }
func (i *IP) ApplyIPToMask(ip net.IP) net.IP { newIp := ip.Mask(i.mask).To16() ourIp := i.ip.To16() for idx, val := range ourIp { newIp[idx] = newIp[idx] | val } return newIp }
func (t TargetOptions) GetTargets(ip net.IP) ([]string, int) { targets := make([]string, 0) var country, continent, region, regionGroup, asn string var netmask int if t&TargetASN > 0 { asn, netmask = geoIP.GetASN(ip) } if t&TargetRegion > 0 || t&TargetRegionGroup > 0 { country, continent, regionGroup, region, netmask = geoIP.GetCountryRegion(ip) } else if t&TargetCountry > 0 || t&TargetContinent > 0 { country, continent, netmask = geoIP.GetCountry(ip) } if t&TargetIP > 0 { ipStr := ip.String() targets = append(targets, "["+ipStr+"]") ip4 := ip.To4() if ip4 != nil { if ip4[3] != 0 { ip4[3] = 0 targets = append(targets, "["+ip4.String()+"]") } } else { // v6 address, also target the /48 address ip48 := ip.Mask(cidr48Mask) targets = append(targets, "["+ip48.String()+"]") } } if t&TargetASN > 0 && len(asn) > 0 { targets = append(targets, asn) } if t&TargetRegion > 0 && len(region) > 0 { targets = append(targets, region) } if t&TargetRegionGroup > 0 && len(regionGroup) > 0 { targets = append(targets, regionGroup) } if t&TargetCountry > 0 && len(country) > 0 { targets = append(targets, country) } if t&TargetContinent > 0 && len(continent) > 0 { targets = append(targets, continent) } if t&TargetGlobal > 0 { targets = append(targets, "@") } return targets, netmask }
// NetList : subnet helper function func NetList(ip net.IP, subnet net.IP) (IPlist []net.IP) { //ip, ipnet, err := net.ParseCIDR(cidrNet) mask := net.IPv4Mask(subnet[0], subnet[1], subnet[2], subnet[3]) ipnet := net.IPNet{ip, mask} for ip := ip.Mask(mask); ipnet.Contains(ip); incIP(ip) { IPlist = append(IPlist, net.IP{ip[0], ip[1], ip[2], ip[3]}) } return }
func maskRange(ip net.IP, mask net.IPMask) (btm, top net.IP) { btm = ip.Mask(mask) top = make(net.IP, len(ip)) copy(top, ip) for i, b := range mask { top[i] |= ^b } return }
func Mask(addr net.IP) { mask := addr.DefaultMask() network := addr.Mask(mask) ones, bits := mask.Size() fmt.Println("Address is ", addr.String(), " Default mask length is ", bits, "Leading ones count is ", ones, "Mask is (hex) ", mask.String(), " Network is ", network.String()) }
// SpanningCIDR computes network covers given IP addresses func SpanningCIDR(first, last net.IP) *net.IPNet { _, bits := last.DefaultMask().Size() var network net.IPNet for ones := bits; !network.Contains(first); ones-- { network.Mask = net.CIDRMask(ones, bits) network.IP = last.Mask(network.Mask) } return &network }
func (i *IP2ASNClient) keys(IP net.IP) []net.IPNet { var keys []net.IPNet for _, n := range netmasks { ipn := net.IPNet{ IP: IP.Mask(n), Mask: n, } keys = append(keys, ipn) } return keys }
func SubIP(ip net.IP, mask net.IPMask) net.IP { m := ip.Mask(mask) fmt.Printf("%d\n", len(m)) out := make(net.IP, len(ip)) for i, v := range ip { j := len(ip) - i if j > len(m) { out[i] = v } else { out[i] = v &^ m[len(m)-j] } } return out }
func (pm *PeerMap) mask(ip net.IP) string { if !pm.Config.PreferredSubnet { return "" } var maskedIP net.IP if len(ip) == net.IPv6len { maskedIP = ip.Mask(net.CIDRMask(pm.Config.PreferredIPv6Subnet, 128)) } else { maskedIP = ip.Mask(net.CIDRMask(pm.Config.PreferredIPv4Subnet, 32)) } return maskedIP.String() }
// NetworkRange calculates the first and last IP addresses in an IPNet func NetworkRange(network *net.IPNet) (net.IP, net.IP) { var netIP net.IP if network.IP.To4() != nil { netIP = network.IP.To4() } else if network.IP.To16() != nil { netIP = network.IP.To16() } else { return nil, nil } lastIP := make([]byte, len(netIP), len(netIP)) for i := 0; i < len(netIP); i++ { lastIP[i] = netIP[i] | ^network.Mask[i] } return netIP.Mask(network.Mask), net.IP(lastIP) }
// ipRange returns a range of IP addresses suitable for querying MySQL for the // purpose of rate limiting using a range that is inclusive on the lower end and // exclusive at the higher end. If ip is an IPv4 address, it returns that address, // plus the one immediately higher than it. If ip is an IPv6 address, it applies // a /48 mask to it and returns the lowest IP in the resulting network, and the // first IP outside of the resulting network. func ipRange(ip net.IP) (net.IP, net.IP) { ip = ip.To16() // For IPv6, match on a certain subnet range, since one person can commonly // have an entire /48 to themselves. maskLength := 48 // For IPv4 addresses, do a match on exact address, so begin = ip and end = // next higher IP. if ip.To4() != nil { maskLength = 128 } mask := net.CIDRMask(maskLength, 128) begin := ip.Mask(mask) end := incrementIP(begin, maskLength) return begin, end }
func findInterfaceForHost(hostname string) (string, error) { var hostIP net.IP if hostname == "" { hostIP = make(net.IP, 4) } else { hostIPs, err := net.LookupIP(hostname) if err != err { return "", err } if len(hostIPs) < 1 { return "", errors.New("not enough IPs") } hostIP = hostIPs[0] } file, err := os.Open(procRouteFilename) if err != nil { return "", err } defer file.Close() scanner := bufio.NewScanner(file) mostSpecificInterfaceName := "" mostSpecificNetmaskBits := -1 for scanner.Scan() { var interfaceName string var destAddr, gatewayAddr, flags, mask uint32 var ign int nCopied, err := fmt.Sscanf(scanner.Text(), "%s %x %x %x %d %d %d %x %d %d %d", &interfaceName, &destAddr, &gatewayAddr, &flags, &ign, &ign, &ign, &mask, &ign, &ign, &ign) if err != nil || nCopied < 11 { continue } maskIP := net.IPMask(intToIP(mask)) destIP := intToIP(destAddr) if hostIP.Mask(maskIP).Equal(destIP) { size, _ := maskIP.Size() if size > mostSpecificNetmaskBits { mostSpecificInterfaceName = interfaceName mostSpecificNetmaskBits = size } } } return mostSpecificInterfaceName, scanner.Err() }
func main() { mn := new(MyNet) ifaces, err := net.Interfaces() if err != nil { log.Fatal(err) } for _, iface := range ifaces { if iface.Flags&net.FlagUp == 0 { continue // interface down } if iface.Flags&net.FlagLoopback != 0 { continue // loopback interface } addrs, err := iface.Addrs() if err != nil { log.Fatal(err) } for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: // ip = v.IP continue } if ip == nil || ip.IsLoopback() { continue } ip = ip.To4() if ip == nil { continue // not an ipv4 address } fmt.Println("IP: ", ip) fmt.Println("Subnet: ", ip.Mask(ip.DefaultMask())) mn.IP = addr.(*net.IPNet) mn.Subnet = ip.Mask(ip.DefaultMask()) } } fmt.Println(mn) mn.GetNetwork() }
// Process a packet func (nflog *NfLog) ProcessPacket(packet []byte, seq uint32) AddPacket { // log.Printf("Packet %#v", packet) // Peek the IP Version out of the header ip_version := packet[IpVersion] >> IpVersionShift & IpVersionMask // log.Printf("Received %d: size %d, IPv%d", seq, payload_len, ip_version) if seq != 0 && seq != nflog.seq { nflog.errors++ log.Printf("%d missing packets detected, %d to %d", seq-nflog.seq, seq, nflog.seq) } nflog.seq = seq + 1 if ip_version != nflog.IpVersion { nflog.errors++ log.Printf("Bad IP version: %d", ip_version) return AddPacket{Length: -1} } i := nflog.IpPacket if len(packet) < i.HeaderSize { nflog.errors++ log.Printf("Short IPv%d packet %d/%d bytes", ip_version, len(packet), i.HeaderSize) return AddPacket{Length: -1} } var addr net.IP if nflog.Direction { addr = i.Src(packet) } else { addr = i.Dst(packet) } // Mask the address if nflog.UseMask { addr = addr.Mask(nflog.Mask) } return AddPacket{ Direction: nflog.Direction, Addr: string(addr), Length: i.Length(packet), } }
func MaskNetwork(ip net.IP, mask net.IPMask) net.IP { return ip.Mask(mask) }
func first(ip net.IP, mask net.IPMask) net.IP { return ip.Mask(mask) }
// Check whether an IP matches a Ban func (ban Ban) Match(ip net.IP) bool { banned := ban.IP.Mask(ban.IPMask()) masked := ip.Mask(ban.IPMask()) return banned.Equal(masked) }
// GetClientGroup returns a *net.IPNet which represents a subnet of prefix // size v4PrefixSize in the case of IPv4 addresses. func GetClientGroup(ip net.IP) *net.IPNet { if ip.To4() == nil { return &net.IPNet{IP: ip.Mask(v6PrefixMask), Mask: v6PrefixMask} } return &net.IPNet{IP: ip.Mask(v4PrefixMask), Mask: v4PrefixMask} }