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  }