github.com/zhongdalu/gf@v1.0.0/g/net/gipv4/gipv4.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf.
     6  //
     7  
     8  // Package gipv4 provides useful API for IPv4 address handling.
     9  package gipv4
    10  
    11  import (
    12  	"encoding/binary"
    13  	"fmt"
    14  	"github.com/zhongdalu/gf/g/text/gregex"
    15  	"net"
    16  	"regexp"
    17  	"strconv"
    18  	"strings"
    19  )
    20  
    21  // 判断所给地址是否是一个IPv4地址
    22  func Validate(ip string) bool {
    23  	return gregex.IsMatchString(`^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$`, ip)
    24  }
    25  
    26  // Get the IPv4 address corresponding to a given Internet host name.
    27  func GetHostByName(hostname string) (string, error) {
    28  	ips, err := net.LookupIP(hostname)
    29  	if ips != nil {
    30  		for _, v := range ips {
    31  			if v.To4() != nil {
    32  				return v.String(), nil
    33  			}
    34  		}
    35  		return "", nil
    36  	}
    37  	return "", err
    38  }
    39  
    40  // Get a list of IPv4 addresses corresponding to a given Internet host name.
    41  func GetHostsByName(hostname string) ([]string, error) {
    42  	ips, err := net.LookupIP(hostname)
    43  	if ips != nil {
    44  		var ipStrs []string
    45  		for _, v := range ips {
    46  			if v.To4() != nil {
    47  				ipStrs = append(ipStrs, v.String())
    48  			}
    49  		}
    50  		return ipStrs, nil
    51  	}
    52  	return nil, err
    53  }
    54  
    55  // Get the Internet host name corresponding to a given IP address.
    56  func GetNameByAddr(ipAddress string) (string, error) {
    57  	names, err := net.LookupAddr(ipAddress)
    58  	if names != nil {
    59  		return strings.TrimRight(names[0], "."), nil
    60  	}
    61  	return "", err
    62  }
    63  
    64  // IP字符串转为整形.
    65  func Ip2long(ipAddress string) uint32 {
    66  	ip := net.ParseIP(ipAddress)
    67  	if ip == nil {
    68  		return 0
    69  	}
    70  	return binary.BigEndian.Uint32(ip.To4())
    71  }
    72  
    73  // ip整形转为字符串
    74  func Long2ip(properAddress uint32) string {
    75  	ipByte := make([]byte, 4)
    76  	binary.BigEndian.PutUint32(ipByte, properAddress)
    77  	return net.IP(ipByte).String()
    78  }
    79  
    80  // 获得ip的网段,例如:192.168.2.102 -> 192.168.2
    81  func GetSegment(ip string) string {
    82  	r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$`
    83  	reg, err := regexp.Compile(r)
    84  	if err != nil {
    85  		return ""
    86  	}
    87  	ips := reg.FindStringSubmatch(ip)
    88  	if ips == nil {
    89  		return ""
    90  	}
    91  	return fmt.Sprintf("%s.%s.%s", ips[1], ips[2], ips[3])
    92  }
    93  
    94  // 解析地址,形如:192.168.1.1:80 -> 192.168.1.1, 80
    95  func ParseAddress(addr string) (string, int) {
    96  	r := `^(.+):(\d+)$`
    97  	reg, err := regexp.Compile(r)
    98  	if err != nil {
    99  		return "", 0
   100  	}
   101  	result := reg.FindStringSubmatch(addr)
   102  	if result != nil {
   103  		i, _ := strconv.Atoi(result[2])
   104  		return result[1], i
   105  	}
   106  	return "", 0
   107  }
   108  
   109  // 获取本地局域网ip列表
   110  func IntranetIP() (ips []string, err error) {
   111  	ips = make([]string, 0)
   112  	ifaces, e := net.Interfaces()
   113  	if e != nil {
   114  		return ips, e
   115  	}
   116  	for _, iface := range ifaces {
   117  		if iface.Flags&net.FlagUp == 0 {
   118  			continue // interface down
   119  		}
   120  
   121  		if iface.Flags&net.FlagLoopback != 0 {
   122  			continue // loopback interface
   123  		}
   124  
   125  		// ignore warden bridge
   126  		if strings.HasPrefix(iface.Name, "w-") {
   127  			continue
   128  		}
   129  
   130  		addrs, e := iface.Addrs()
   131  		if e != nil {
   132  			return ips, e
   133  		}
   134  
   135  		for _, addr := range addrs {
   136  			var ip net.IP
   137  			switch v := addr.(type) {
   138  			case *net.IPNet:
   139  				ip = v.IP
   140  			case *net.IPAddr:
   141  				ip = v.IP
   142  			}
   143  
   144  			if ip == nil || ip.IsLoopback() {
   145  				continue
   146  			}
   147  
   148  			ip = ip.To4()
   149  			if ip == nil {
   150  				continue // not an ipv4 address
   151  			}
   152  
   153  			ipStr := ip.String()
   154  			if IsIntranet(ipStr) {
   155  				ips = append(ips, ipStr)
   156  			}
   157  		}
   158  	}
   159  	return ips, nil
   160  }
   161  
   162  // 判断所给ip是否为局域网ip
   163  // A类 10.0.0.0--10.255.255.255
   164  // B类 172.16.0.0--172.31.255.255
   165  // C类 192.168.0.0--192.168.255.255
   166  func IsIntranet(ipStr string) bool {
   167  	// ip协议保留的局域网ip
   168  	if strings.HasPrefix(ipStr, "10.") || strings.HasPrefix(ipStr, "192.168.") {
   169  		return true
   170  	}
   171  	if strings.HasPrefix(ipStr, "172.") {
   172  		// 172.16.0.0 - 172.31.255.255
   173  		arr := strings.Split(ipStr, ".")
   174  		if len(arr) != 4 {
   175  			return false
   176  		}
   177  
   178  		second, err := strconv.ParseInt(arr[1], 10, 64)
   179  		if err != nil {
   180  			return false
   181  		}
   182  
   183  		if second >= 16 && second <= 31 {
   184  			return true
   185  		}
   186  	}
   187  
   188  	return false
   189  }