github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/util/ip.go (about) 1 package util 2 3 import ( 4 "net" 5 "net/http" 6 "strings" 7 "time" 8 ) 9 10 // InternalIPv4 获取内网地址 (IPv4) 11 func InternalIPv4() string { 12 return InternalIP("", "udp4") 13 } 14 15 // InternalIPv6 获取内网地址 (临时 IPv6 地址) 16 func InternalIPv6() string { 17 return InternalIP("[2001:4860:4860::8888]:53", "udp6") 18 } 19 20 // InternalIP 获取内网地址 (出口本地地址) 21 func InternalIP(dstAddr, network string) string { 22 if dstAddr == "" { 23 dstAddr = "8.8.8.8:53" 24 } 25 if network == "" { 26 network = "udp" 27 } 28 29 conn, err := net.DialTimeout(network, dstAddr, time.Second) 30 if err != nil { 31 return "" 32 } 33 34 defer func() { 35 _ = conn.Close() 36 }() 37 38 addr := conn.LocalAddr().String() 39 ip := net.ParseIP(addr).String() 40 if ip == "<nil>" { 41 ip, _, _ = net.SplitHostPort(addr) 42 } 43 44 return ip 45 } 46 47 // LocalIP 获取本地地址 (第一个) 48 func LocalIP() string { 49 addrs, err := net.InterfaceAddrs() 50 if err == nil { 51 for _, addr := range addrs { 52 if ipnet, ok := addr.(*net.IPNet); ok && 53 !ipnet.IP.IsLinkLocalUnicast() && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil { 54 return ipnet.IP.String() 55 } 56 } 57 } 58 59 return "" 60 } 61 62 // LocalIPv4s 获取所有本地地址 IPv4 63 func LocalIPv4s() (ips []string) { 64 addrs, err := net.InterfaceAddrs() 65 if err == nil { 66 for _, addr := range addrs { 67 if ipnet, ok := addr.(*net.IPNet); ok && 68 !ipnet.IP.IsLinkLocalUnicast() && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil { 69 ips = append(ips, ipnet.IP.String()) 70 } 71 } 72 } 73 74 return 75 } 76 77 // InterfaceAddrs 获取所有带 IP 的接口和对应的所有 IP 78 // 排除本地链路地址和环回地址 79 func InterfaceAddrs(v ...string) (map[string][]net.IP, error) { 80 ifAddrs := make(map[string][]net.IP) 81 ifaces, err := net.Interfaces() 82 if err != nil { 83 return ifAddrs, err 84 } 85 86 var ( 87 ip net.IP 88 t string 89 ) 90 if len(v) > 0 { 91 t = strings.ToLower(v[0]) 92 } 93 94 for _, i := range ifaces { 95 addrs, err := i.Addrs() 96 if err != nil { 97 return nil, err 98 } 99 for _, addr := range addrs { 100 switch v := addr.(type) { 101 case *net.IPNet: 102 ip = v.IP 103 case *net.IPAddr: 104 ip = v.IP 105 default: 106 ip = net.IPv4zero 107 } 108 if ip.IsLinkLocalUnicast() || ip.IsLoopback() { 109 continue 110 } 111 switch t { 112 case "ipv6": 113 if ip.To4() != nil { 114 continue 115 } 116 case "ipv4": 117 if ip.To4() == nil { 118 continue 119 } 120 } 121 ifAddrs[i.Name] = append(ifAddrs[i.Name], ip) 122 } 123 } 124 return ifAddrs, nil 125 } 126 127 // GetRealIP get user real ip 128 func GetRealIP(r *http.Request) (ip string) { 129 var header = r.Header 130 var index int 131 if ip = header.Get("X-Forwarded-For"); ip != "" { 132 index = strings.IndexByte(ip, ',') 133 if index < 0 { 134 return ip 135 } 136 if ip = ip[:index]; ip != "" { 137 return ip 138 } 139 } 140 if ip = header.Get("X-Real-Ip"); ip != "" { 141 index = strings.IndexByte(ip, ',') 142 if index < 0 { 143 return ip 144 } 145 if ip = ip[:index]; ip != "" { 146 return ip 147 } 148 } 149 if ip = header.Get("Proxy-Forwarded-For"); ip != "" { 150 index = strings.IndexByte(ip, ',') 151 if index < 0 { 152 return ip 153 } 154 if ip = ip[:index]; ip != "" { 155 return ip 156 } 157 } 158 ip, _, err := net.SplitHostPort(r.RemoteAddr) 159 if err != nil { 160 return "" 161 } 162 163 return ip 164 }