github.com/prysmaticlabs/prysm@v1.4.4/shared/iputils/external_ip.go (about)

     1  // Package iputils contains useful functions for ip address formatting.
     2  package iputils
     3  
     4  import (
     5  	"net"
     6  	"sort"
     7  )
     8  
     9  // ExternalIPv4 returns the first IPv4 available.
    10  func ExternalIPv4() (string, error) {
    11  	ips, err := ipAddrs()
    12  	if err != nil {
    13  		return "", err
    14  	}
    15  	if len(ips) == 0 {
    16  		return "127.0.0.1", nil
    17  	}
    18  	for _, ip := range ips {
    19  		ip = ip.To4()
    20  		if ip == nil {
    21  			continue // not an ipv4 address
    22  		}
    23  		return ip.String(), nil
    24  	}
    25  	return "127.0.0.1", nil
    26  }
    27  
    28  // ExternalIP returns the first IPv4/IPv6 available.
    29  func ExternalIP() (string, error) {
    30  	ips, err := ipAddrs()
    31  	if err != nil {
    32  		return "", err
    33  	}
    34  	if len(ips) == 0 {
    35  		return "127.0.0.1", nil
    36  	}
    37  	return ips[0].String(), nil
    38  }
    39  
    40  // ipAddrs returns all the valid IPs available.
    41  func ipAddrs() ([]net.IP, error) {
    42  	ifaces, err := net.Interfaces()
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	var ipAddrs []net.IP
    47  	for _, iface := range ifaces {
    48  		if iface.Flags&net.FlagUp == 0 {
    49  			continue // interface down
    50  		}
    51  		if iface.Flags&net.FlagLoopback != 0 {
    52  			continue // loopback interface
    53  		}
    54  		addrs, err := iface.Addrs()
    55  		if err != nil {
    56  			return nil, err
    57  		}
    58  		for _, addr := range addrs {
    59  			var ip net.IP
    60  			switch v := addr.(type) {
    61  			case *net.IPNet:
    62  				ip = v.IP
    63  			case *net.IPAddr:
    64  				ip = v.IP
    65  			}
    66  			if ip == nil || ip.IsLoopback() || ip.IsLinkLocalUnicast() {
    67  				continue
    68  			}
    69  			ipAddrs = append(ipAddrs, ip)
    70  		}
    71  	}
    72  	return SortAddresses(ipAddrs), nil
    73  }
    74  
    75  // SortAddresses sorts a set of addresses in the order of
    76  // ipv4 -> ipv6.
    77  func SortAddresses(ipAddrs []net.IP) []net.IP {
    78  	sort.Slice(ipAddrs, func(i, j int) bool {
    79  		return ipAddrs[i].To4() != nil && ipAddrs[j].To4() == nil
    80  	})
    81  	return ipAddrs
    82  }