github.com/amazechain/amc@v0.1.3/utils/network.go (about)

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