mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-06 18:10: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
|
||
}
|