// probeIPv6Stack returns two boolean values.  If the first boolean
// value is true, kernel supports basic IPv6 functionality.  If the
// second boolean value is true, kernel supports IPv6 IPv4-mapping.
506195
func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
	// Plan 9 uses IPv6 natively, see ip(3).
	r := probe("/net/iproute", "6i")
	v := false
	if r {
		v = probe("/net/iproute", "4i")
	}
	return r, v
}
711553
func iptablesFlush() error {
	for _, af := range seesaw.AFs() {
		for _, table := range []string{"filter", "mangle", "raw"} {
			if err := iptablesRun(af, fmt.Sprintf("--flush -t %v", table)); err != nil {
				return err
			}
		}
	}
	// NAT is IPv4-only until linux kernel version 3.7.
	// TODO(angusc): Support IPv6 NAT.
	if err := iptablesRun(seesaw.IPv4, "--flush -t nat"); err != nil {
		return err
	}
	return nil
}
1017244
func (cn *connection) ipv6() bool {
	ip := cn.remoteAddr.IP
	if ip.To4() != nil {
		return false
	}
	return len(ip) == net.IPv6len
}
265542
func MyIp6() *net.IPAddr {
	myIp6Once.Do(func() {
		var err error
		myIp6, err = net.ResolveIPAddr("ip6", MyHostname())
		if err != nil {
			log.Fatal(err)
		}
	})
	return myIp6
}
75125
func IsV6MulticastAddress(addr tcpip.Address) bool {
	if len(addr) != IPv6AddressSize {
		return false
	}
	return addr[0] == 0xff
}
955276
func ipsTo4And6(allIPs []net.IP) (ips []net.IP) {
	var ipv4, ipv6 net.IP
	for _, ip := range allIPs {
		if ipv4 != nil && ipv6 != nil {
			break
		} else if t4 := ip.To4(); t4 != nil {
			if ipv4 == nil {
				ipv4 = t4
			}
		} else if t6 := ip.To16(); t6 != nil {
			if ipv6 == nil {
				ipv6 = t6
			}
		}
	}
	ips = []net.IP{}
	if ipv4 != nil {
		ips = append(ips, ipv4)
	}
	if ipv6 != nil {
		ips = append(ips, ipv6)
	}
	return
}
760466
func GetNextIPv6HostID(hostID, subnetAddr string, subnetLen uint, IPv6AllocMap map[string]bool) (string, error) {
	if hostID == "" {
		hostID = "::"
	}
	if subnetLen == 0 {
		return "", core.Errorf("subnet length %d is invalid", subnetLen)
	}

	hostidIP := net.ParseIP(hostID)

	// start with the carryOver 1 to get the next hostID
	var carryOver = 1
	var allocd = true

	for allocd == true {
		// Add 1 to hostID
		for i := len(hostidIP) - 1; i >= 0; i-- {
			var temp int
			temp = int(hostidIP[i]) + carryOver
			if temp > int(0xFF) {
				hostidIP[i] = 0
				carryOver = 1
			} else {
				hostidIP[i] = uint8(temp)
				carryOver = 0
				break
			}
		}
		// Check if this hostID is already allocated
		if _, allocd = IPv6AllocMap[hostidIP.String()]; allocd == true {
			// Already allocated find the next hostID
			carryOver = 1
		} else {
			// allocd == false. check if we reached MaxHosts
			offset := (subnetLen - 1) / 8
			masklen := subnetLen % 8
			mask := ((1 << masklen) - 1) << (8 - masklen)
			if (hostidIP[offset] & byte(mask)) != 0 {
				// if hostID is outside subnet range,
				//	check if we have reached MaxHosts
				maxHosts := math.Pow(2, float64(128-subnetLen)) - 1
				if float64(len(IPv6AllocMap)) < maxHosts {
					hostID = "::"
					hostidIP = net.ParseIP(hostID)
					carryOver = 1
					allocd = true // continue the loop
				} else {
					return "", core.Errorf("Reached MaxHosts (%v). Cannot allocate more hosts", maxHosts)
				}
			}
		}
	}
	return hostidIP.String(), nil
}
1243789
func isIPV6(v interface{}) bool {
	s, ok := v.(string)
	if !ok {
		return false
	}
	if !strings.Contains(s, ":") {
		return false
	}
	return net.ParseIP(s) != nil
}
316639
func CheckIPWhitelist(remoteAddr string, ipRange string) (bool, error) {
	// Extract IP address from remote address.

	ip := remoteAddr

	if strings.LastIndex(remoteAddr, ":") != -1 {
		ip = remoteAddr[0:strings.LastIndex(remoteAddr, ":")]
	}

	ip = strings.TrimSpace(ip)

	// IPv6 addresses will likely be surrounded by [], so don't forget to remove those.

	if strings.HasPrefix(ip, "[") && strings.HasSuffix(ip, "]") {
		ip = ip[1 : len(ip)-1]
	}

	parsedIP := net.ParseIP(strings.TrimSpace(ip))

	if parsedIP == nil {
		return false, fmt.Errorf("invalid IP address found in remote address '%s'", remoteAddr)
	}

	// Extract IP range in CIDR form.  If a single IP address is provided, turn it into CIDR form.

	ipRange = strings.TrimSpace(ipRange)

	if !strings.Contains(ipRange, "/") {
		ipRange = ipRange + "/32"
	}

	_, cidr, err := net.ParseCIDR(ipRange)

	if err != nil {
		return false, err
	}

	return cidr.Contains(parsedIP), nil
}
503755
func includesIPv6(ips []net.IP) bool {
	for _, ip := range ips {
		if ip.To4() == nil && ip.To16() != nil {
			return true
		}
	}

	return false
}
385471
func IsIP6LinkLocal(m ma.Multiaddr) bool {
	m = zoneless(m)
	c, _ := ma.SplitFirst(m)
	if c == nil || c.Protocol().Code != ma.P_IP6 {
		return false
	}
	ip := net.IP(c.RawValue())
	return ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast()
}
980022
func IsIPv6(addr string) (bool, error) {
	ip := net.ParseIP(addr)
	if ip == nil {
		return false, fmt.Errorf("invalid IP address: %q", addr)
	}
	return ip.To4() == nil, nil
}
918891
func (ipv6 IPv6Addr) Contains(sa SockAddr) bool {
	ipv6b, ok := sa.(IPv6Addr)
	if !ok {
		return false
	}

	return ipv6.ContainsNetwork(ipv6b)
}
449512
func NewCiliumIPv6(address string) (CiliumIPv6, error) {
	ip, _, err := net.ParseCIDR(address)
	if err != nil {
		ip = net.ParseIP(address)
		if ip == nil {
			return nil, fmt.Errorf("Invalid IPv6 address: %s", address)
		}
	}

	// As result of ParseIP, ip is either a valid IPv6 or IPv4 address. net.IP
	// represents both versions on 16 bytes, so a more reliable way to tell
	// IPv4 and IPv6 apart is to see if it fits 4 bytes
	ip4 := ip.To4()
	if ip4 != nil {
		return nil, fmt.Errorf("Not an IPv6 address: %s", address)
	}
	return DeriveCiliumIPv6(ip.To16()), nil
}
912761
func GetPublicIPv6() ([]*net.IPAddr, error) {
	addresses, err := net.InterfaceAddrs()
	if err != nil {
		return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
	}

	var addrs []*net.IPAddr
	for _, rawAddr := range addresses {
		var ip net.IP
		switch addr := rawAddr.(type) {
		case *net.IPAddr:
			ip = addr.IP
		case *net.IPNet:
			ip = addr.IP
		default:
			continue
		}
		if ip.To4() != nil {
			continue
		}
		if isPrivate(ip) {
			continue
		}
		addrs = append(addrs, &net.IPAddr{IP: ip})
	}
	return addrs, nil
}
1366375
func SupportsIPv6() bool {
	ln, err := netListen("tcp6", "[::1]:0")
	if err != nil {
		return false
	}
	ln.Close()
	return true
}
1299723
func loopbackIP() net.IP {
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil
	}
	for _, inf := range interfaces {
		const flagUpLoopback = net.FlagUp | net.FlagLoopback
		if inf.Flags&flagUpLoopback == flagUpLoopback {
			addrs, _ := inf.Addrs()
			for _, addr := range addrs {
				ip, _, err := net.ParseCIDR(addr.String())
				if err == nil && ip.IsLoopback() {
					return ip
				}
			}
		}
	}
	return nil
}