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 }