github.com/gogf/gf@v1.16.9/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  	"github.com/gogf/gf/errors/gcode"
    12  	"github.com/gogf/gf/errors/gerror"
    13  	"net"
    14  	"strconv"
    15  	"strings"
    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  		return nil, err
    23  	}
    24  	for _, address := range interfaceAddr {
    25  		ipNet, isValidIpNet := address.(*net.IPNet)
    26  		if isValidIpNet && !ipNet.IP.IsLoopback() {
    27  			if ipNet.IP.To4() != nil {
    28  				ips = append(ips, ipNet.IP.String())
    29  			}
    30  		}
    31  	}
    32  	return ips, nil
    33  }
    34  
    35  // GetIntranetIp retrieves and returns the first intranet ip of current machine.
    36  func GetIntranetIp() (ip string, err error) {
    37  	ips, err := GetIntranetIpArray()
    38  	if err != nil {
    39  		return "", err
    40  	}
    41  	if len(ips) == 0 {
    42  		return "", gerror.NewCode(gcode.CodeOperationFailed, "no intranet ip found")
    43  	}
    44  	return ips[0], nil
    45  }
    46  
    47  // GetIntranetIpArray retrieves and returns the intranet ip list of current machine.
    48  func GetIntranetIpArray() (ips []string, err error) {
    49  	interFaces, e := net.Interfaces()
    50  	if e != nil {
    51  		return ips, e
    52  	}
    53  	for _, interFace := range interFaces {
    54  		if interFace.Flags&net.FlagUp == 0 {
    55  			// interface down
    56  			continue
    57  		}
    58  		if interFace.Flags&net.FlagLoopback != 0 {
    59  			// loopback interface
    60  			continue
    61  		}
    62  		// ignore warden bridge
    63  		if strings.HasPrefix(interFace.Name, "w-") {
    64  			continue
    65  		}
    66  		addresses, e := interFace.Addrs()
    67  		if e != nil {
    68  			return ips, e
    69  		}
    70  		for _, addr := range addresses {
    71  			var ip net.IP
    72  			switch v := addr.(type) {
    73  			case *net.IPNet:
    74  				ip = v.IP
    75  			case *net.IPAddr:
    76  				ip = v.IP
    77  			}
    78  
    79  			if ip == nil || ip.IsLoopback() {
    80  				continue
    81  			}
    82  			ip = ip.To4()
    83  			if ip == nil {
    84  				// not an ipv4 address
    85  				continue
    86  			}
    87  			ipStr := ip.String()
    88  			if IsIntranet(ipStr) {
    89  				ips = append(ips, ipStr)
    90  			}
    91  		}
    92  	}
    93  	return ips, nil
    94  }
    95  
    96  // IsIntranet checks and returns whether given ip an intranet ip.
    97  //
    98  // Local: 127.0.0.1
    99  // A: 10.0.0.0--10.255.255.255
   100  // B: 172.16.0.0--172.31.255.255
   101  // C: 192.168.0.0--192.168.255.255
   102  func IsIntranet(ip string) bool {
   103  	if ip == "127.0.0.1" {
   104  		return true
   105  	}
   106  	array := strings.Split(ip, ".")
   107  	if len(array) != 4 {
   108  		return false
   109  	}
   110  	// A
   111  	if array[0] == "10" || (array[0] == "192" && array[1] == "168") {
   112  		return true
   113  	}
   114  	// C
   115  	if array[0] == "192" && array[1] == "168" {
   116  		return true
   117  	}
   118  	// B
   119  	if array[0] == "172" {
   120  		second, err := strconv.ParseInt(array[1], 10, 64)
   121  		if err != nil {
   122  			return false
   123  		}
   124  		if second >= 16 && second <= 31 {
   125  			return true
   126  		}
   127  	}
   128  	return false
   129  }