github.com/gogf/gf/v2@v2.7.4/net/gipv4/gipv4_ip.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  //
     7  
     8  package gipv4
     9  
    10  import (
    11  	"net"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/gogf/gf/v2/errors/gerror"
    16  )
    17  
    18  // GetIpArray retrieves and returns all the ip of current host.
    19  func GetIpArray() (ips []string, err error) {
    20  	interfaceAddr, err := net.InterfaceAddrs()
    21  	if err != nil {
    22  		err = gerror.Wrap(err, `net.InterfaceAddrs failed`)
    23  		return nil, err
    24  	}
    25  	for _, address := range interfaceAddr {
    26  		ipNet, isValidIpNet := address.(*net.IPNet)
    27  		if isValidIpNet && !ipNet.IP.IsLoopback() {
    28  			if ipNet.IP.To4() != nil {
    29  				ips = append(ips, ipNet.IP.String())
    30  			}
    31  		}
    32  	}
    33  	return ips, nil
    34  }
    35  
    36  // MustGetIntranetIp performs as GetIntranetIp, but it panics if any error occurs.
    37  func MustGetIntranetIp() string {
    38  	ip, err := GetIntranetIp()
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	return ip
    43  }
    44  
    45  // GetIntranetIp retrieves and returns the first intranet ip of current machine.
    46  func GetIntranetIp() (ip string, err error) {
    47  	ips, err := GetIntranetIpArray()
    48  	if err != nil {
    49  		return "", err
    50  	}
    51  	if len(ips) == 0 {
    52  		return "", gerror.New("no intranet ip found")
    53  	}
    54  	return ips[0], nil
    55  }
    56  
    57  // GetIntranetIpArray retrieves and returns the intranet ip list of current machine.
    58  func GetIntranetIpArray() (ips []string, err error) {
    59  	var (
    60  		addresses  []net.Addr
    61  		interFaces []net.Interface
    62  	)
    63  	interFaces, err = net.Interfaces()
    64  	if err != nil {
    65  		err = gerror.Wrap(err, `net.Interfaces failed`)
    66  		return ips, err
    67  	}
    68  	for _, interFace := range interFaces {
    69  		if interFace.Flags&net.FlagUp == 0 {
    70  			// interface down
    71  			continue
    72  		}
    73  		if interFace.Flags&net.FlagLoopback != 0 {
    74  			// loop back interface
    75  			continue
    76  		}
    77  		// ignore warden bridge
    78  		if strings.HasPrefix(interFace.Name, "w-") {
    79  			continue
    80  		}
    81  		addresses, err = interFace.Addrs()
    82  		if err != nil {
    83  			err = gerror.Wrap(err, `interFace.Addrs failed`)
    84  			return ips, err
    85  		}
    86  		for _, addr := range addresses {
    87  			var ip net.IP
    88  			switch v := addr.(type) {
    89  			case *net.IPNet:
    90  				ip = v.IP
    91  			case *net.IPAddr:
    92  				ip = v.IP
    93  			}
    94  
    95  			if ip == nil || ip.IsLoopback() {
    96  				continue
    97  			}
    98  			ip = ip.To4()
    99  			if ip == nil {
   100  				// not an ipv4 address
   101  				continue
   102  			}
   103  			ipStr := ip.String()
   104  			if IsIntranet(ipStr) {
   105  				ips = append(ips, ipStr)
   106  			}
   107  		}
   108  	}
   109  	return ips, nil
   110  }
   111  
   112  // IsIntranet checks and returns whether given ip an intranet ip.
   113  //
   114  // Local: 127.0.0.1
   115  // A: 10.0.0.0--10.255.255.255
   116  // B: 172.16.0.0--172.31.255.255
   117  // C: 192.168.0.0--192.168.255.255
   118  func IsIntranet(ip string) bool {
   119  	if ip == "127.0.0.1" {
   120  		return true
   121  	}
   122  	array := strings.Split(ip, ".")
   123  	if len(array) != 4 {
   124  		return false
   125  	}
   126  	// A
   127  	if array[0] == "10" || (array[0] == "192" && array[1] == "168") {
   128  		return true
   129  	}
   130  	// C
   131  	if array[0] == "192" && array[1] == "168" {
   132  		return true
   133  	}
   134  	// B
   135  	if array[0] == "172" {
   136  		second, err := strconv.ParseInt(array[1], 10, 64)
   137  		if err != nil {
   138  			return false
   139  		}
   140  		if second >= 16 && second <= 31 {
   141  			return true
   142  		}
   143  	}
   144  	return false
   145  }