2021-09-22 22:38:06 +00:00
|
|
|
// Package network contains useful functions for ip address formatting.
|
2021-09-16 19:12:27 +00:00
|
|
|
package network
|
2018-08-14 16:16:21 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
2020-09-17 03:02:20 +00:00
|
|
|
"sort"
|
2018-08-14 16:16:21 +00:00
|
|
|
)
|
|
|
|
|
2022-08-17 06:38:57 +00:00
|
|
|
// IPAddr gets the external ipv4 address and converts into a libp2p formatted value.
|
|
|
|
func IPAddr() net.IP {
|
|
|
|
ip, err := ExternalIP()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return net.ParseIP(ip)
|
|
|
|
}
|
|
|
|
|
2018-08-14 16:16:21 +00:00
|
|
|
// ExternalIPv4 returns the first IPv4 available.
|
|
|
|
func ExternalIPv4() (string, error) {
|
2021-01-25 21:27:30 +00:00
|
|
|
ips, err := ipAddrs()
|
2020-09-16 00:17:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if len(ips) == 0 {
|
|
|
|
return "127.0.0.1", nil
|
|
|
|
}
|
|
|
|
for _, ip := range ips {
|
|
|
|
ip = ip.To4()
|
|
|
|
if ip == nil {
|
|
|
|
continue // not an ipv4 address
|
|
|
|
}
|
|
|
|
return ip.String(), nil
|
|
|
|
}
|
|
|
|
return "127.0.0.1", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExternalIP returns the first IPv4/IPv6 available.
|
|
|
|
func ExternalIP() (string, error) {
|
2021-01-25 21:27:30 +00:00
|
|
|
ips, err := ipAddrs()
|
2018-08-14 16:16:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2020-09-16 00:17:22 +00:00
|
|
|
if len(ips) == 0 {
|
|
|
|
return "127.0.0.1", nil
|
|
|
|
}
|
|
|
|
return ips[0].String(), nil
|
|
|
|
}
|
|
|
|
|
2021-01-25 21:27:30 +00:00
|
|
|
// ipAddrs returns all the valid IPs available.
|
|
|
|
func ipAddrs() ([]net.IP, error) {
|
2020-09-16 00:17:22 +00:00
|
|
|
ifaces, err := net.Interfaces()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-10-12 08:11:05 +00:00
|
|
|
var ipAddrs []net.IP
|
2018-08-14 16:16:21 +00:00
|
|
|
for _, iface := range ifaces {
|
|
|
|
if iface.Flags&net.FlagUp == 0 {
|
|
|
|
continue // interface down
|
|
|
|
}
|
|
|
|
if iface.Flags&net.FlagLoopback != 0 {
|
|
|
|
continue // loopback interface
|
|
|
|
}
|
|
|
|
addrs, err := iface.Addrs()
|
|
|
|
if err != nil {
|
2020-09-16 00:17:22 +00:00
|
|
|
return nil, err
|
2018-08-14 16:16:21 +00:00
|
|
|
}
|
|
|
|
for _, addr := range addrs {
|
|
|
|
var ip net.IP
|
|
|
|
switch v := addr.(type) {
|
|
|
|
case *net.IPNet:
|
|
|
|
ip = v.IP
|
|
|
|
case *net.IPAddr:
|
|
|
|
ip = v.IP
|
|
|
|
}
|
2020-09-17 03:02:20 +00:00
|
|
|
if ip == nil || ip.IsLoopback() || ip.IsLinkLocalUnicast() {
|
2018-08-14 16:16:21 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-09-16 00:17:22 +00:00
|
|
|
ipAddrs = append(ipAddrs, ip)
|
2018-08-14 16:16:21 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-17 03:02:20 +00:00
|
|
|
return SortAddresses(ipAddrs), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SortAddresses sorts a set of addresses in the order of
|
|
|
|
// ipv4 -> ipv6.
|
|
|
|
func SortAddresses(ipAddrs []net.IP) []net.IP {
|
|
|
|
sort.Slice(ipAddrs, func(i, j int) bool {
|
|
|
|
return ipAddrs[i].To4() != nil && ipAddrs[j].To4() == nil
|
|
|
|
})
|
|
|
|
return ipAddrs
|
2018-08-14 16:16:21 +00:00
|
|
|
}
|