github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xnet/addr.go (about) 1 package xnet 2 3 import ( 4 "fmt" 5 "net" 6 ) 7 8 var ( 9 privateBlocks []*net.IPNet 10 ) 11 12 func init() { 13 for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10", "fd00::/8"} { 14 if _, block, err := net.ParseCIDR(b); err == nil { 15 privateBlocks = append(privateBlocks, block) 16 } 17 } 18 } 19 20 func isPrivateIP(ipAddr string) bool { 21 ip := net.ParseIP(ipAddr) 22 for _, priv := range privateBlocks { 23 if priv.Contains(ip) { 24 return true 25 } 26 } 27 return false 28 } 29 30 // PrivateAddress returns a real ip 31 func PrivateAddress() (string, error) { 32 ifaces, err := net.Interfaces() 33 if err != nil { 34 return "", fmt.Errorf("failed to get interfaces! Err: %v", err) 35 } 36 37 var addrs []net.Addr 38 for _, iface := range ifaces { 39 ifaceAddrs, err := iface.Addrs() 40 if err != nil { 41 // ignore error, interface can dissapear from system 42 continue 43 } 44 addrs = append(addrs, ifaceAddrs...) 45 } 46 47 var ipAddr []byte 48 var publicIP []byte 49 50 for _, rawAddr := range addrs { 51 var ip net.IP 52 switch addr := rawAddr.(type) { 53 case *net.IPAddr: 54 ip = addr.IP 55 case *net.IPNet: 56 ip = addr.IP 57 default: 58 continue 59 } 60 61 if !isPrivateIP(ip.String()) { 62 publicIP = ip 63 continue 64 } 65 66 ipAddr = ip 67 break 68 } 69 70 // return private ip 71 if ipAddr != nil { 72 return net.IP(ipAddr).String(), nil 73 } 74 75 // return public or virtual ip 76 if publicIP != nil { 77 return net.IP(publicIP).String(), nil 78 } 79 80 return "", fmt.Errorf("err: no IP address found, and explicit IP not provided") 81 } 82 83 // IPAddresses returns all known ips 84 func IPAddresses() []string { 85 ifaces, err := net.Interfaces() 86 if err != nil { 87 return nil 88 } 89 90 var ipAddrs []string 91 92 for _, i := range ifaces { 93 addrs, err := i.Addrs() 94 if err != nil { 95 continue 96 } 97 98 for _, addr := range addrs { 99 var ip net.IP 100 switch v := addr.(type) { 101 case *net.IPNet: 102 ip = v.IP 103 case *net.IPAddr: 104 ip = v.IP 105 } 106 107 if ip == nil { 108 continue 109 } 110 111 // dont skip ipv6 addrs 112 /* 113 ip = ip.To4() 114 if ip == nil { 115 continue 116 } 117 */ 118 119 ipAddrs = append(ipAddrs, ip.String()) 120 } 121 } 122 123 return ipAddrs 124 }