gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/util/addr/addr.go (about) 1 package addr 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 // Extract returns a real ip 31 func Extract(addr string) (string, error) { 32 // if addr specified then its returned 33 if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]" && addr != "::") { 34 return addr, nil 35 } 36 37 ifaces, err := net.Interfaces() 38 if err != nil { 39 return "", fmt.Errorf("Failed to get interfaces! Err: %v", err) 40 } 41 42 //nolint:prealloc 43 var addrs []net.Addr 44 var loAddrs []net.Addr 45 for _, iface := range ifaces { 46 ifaceAddrs, err := iface.Addrs() 47 if err != nil { 48 // ignore error, interface can dissapear from system 49 continue 50 } 51 if iface.Flags&net.FlagLoopback != 0 { 52 loAddrs = append(loAddrs, ifaceAddrs...) 53 continue 54 } 55 addrs = append(addrs, ifaceAddrs...) 56 } 57 addrs = append(addrs, loAddrs...) 58 59 var ipAddr []byte 60 var publicIP []byte 61 62 for _, rawAddr := range addrs { 63 var ip net.IP 64 switch addr := rawAddr.(type) { 65 case *net.IPAddr: 66 ip = addr.IP 67 case *net.IPNet: 68 ip = addr.IP 69 default: 70 continue 71 } 72 73 if !isPrivateIP(ip.String()) { 74 publicIP = ip 75 continue 76 } 77 78 ipAddr = ip 79 break 80 } 81 82 // return private ip 83 if ipAddr != nil { 84 return net.IP(ipAddr).String(), nil 85 } 86 87 // return public or virtual ip 88 if publicIP != nil { 89 return net.IP(publicIP).String(), nil 90 } 91 92 return "", fmt.Errorf("No IP address found, and explicit IP not provided") 93 } 94 95 // IPs returns all known ips 96 func IPs() []string { 97 ifaces, err := net.Interfaces() 98 if err != nil { 99 return nil 100 } 101 102 var ipAddrs []string 103 104 for _, i := range ifaces { 105 addrs, err := i.Addrs() 106 if err != nil { 107 continue 108 } 109 110 for _, addr := range addrs { 111 var ip net.IP 112 switch v := addr.(type) { 113 case *net.IPNet: 114 ip = v.IP 115 case *net.IPAddr: 116 ip = v.IP 117 } 118 119 if ip == nil { 120 continue 121 } 122 123 // dont skip ipv6 addrs 124 /* 125 ip = ip.To4() 126 if ip == nil { 127 continue 128 } 129 */ 130 131 ipAddrs = append(ipAddrs, ip.String()) 132 } 133 } 134 135 return ipAddrs 136 }