mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-07 10:40:26 +08:00
133 lines
2.8 KiB
Go
133 lines
2.8 KiB
Go
|
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|||
|
|
|
|||
|
|
package values
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"bytes"
|
|||
|
|
"net"
|
|||
|
|
"strings"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type IPRangeType = string
|
|||
|
|
|
|||
|
|
const (
|
|||
|
|
IPRangeTypeCIDR IPRangeType = "cidr" // CIDR
|
|||
|
|
IPRangeTypeSingeIP IPRangeType = "singleIP" // 单个IP
|
|||
|
|
IPRangeTypeRange IPRangeType = "range" // IP范围,IP1-IP2
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type IPRange struct {
|
|||
|
|
Type IPRangeType
|
|||
|
|
CIDR *net.IPNet
|
|||
|
|
IPFrom net.IP
|
|||
|
|
IPTo net.IP
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (this *IPRange) Contains(netIP net.IP) bool {
|
|||
|
|
if netIP == nil {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
switch this.Type {
|
|||
|
|
case IPRangeTypeCIDR:
|
|||
|
|
if this.CIDR != nil {
|
|||
|
|
return this.CIDR.Contains(netIP)
|
|||
|
|
}
|
|||
|
|
case IPRangeTypeSingeIP:
|
|||
|
|
if this.IPFrom != nil {
|
|||
|
|
return bytes.Equal(this.IPFrom, netIP)
|
|||
|
|
}
|
|||
|
|
case IPRangeTypeRange:
|
|||
|
|
return bytes.Compare(this.IPFrom, netIP) <= 0 && bytes.Compare(this.IPTo, netIP) >= 0
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type IPRangeList struct {
|
|||
|
|
Ranges []*IPRange
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func NewIPRangeList() *IPRangeList {
|
|||
|
|
return &IPRangeList{}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func ParseIPRangeList(value string) *IPRangeList {
|
|||
|
|
var list = NewIPRangeList()
|
|||
|
|
|
|||
|
|
if len(value) == 0 {
|
|||
|
|
return list
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lines = strings.Split(value, "\n")
|
|||
|
|
for _, line := range lines {
|
|||
|
|
line = strings.TrimSpace(line)
|
|||
|
|
if len(line) == 0 {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if strings.Contains(line, ",") { // IPFrom,IPTo
|
|||
|
|
var pieces = strings.SplitN(line, ",", 2)
|
|||
|
|
if len(pieces) == 2 {
|
|||
|
|
var ipFrom = net.ParseIP(strings.TrimSpace(pieces[0]))
|
|||
|
|
var ipTo = net.ParseIP(strings.TrimSpace(pieces[1]))
|
|||
|
|
if ipFrom != nil && ipTo != nil {
|
|||
|
|
if bytes.Compare(ipFrom, ipTo) > 0 {
|
|||
|
|
ipFrom, ipTo = ipTo, ipFrom
|
|||
|
|
}
|
|||
|
|
list.Ranges = append(list.Ranges, &IPRange{
|
|||
|
|
Type: IPRangeTypeRange,
|
|||
|
|
IPFrom: ipFrom,
|
|||
|
|
IPTo: ipTo,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if strings.Contains(line, "-") { // IPFrom-IPTo
|
|||
|
|
var pieces = strings.SplitN(line, "-", 2)
|
|||
|
|
if len(pieces) == 2 {
|
|||
|
|
var ipFrom = net.ParseIP(strings.TrimSpace(pieces[0]))
|
|||
|
|
var ipTo = net.ParseIP(strings.TrimSpace(pieces[1]))
|
|||
|
|
if ipFrom != nil && ipTo != nil {
|
|||
|
|
if bytes.Compare(ipFrom, ipTo) > 0 {
|
|||
|
|
ipFrom, ipTo = ipTo, ipFrom
|
|||
|
|
}
|
|||
|
|
list.Ranges = append(list.Ranges, &IPRange{
|
|||
|
|
Type: IPRangeTypeRange,
|
|||
|
|
IPFrom: ipFrom,
|
|||
|
|
IPTo: ipTo,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if strings.Contains(line, "/") { // CIDR
|
|||
|
|
_, cidr, _ := net.ParseCIDR(line)
|
|||
|
|
if cidr != nil {
|
|||
|
|
list.Ranges = append(list.Ranges, &IPRange{
|
|||
|
|
Type: IPRangeTypeCIDR,
|
|||
|
|
CIDR: cidr,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
} else { // single ip
|
|||
|
|
var netIP = net.ParseIP(line)
|
|||
|
|
if netIP != nil {
|
|||
|
|
list.Ranges = append(list.Ranges, &IPRange{
|
|||
|
|
Type: IPRangeTypeSingeIP,
|
|||
|
|
IPFrom: netIP,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return list
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (this *IPRangeList) Contains(ip string) bool {
|
|||
|
|
var netIP = net.ParseIP(ip)
|
|||
|
|
if netIP == nil {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
for _, r := range this.Ranges {
|
|||
|
|
if r.Contains(netIP) {
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|