github.com/sandwich-go/boost@v1.3.29/xip/ip.go (about)

     1  package xip
     2  
     3  import (
     4  	"net"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  // LocalIpv4Addrs scan all ip addresses with loopback excluded.
    11  func LocalIpv4Addrs() (ips []string, err error) {
    12  	ips = make([]string, 0)
    13  
    14  	ifaces, e := net.Interfaces()
    15  	if e != nil {
    16  		return ips, e
    17  	}
    18  
    19  	for _, iface := range ifaces {
    20  		if iface.Flags&net.FlagUp == 0 {
    21  			continue // interface down
    22  		}
    23  
    24  		if iface.Flags&net.FlagLoopback != 0 {
    25  			continue // loopback interface
    26  		}
    27  
    28  		// ignore docker and warden bridge
    29  		if strings.HasPrefix(iface.Name, "docker") || strings.HasPrefix(iface.Name, "w-") {
    30  			continue
    31  		}
    32  
    33  		addrs, e := iface.Addrs()
    34  		if e != nil {
    35  			return ips, e
    36  		}
    37  
    38  		for _, addr := range addrs {
    39  			var ip net.IP
    40  			switch v := addr.(type) {
    41  			case *net.IPNet:
    42  				ip = v.IP
    43  			case *net.IPAddr:
    44  				ip = v.IP
    45  			}
    46  
    47  			if ip == nil || ip.IsLoopback() {
    48  				continue
    49  			}
    50  
    51  			ip = ip.To4()
    52  			if ip == nil {
    53  				continue // not an ipv4 address
    54  			}
    55  
    56  			ipStr := ip.String()
    57  			if IsIntranet(ipStr) {
    58  				ips = append(ips, ipStr)
    59  			}
    60  		}
    61  	}
    62  
    63  	return ips, nil
    64  }
    65  
    66  // IsIntranet 是否是内网地址
    67  func IsIntranet(ipStr string) bool {
    68  	if strings.HasPrefix(ipStr, "10.") || strings.HasPrefix(ipStr, "192.168.") {
    69  		return true
    70  	}
    71  	if strings.HasPrefix(ipStr, "172.") {
    72  		// 172.16.0.0-172.31.255.255
    73  		arr := strings.Split(ipStr, ".")
    74  		if len(arr) != 4 {
    75  			return false
    76  		}
    77  		second, err := strconv.ParseInt(arr[1], 10, 64)
    78  		if err != nil {
    79  			return false
    80  		}
    81  		if second >= 16 && second <= 31 {
    82  			return true
    83  		}
    84  	}
    85  	return false
    86  }
    87  
    88  // GetLocalIP returns the non loopback local IP of the host
    89  // 该接口在 POD 中可能会获取到空的 local IP
    90  func GetLocalIP() string {
    91  	addrs, err := LocalIpv4Addrs()
    92  	if err != nil || len(addrs) == 0 {
    93  		return ""
    94  	}
    95  	return addrs[0]
    96  }
    97  
    98  var ip4Reg = regexp.MustCompile(`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)
    99  
   100  // IsValidIP4 是否是合法的 ip4 地址
   101  func IsValidIP4(ipAddress string) bool {
   102  	ipAddress = strings.Trim(ipAddress, " ")
   103  	if i := strings.LastIndex(ipAddress, ":"); i >= 0 {
   104  		ipAddress = ipAddress[:i] //remove port
   105  	}
   106  	return ip4Reg.MatchString(ipAddress)
   107  }