mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-12 06:10:25 +08:00
IP范围支持多行
This commit is contained in:
132
internal/waf/values/ip_range.go
Normal file
132
internal/waf/values/ip_range.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user