mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-02 03:40:27 +08:00
176 lines
3.2 KiB
Go
176 lines
3.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
|
"github.com/iwind/TeaGo/types"
|
|
)
|
|
|
|
// ParseIPValue 解析IP值
|
|
func ParseIPValue(value string) (newValue string, ipFrom string, ipTo string, ok bool) {
|
|
if len(value) == 0 {
|
|
return
|
|
}
|
|
|
|
newValue = value
|
|
|
|
// ip1-ip2
|
|
if strings.Contains(value, "-") {
|
|
var pieces = strings.Split(value, "-")
|
|
if len(pieces) != 2 {
|
|
return
|
|
}
|
|
|
|
ipFrom = strings.TrimSpace(pieces[0])
|
|
ipTo = strings.TrimSpace(pieces[1])
|
|
|
|
if !iputils.IsValid(ipFrom) || !iputils.IsValid(ipTo) {
|
|
return
|
|
}
|
|
|
|
if !iputils.IsSameVersion(ipFrom, ipTo) {
|
|
return
|
|
}
|
|
|
|
if iputils.CompareIP(ipFrom, ipTo) > 0 {
|
|
ipFrom, ipTo = ipTo, ipFrom
|
|
newValue = ipFrom + "-" + ipTo
|
|
}
|
|
|
|
ok = true
|
|
return
|
|
}
|
|
|
|
// ip/mask
|
|
if strings.Contains(value, "/") {
|
|
cidr, err := iputils.ParseCIDR(value)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return newValue, cidr.From().String(), cidr.To().String(), true
|
|
}
|
|
|
|
// single value
|
|
if iputils.IsValid(value) {
|
|
ipFrom = value
|
|
ok = true
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// ExtractIP 分解IP
|
|
// 只支持D段掩码的CIDR
|
|
// 最多只记录255个值
|
|
func ExtractIP(ipStrings string) ([]string, error) {
|
|
ipStrings = strings.ReplaceAll(ipStrings, " ", "")
|
|
|
|
// CIDR
|
|
if strings.Contains(ipStrings, "/") {
|
|
_, cidrNet, err := net.ParseCIDR(ipStrings)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var index = strings.Index(ipStrings, "/")
|
|
var ipFrom = ipStrings[:index]
|
|
var bits = types.Int(ipStrings[index+1:])
|
|
if bits < 24 {
|
|
return nil, errors.New("CIDR bits should be greater than 24")
|
|
}
|
|
|
|
var ipv4 = net.ParseIP(ipFrom).To4()
|
|
if len(ipv4) == 0 {
|
|
return nil, errors.New("support IPv4 only")
|
|
}
|
|
|
|
var result = []string{}
|
|
ipv4[3] = 0 // 从0开始
|
|
for i := 0; i <= 255; i++ {
|
|
if cidrNet.Contains(ipv4) {
|
|
result = append(result, ipv4.String())
|
|
}
|
|
ipv4 = NextIP(ipv4)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// IP Range
|
|
if strings.Contains(ipStrings, "-") {
|
|
var index = strings.Index(ipStrings, "-")
|
|
var ipFromString = ipStrings[:index]
|
|
var ipToString = ipStrings[index+1:]
|
|
|
|
var ipFrom = net.ParseIP(ipFromString).To4()
|
|
if len(ipFrom) == 0 {
|
|
return nil, errors.New("invalid ip '" + ipFromString + "'")
|
|
}
|
|
|
|
var ipTo = net.ParseIP(ipToString).To4()
|
|
if len(ipTo) == 0 {
|
|
return nil, errors.New("invalid ip '" + ipToString + "'")
|
|
}
|
|
|
|
if bytes.Compare(ipFrom, ipTo) > 0 {
|
|
ipFrom, ipTo = ipTo, ipFrom
|
|
}
|
|
|
|
var result = []string{}
|
|
for i := 0; i < 255; i++ {
|
|
if bytes.Compare(ipFrom, ipTo) > 0 {
|
|
break
|
|
}
|
|
result = append(result, ipFrom.String())
|
|
ipFrom = NextIP(ipFrom)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
return []string{ipStrings}, nil
|
|
}
|
|
|
|
// NextIP IP增加1
|
|
func NextIP(prevIP net.IP) net.IP {
|
|
var ip = make(net.IP, len(prevIP))
|
|
copy(ip, prevIP)
|
|
var index = len(ip) - 1
|
|
for {
|
|
if ip[index] == 255 {
|
|
ip[index] = 0
|
|
index--
|
|
if index < 0 {
|
|
break
|
|
}
|
|
} else {
|
|
ip[index]++
|
|
break
|
|
}
|
|
}
|
|
return ip
|
|
}
|
|
|
|
// IsLocalIP 判断是否为本地IP
|
|
// ip 是To4()或者To16()的结果
|
|
func IsLocalIP(ip net.IP) bool {
|
|
if ip == nil {
|
|
return false
|
|
}
|
|
|
|
if ip[0] == 127 ||
|
|
ip[0] == 10 ||
|
|
(ip[0] == 172 && ip[1]&0xf0 == 16) ||
|
|
(ip[0] == 192 && ip[1] == 168) {
|
|
return true
|
|
}
|
|
|
|
if ip.String() == "::1" {
|
|
return true
|
|
}
|
|
return false
|
|
}
|