コード例 #1
0
ファイル: util.go プロジェクト: sandwich-share/sandwich-go
func GetPort(address net.IP) string {
	if address.Equal(net.IPv4(127, 0, 0, 1)) {
		return ":8000" //It would be silly to do something funny on your own computer
	}
	port := ComputeHash(address)
	return ":" + strconv.Itoa(port)
}
コード例 #2
0
ファイル: proxier.go プロジェクト: nhr/kubernetes
// NewProxier returns a new Proxier given a LoadBalancer and an address on
// which to listen.  Because of the iptables logic, It is assumed that there
// is only a single Proxier active on a machine.
func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface) *Proxier {
	if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) {
		glog.Errorf("Can't proxy only on localhost - iptables can't do it")
		return nil
	}

	hostIP, err := chooseHostInterface()
	if err != nil {
		glog.Errorf("Failed to select a host interface: %v", err)
		return nil
	}

	glog.Infof("Initializing iptables")
	// Clean up old messes.  Ignore erors.
	iptablesDeleteOld(iptables)
	// Set up the iptables foundations we need.
	if err := iptablesInit(iptables); err != nil {
		glog.Errorf("Failed to initialize iptables: %v", err)
		return nil
	}
	// Flush old iptables rules (since the bound ports will be invalid after a restart).
	// When OnUpdate() is first called, the rules will be recreated.
	if err := iptablesFlush(iptables); err != nil {
		glog.Errorf("Failed to flush iptables: %v", err)
		return nil
	}
	return &Proxier{
		loadBalancer: loadBalancer,
		serviceMap:   make(map[string]*serviceInfo),
		listenIP:     listenIP,
		iptables:     iptables,
		hostIP:       hostIP,
	}
}
コード例 #3
0
// Validate given node IP belongs to the current host
func (kl *Kubelet) validateNodeIP() error {
	if kl.nodeIP == nil {
		return nil
	}

	// Honor IP limitations set in setNodeStatus()
	if kl.nodeIP.IsLoopback() {
		return fmt.Errorf("nodeIP can't be loopback address")
	}
	if kl.nodeIP.To4() == nil {
		return fmt.Errorf("nodeIP must be IPv4 address")
	}

	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return 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
		}
		if ip != nil && ip.Equal(kl.nodeIP) {
			return nil
		}
	}
	return fmt.Errorf("Node IP: %q not found in the host's network interfaces", kl.nodeIP.String())
}
コード例 #4
0
func ipIsLocal(ip net.IP) bool {
	if ip.To4() == nil {
		return ip.Equal(net.IPv6loopback)
	}

	return v4Loopback.Contains(ip)
}
コード例 #5
0
ファイル: etcd.go プロジェクト: ScriptRock/peerdiscovery
func (c *EtcdConfig) verifyIP(ip net.IP, source string) {
	fmt.Printf("IP '%s' found in '%s'\n", ip.String(), source)
	// valid ip address found from source. Verify that it exists
	if iface, ip_net, ipverify, err := LocalNetForIp(ip); err != nil {
		fmt.Printf("%s\n", err.Error())
	} else if !ip.Equal(ipverify) {
		fmt.Printf("IP address on interface %s: %s does not match ip from %s: %s\n",
			iface.Name, ipverify, c.AddrSource, ip)
	} else {
		fmt.Printf("IP '%s' verified, on interface '%s' net '%s'\n",
			ip.String(), iface.Name, ip_net.String())
		set := false
		// set local defaults appropriately
		if c.ClientAddr == "" {
			c.ClientAddr = ip.String()
			set = true
		}
		if c.PeerAddr == "" {
			c.PeerAddr = ip.String()
			set = true
		}
		if set {
			c.Interface = iface
		}
	}
}
コード例 #6
0
ファイル: hostgw.go プロジェクト: rajatchopra/flannel
func (rb *HostgwBackend) Init(extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
	rb.extIface = extIface
	rb.extIaddr = extIaddr

	if !extIaddr.Equal(extEaddr) {
		return nil, fmt.Errorf("your PublicIP differs from interface IP, meaning that probably you're on a NAT, which is not supported by host-gw backend")
	}

	attrs := subnet.LeaseAttrs{
		PublicIP:    ip.FromIP(extIaddr),
		BackendType: "host-gw",
	}

	l, err := rb.sm.AcquireLease(rb.ctx, rb.network, &attrs)
	switch err {
	case nil:
		rb.lease = l

	case context.Canceled, context.DeadlineExceeded:
		return nil, err

	default:
		return nil, fmt.Errorf("failed to acquire lease: %v", err)
	}

	/* NB: docker will create the local route to `sn` */

	return &backend.SubnetDef{
		Net: l.Subnet,
		MTU: extIface.MTU,
	}, nil
}
コード例 #7
0
ファイル: proxier.go プロジェクト: ericcapricorn/kubernetes
// Build a slice of iptables args for a portal rule.
func iptablesPortalArgs(destIP net.IP, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service string) []string {
	args := []string{
		"-m", "comment",
		"--comment", service,
		"-p", strings.ToLower(string(protocol)),
		"-d", destIP.String(),
		"--dport", fmt.Sprintf("%d", destPort),
	}
	// This is tricky.  If the proxy is bound (see Proxier.listenAddress)
	// to 0.0.0.0 ("any interface") or 127.0.0.1, we can use REDIRECT,
	// which will bring packets back to the host's loopback interface.  If
	// the proxy is bound to any other interface, then it is not listening
	// on the hosts's loopback, so we have to use DNAT to that specific
	// IP.  We can not simply use DNAT to 127.0.0.1 in the first case
	// because from within a container, 127.0.0.1 is the container's
	// loopback interface, not the host's.
	//
	// Why would anyone bind to an address that is not inclusive of
	// localhost?  Apparently some cloud environments have their public IP
	// exposed as a real network interface AND do not have firewalling.  We
	// don't want to expose everything out to the world.
	//
	// Unfortunately, I don't know of any way to listen on some (N > 1)
	// interfaces but not ALL interfaces, short of doing it manually, and
	// this is simpler than that.
	if proxyIP.Equal(zeroIP) || proxyIP.Equal(localhostIP) {
		args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort))
	} else {
		args = append(args, "-j", "DNAT", "--to-destination", fmt.Sprintf("%s:%d", proxyIP.String(), proxyPort))
	}
	return args
}
コード例 #8
0
ファイル: any_proxy.go プロジェクト: ryanchapman/go-any-proxy
func buildDirectors(gDirects string) []directorFunc {
	// Generates a list of directorFuncs that are have "cached" values within
	// the scope of the functions.

	directorCidrs := strings.Split(gDirects, ",")
	directorFuncs := make([]directorFunc, len(directorCidrs))

	for idx, directorCidr := range directorCidrs {
		//dstring := director
		var dfunc directorFunc
		if strings.Contains(directorCidr, "/") {
			_, directorIpNet, err := net.ParseCIDR(directorCidr)
			if err != nil {
				panic(fmt.Sprintf("\nUnable to parse CIDR string : %s : %s\n", directorCidr, err))
			}
			dfunc = func(ptestip *net.IP) bool {
				testIp := *ptestip
				return directorIpNet.Contains(testIp)
			}
			directorFuncs[idx] = dfunc
		} else {
			var directorIp net.IP
			directorIp = net.ParseIP(directorCidr)
			dfunc = func(ptestip *net.IP) bool {
				var testIp net.IP
				testIp = *ptestip
				return testIp.Equal(directorIp)
			}
			directorFuncs[idx] = dfunc
		}

	}
	return directorFuncs
}
コード例 #9
0
ファイル: proxier.go プロジェクト: numidiasoft/kubernetes
// Build a slice of iptables args for a from-host portal rule.
func (proxier *Proxier) iptablesHostPortalArgs(destIP net.IP, addDstLocalMatch bool, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string {
	args := iptablesCommonPortalArgs(destIP, false, addDstLocalMatch, destPort, protocol, service)

	// This is tricky.
	//
	// If the proxy is bound (see Proxier.listenIP) to 0.0.0.0 ("any
	// interface") we want to do the same as from-container traffic and use
	// REDIRECT.  Except that it doesn't work (empirically).  REDIRECT on
	// local packets sends the traffic to localhost (special case, but it is
	// documented) but the response comes from the eth0 IP (not sure why,
	// truthfully), which makes DNS unhappy.
	//
	// So we have to use DNAT.  DNAT to 127.0.0.1 can't work for the same
	// reason.
	//
	// So we do our best to find an interface that is not a loopback and
	// DNAT to that.  This works (again, empirically).
	//
	// If the proxy is bound to a specific IP, then we have to use DNAT to
	// that IP.  Unlike the previous case, this works because the proxy is
	// ONLY listening on that IP, not the bridge.
	//
	// If the proxy is bound to localhost only, this should work, but we
	// don't allow it for now.
	if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) {
		proxyIP = proxier.hostIP
	}
	// TODO: Can we DNAT with IPv6?
	args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort)))
	return args
}
コード例 #10
0
func HardwareAddrByIP(x net.IP) (*net.HardwareAddr, error) {
	file, err := os.Open("/proc/net/arp")
	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fields := strings.Fields(scanner.Text())

		if x.Equal(net.ParseIP(fields[0])) {
			addr, err := net.ParseMAC(fields[3])
			if err != nil {
				continue
			}

			return &addr, nil
		}
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}

	return nil, errors.New("no mac address found")
}
コード例 #11
0
func netIP4ToInterface(ip net.IP) (*net.Interface, error) {
	ift, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, ifi := range ift {
		ifat, err := ifi.Addrs()
		if err != nil {
			return nil, err
		}
		for _, ifa := range ifat {
			switch ifa := ifa.(type) {
			case *net.IPAddr:
				if ip.Equal(ifa.IP) {
					return &ifi, nil
				}
			case *net.IPNet:
				if ip.Equal(ifa.IP) {
					return &ifi, nil
				}
			}
		}
	}
	return nil, errNoSuchInterface
}
コード例 #12
0
func InterfaceByIP(x net.IP) (*net.Interface, error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}

	for _, iface := range ifaces {
		addrs, err := iface.Addrs()
		if err != nil {
			continue
		}
		for _, addr := range addrs {
			var ip net.IP

			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}

			if x.Equal(ip.To4()) {
				return &iface, nil
			}
		}
	}
	return nil, errors.New("no such network interface")
}
コード例 #13
0
ファイル: values_test.go プロジェクト: segmentio/pgx
func TestInetCidrTranscodeIP(t *testing.T) {
	t.Parallel()

	conn := mustConnect(t, *defaultConnConfig)
	defer closeConn(t, conn)

	tests := []struct {
		sql   string
		value net.IP
	}{
		{"select $1::inet", net.ParseIP("0.0.0.0")},
		{"select $1::inet", net.ParseIP("127.0.0.1")},
		{"select $1::inet", net.ParseIP("12.34.56.0")},
		{"select $1::inet", net.ParseIP("255.255.255.255")},
		{"select $1::inet", net.ParseIP("::1")},
		{"select $1::inet", net.ParseIP("2607:f8b0:4009:80b::200e")},
		{"select $1::cidr", net.ParseIP("0.0.0.0")},
		{"select $1::cidr", net.ParseIP("127.0.0.1")},
		{"select $1::cidr", net.ParseIP("12.34.56.0")},
		{"select $1::cidr", net.ParseIP("255.255.255.255")},
		{"select $1::cidr", net.ParseIP("::1")},
		{"select $1::cidr", net.ParseIP("2607:f8b0:4009:80b::200e")},
	}

	for i, tt := range tests {
		var actual net.IP

		err := conn.QueryRow(tt.sql, tt.value).Scan(&actual)
		if err != nil {
			t.Errorf("%d. Unexpected failure: %v (sql -> %v, value -> %v)", i, err, tt.sql, tt.value)
			continue
		}

		if !actual.Equal(tt.value) {
			t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.value, actual, tt.sql)
		}

		ensureConnValid(t, conn)
	}

	failTests := []struct {
		sql   string
		value net.IPNet
	}{
		{"select $1::inet", mustParseCIDR(t, "192.168.1.0/24")},
		{"select $1::cidr", mustParseCIDR(t, "192.168.1.0/24")},
	}
	for i, tt := range failTests {
		var actual net.IP

		err := conn.QueryRow(tt.sql, tt.value).Scan(&actual)
		if !strings.Contains(err.Error(), "Cannot decode netmask") {
			t.Errorf("%d. Expected failure cannot decode netmask, but got: %v (sql -> %v, value -> %v)", i, err, tt.sql, tt.value)
			continue
		}

		ensureConnValid(t, conn)
	}
}
コード例 #14
0
ファイル: router.go プロジェクト: udhos/nexthop
func (v *ripVrf) nexthopGet(prefix *net.IPNet, nexthop net.IP) (int, *ripNet) {
	for i, n := range v.nets {
		if nexthop.Equal(n.nexthop) == addr.NetEqual(prefix, &n.addr) {
			return i, n
		}
	}
	return -1, nil
}
コード例 #15
0
ファイル: crypto.go プロジェクト: johnmccawley/origin
func ipInSlice(needle net.IP, haystack []net.IP) bool {
	for _, straw := range haystack {
		if needle.Equal(straw) {
			return true
		}
	}
	return false
}
コード例 #16
0
ファイル: driver.go プロジェクト: n054/weave
func (i *Ipam) ReleaseAddress(poolID string, address net.IP) error {
	i.logReq("ReleaseAddress", poolID, address)
	if subnet, _, err := splitPoolID(poolID); err != nil {
		return err
	} else if address.Equal(subnet.IP) { // is it the gateway address we faked earlier?
		return nil
	}
	return i.weave.ReleaseIPsFor(address.String())
}
コード例 #17
0
ファイル: proxier.go プロジェクト: numidiasoft/kubernetes
// Build a slice of iptables args for a from-host public-port rule.
// See iptablesHostPortalArgs
// TODO: Should we just reuse iptablesHostPortalArgs?
func (proxier *Proxier) iptablesHostNodePortArgs(nodePort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string {
	args := iptablesCommonPortalArgs(nil, false, false, nodePort, protocol, service)

	if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) {
		proxyIP = proxier.hostIP
	}
	// TODO: Can we DNAT with IPv6?
	args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort)))
	return args
}
コード例 #18
0
ファイル: interface_linux.go プロジェクト: hpdvanwyk/ib
func InterfaceForAddr(addr net.Addr) *Interface {
	var ip net.IP
	if ipAddr, ok := addr.(*net.IPNet); ok {
		ip = ipAddr.IP
	} else if tcpAddr, ok := addr.(*net.TCPAddr); ok {
		ip = tcpAddr.IP
	} else {
		return nil
	}

	ifaces, err := net.Interfaces()
	if err != nil {
		return nil
	}

	var ibIface *Interface
	for i := range ifaces {
		iface := &ifaces[i]

		// hack until ifi_type in ifinfomsg is available in Go
		if len(iface.HardwareAddr) != 20 {
			continue
		}

		guidKey := string([]byte(iface.HardwareAddr[12:]))
		var ok bool
		ibIface, ok = guidToInterface[guidKey]
		if !ok || iface == nil {
			continue
		}

		ifaceAddrs, err := iface.Addrs()
		if err != nil || len(ifaceAddrs) == 0 {
			continue
		}
		found := false
		for _, ifaceAddr := range ifaceAddrs {
			ifaceIPNet := ifaceAddr.(*net.IPNet)
			if ifaceIPNet.IP.To4() == nil {
				continue
			}
			if ip.Equal(ifaceIPNet.IP) {
				found = true
				break
			}
		}
		if found {
			break
		} else {
			ibIface = nil
		}
	}
	return ibIface
}
コード例 #19
0
ファイル: daemon.go プロジェクト: mickydelfavero/lxd
func IpsEqual(ip1 net.IP, ip2 net.IP) bool {
	if ip1.Equal(ip2) {
		return true
	}

	/* the go std library Equal doesn't recognize [::] == 0.0.0.0, since it
	 * tests for the ipv4 prefix, which isn't present in [::]. However,
	 * they are in fact equal. Let's test for this case too.
	 */
	return isZeroIP(ip1) && isZeroIP(ip2)
}
コード例 #20
0
ファイル: ipam.go プロジェクト: jak-atx/vic
func splitRange(parentRange *ip.Range, firstIP net.IP, lastIP net.IP) (before, reserved, after *ip.Range) {
	if !firstIP.Equal(parentRange.FirstIP) {
		before = ip.NewRange(parentRange.FirstIP, decrementIP4(firstIP))
	}
	if !lastIP.Equal(parentRange.LastIP) {
		after = ip.NewRange(incrementIP4(lastIP), parentRange.LastIP)
	}

	reserved = ip.NewRange(firstIP, lastIP)
	return
}
コード例 #21
0
ファイル: reliable.go プロジェクト: cs2dsb/udp-sd
func (c *con) GetListenAddresses() (addresses []*net.UDPAddr) {
	addresses = make([]*net.UDPAddr, 0)

	select {
	case <-c.done:
		return
	default:
	}

	port := c.Port

	interfaces := util.GetUnicastInterfaces()
	ips := make([]net.IP, 0)
	for _, ifc := range interfaces {
		addrs, err := ifc.Addrs()
		if err != nil {
			c.Warnf("Error getting addresses from interface (%v): %v", ifc, err)
			continue
		}
		for _, a := range addrs {
			var ip net.IP
			switch v := a.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			default:
				continue
			}

			if ip.To4() == nil {
				continue
			}
			found := false
			for _, oldA := range ips {
				if ip.Equal(oldA) {
					found = true
					break
				}
			}
			if !found {
				ips = append(ips, ip)
			}
		}
	}

	for _, ip := range ips {
		addresses = append(addresses, &net.UDPAddr{IP: ip, Port: port})
	}

	return
}
コード例 #22
0
func getHostOnlyNetwork(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask net.IPMask) *hostOnlyNetwork {
	for _, n := range nets {
		// Second part of this conditional handles a race where
		// VirtualBox returns us the incorrect netmask value for the
		// newly created interface.
		if hostIP.Equal(n.IPv4.IP) &&
			(netmask.String() == n.IPv4.Mask.String() || n.IPv4.Mask.String() == buggyNetmask) {
			return n
		}
	}

	return nil
}
コード例 #23
0
ファイル: marshal_test.go プロジェクト: robmccoll/gocql
func TestUnmarshalInetCopyBytes(t *testing.T) {
	data := []byte{127, 0, 0, 1}
	var ip net.IP
	if err := unmarshalInet(NativeType{proto: 2, typ: TypeInet}, data, &ip); err != nil {
		t.Fatal(err)
	}

	copy(data, []byte{0xFF, 0xFF, 0xFF, 0xFF})
	ip2 := net.IP(data)
	if !ip.Equal(net.IPv4(127, 0, 0, 1)) {
		t.Fatalf("IP memory shared with data: ip=%v ip2=%v", ip, ip2)
	}
}
コード例 #24
0
ファイル: icmp.go プロジェクト: ChongFeng/beats
func (icmp *Icmp) isLocalIp(ip net.IP) bool {
	if ip.IsLoopback() {
		return true
	}

	for _, localIp := range icmp.localIps {
		if ip.Equal(localIp) {
			return true
		}
	}

	return false
}
コード例 #25
0
ファイル: proxier.go プロジェクト: numidiasoft/kubernetes
// Build a slice of iptables args for a from-container public-port rule.
// See iptablesContainerPortalArgs
// TODO: Should we just reuse iptablesContainerPortalArgs?
func (proxier *Proxier) iptablesContainerNodePortArgs(nodePort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string {
	args := iptablesCommonPortalArgs(nil, false, false, nodePort, protocol, service)

	if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) {
		// TODO: Can we REDIRECT with IPv6?
		args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort))
	} else {
		// TODO: Can we DNAT with IPv6?
		args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort)))
	}

	return args
}
コード例 #26
0
ファイル: client.go プロジェクト: hakobe/paranoidhttp
func isBadIPv4(ip net.IP) bool {
	if ip.To4() == nil {
		panic("cannot be called for IPv6")
	}

	if ip.Equal(net.IPv4bcast) || !ip.IsGlobalUnicast() ||
		netPrivateClassA.Contains(ip) || netPrivateClassB.Contains(ip) || netPrivateClassC.Contains(ip) ||
		netTestNet.Contains(ip) || net6To4Relay.Contains(ip) {
		return true
	}

	return false
}
コード例 #27
0
ファイル: icmp.go プロジェクト: ruflin/beats
func (icmp *icmpPlugin) isLocalIP(ip net.IP) bool {
	if ip.IsLoopback() {
		return true
	}

	for _, localIP := range icmp.localIps {
		if ip.Equal(localIP) {
			return true
		}
	}

	return false
}
コード例 #28
0
ファイル: network.go プロジェクト: cdosso/machine
func getHostOnlyNetwork(hostIP net.IP, netmask net.IPMask) (*hostOnlyNetwork, error) {
	nets, err := listHostOnlyNetworks()
	if err != nil {
		return nil, err
	}
	for _, n := range nets {
		if hostIP.Equal(n.IPv4.IP) &&
			netmask.String() == n.IPv4.Mask.String() {
			return n, nil
		}
	}
	return nil, nil
}
コード例 #29
0
ファイル: proxier.go プロジェクト: cjnygard/origin
// NewProxier returns a new Proxier given a LoadBalancer and an address on
// which to listen.  Because of the iptables logic, It is assumed that there
// is only a single Proxier active on a machine. An error will be returned if
// the proxier cannot be started due to an invalid ListenIP (loopback) or
// if iptables fails to update or acquire the initial lock. Once a proxier is
// created, it will keep iptables up to date in the background and will not
// terminate if a particular iptables call fails.
func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface) (*Proxier, error) {
	if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) {
		return nil, ErrProxyOnLocalhost
	}

	hostIP, err := util.ChooseHostInterface()
	if err != nil {
		return nil, fmt.Errorf("failed to select a host interface: %v", err)
	}

	glog.V(2).Infof("Setting proxy IP to %v and initializing iptables", hostIP)
	return createProxier(loadBalancer, listenIP, iptables, hostIP)
}
コード例 #30
0
ファイル: multicast.go プロジェクト: Christeefym/lantern
func isFromMe(ip net.IP) bool {
	addrs, e := net.InterfaceAddrs()
	if e != nil {
		log.Error(e)
	}
	for _, a := range addrs {
		if ipnet, ok := a.(*net.IPNet); ok {
			if ip.Equal(ipnet.IP) {
				return true
			}
		}
	}
	return false
}