You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.6 KiB
144 lines
3.6 KiB
package utils
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
Ipv4Type = "ipv4"
|
|
Ipv6Type = "ipv6"
|
|
)
|
|
|
|
type (
|
|
Ipv4 [2]net.IP
|
|
Ipv6 [2]net.IP
|
|
)
|
|
|
|
type IpInter interface {
|
|
Type() string
|
|
CheckIpRange() error
|
|
IpString() string
|
|
IsContain(target IpInter) bool
|
|
}
|
|
|
|
//NewIpRange 创建一个ipv4或者ipv6的范围,如果为nil则是错误ip
|
|
func NewIpRange(s string) IpInter {
|
|
ipArr := strings.Split(s, "-")
|
|
if len(ipArr) == 1 {
|
|
ipArr = append(ipArr, ipArr[0])
|
|
}
|
|
|
|
var ips [2]net.IP
|
|
for i, v := range ipArr {
|
|
ip := net.ParseIP(v)
|
|
if ip == nil {
|
|
return nil
|
|
}
|
|
ips[i] = ip
|
|
}
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
switch s[i] {
|
|
case '.':
|
|
return Ipv4(ips)
|
|
case ':':
|
|
return Ipv6(ips)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Type 获取ip类型
|
|
func (i Ipv4) Type() string {
|
|
return Ipv4Type
|
|
}
|
|
func (i Ipv6) Type() string {
|
|
return Ipv6Type
|
|
}
|
|
|
|
// CheckIpRange 判断ip范围是否是由小到大
|
|
func (i Ipv4) CheckIpRange() error {
|
|
for j := 0; j < 16; j++ {
|
|
if i[0][j] < i[1][j] {
|
|
return nil
|
|
}
|
|
if i[0][j] > i[1][j] {
|
|
return errors.New("ip范围错误,不是由小到大配置!")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
func (i Ipv6) CheckIpRange() error {
|
|
for j := 0; j < 16; j++ {
|
|
if i[0][j] < i[1][j] {
|
|
return nil
|
|
}
|
|
if i[0][j] > i[1][j] {
|
|
return errors.New("ip范围错误,不是由小到大配置!")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IpString 返回ip的字符串
|
|
func (i Ipv4) IpString() string {
|
|
if i[0].String() == i[1].String() {
|
|
return i[0].String()
|
|
}
|
|
return strings.Join([]string{i[0].String(), i[1].String()}, "-")
|
|
}
|
|
func (i Ipv6) IpString() string {
|
|
if i[0].String() == i[1].String() {
|
|
return i[0].String()
|
|
}
|
|
return strings.Join([]string{i[0].String(), i[1].String()}, "-")
|
|
}
|
|
|
|
// IsContain 判断当前ip范围是否包含在目标配置ip范围内
|
|
func (i Ipv4) IsContain(target IpInter) bool {
|
|
iLeft := Ipv4ToUint32(i[0])
|
|
iRight := Ipv4ToUint32(i[1])
|
|
tLeft := Ipv4ToUint32(target.(Ipv4)[0])
|
|
tRight := Ipv4ToUint32(target.(Ipv4)[1])
|
|
if tLeft == tRight {
|
|
return i.isContainSingleIp(iLeft, iRight, tLeft)
|
|
}
|
|
return i.isContainSingleIp(iLeft, iRight, tLeft) || i.isContainSingleIp(iLeft, iRight, tRight)
|
|
}
|
|
func (i Ipv6) IsContain(target IpInter) bool {
|
|
iLeft := Ipv6ToUint128(i[0])
|
|
iRight := Ipv6ToUint128(i[1])
|
|
tLeft := Ipv6ToUint128(target.(Ipv6)[0])
|
|
tRight := Ipv6ToUint128(target.(Ipv6)[1])
|
|
if tLeft == tRight {
|
|
return i.isContainSingleIp(iLeft, iRight, tLeft)
|
|
}
|
|
return i.isContainSingleIp(iLeft, iRight, tLeft) || i.isContainSingleIp(iLeft, iRight, tRight)
|
|
}
|
|
|
|
// isContainSingleIp 判断当前ip范围中的单个ip是否包含在目标配置ip范围内
|
|
func (i Ipv4) isContainSingleIp(iLeft, iRight, targetIp uint32) bool {
|
|
return iLeft <= targetIp && iRight >= targetIp
|
|
}
|
|
func (i Ipv6) isContainSingleIp(iLeft, iRight, targetIp Uint128) bool {
|
|
return iLeft.H <= targetIp.H && iRight.H >= targetIp.H && iLeft.L <= targetIp.L && iRight.L >= targetIp.L
|
|
}
|
|
|
|
// Ipv4ToUint32 把ipv4转为uint32
|
|
func Ipv4ToUint32(ipv4 net.IP) uint32 {
|
|
b := ipv4.To4()
|
|
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
|
}
|
|
|
|
// Ipv6ToUint128 把ipv6转为uint128
|
|
func Ipv6ToUint128(Ipv6 net.IP) Uint128 {
|
|
return makeUint128([]uint32{uint32(Ipv6[0])<<24 | uint32(Ipv6[1])<<16 | uint32(Ipv6[2])<<8 | uint32(Ipv6[3]), uint32(Ipv6[4])<<24 | uint32(Ipv6[5])<<16 | uint32(Ipv6[6])<<8 | uint32(Ipv6[7]), uint32(Ipv6[8])<<24 | uint32(Ipv6[9])<<16 | uint32(Ipv6[10])<<8 | uint32(Ipv6[11]), uint32(Ipv6[12])<<24 | uint32(Ipv6[13])<<16 | uint32(Ipv6[14])<<8 | uint32(Ipv6[15])})
|
|
}
|
|
|
|
func makeUint128(a []uint32) Uint128 {
|
|
return Uint128{H: uint64(a[0])<<32 | uint64(a[1]),
|
|
L: uint64(a[2])<<32 | uint64(a[3])}
|
|
}
|
|
|