|
|
|
@ -2,11 +2,13 @@ package ipcheck |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"gitea.drugeyes.vip/pharnexbase/ipcheck/utils" |
|
|
|
|
"sort" |
|
|
|
|
"strings" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
//SingleIpInRange 单个ip地址(范围)判断是否在配置ip范围内
|
|
|
|
|
// SingleIpInRange 单个ip地址(范围)判断是否在配置ip范围内
|
|
|
|
|
func SingleIpInRange(ip, ipConfigStr string) (bool, error) { |
|
|
|
|
singleIp := utils.NewIpRange(ip) |
|
|
|
|
if singleIp == nil { |
|
|
|
@ -22,7 +24,7 @@ func SingleIpInRange(ip, ipConfigStr string) (bool, error) { |
|
|
|
|
for _, ipConfig := range ipConfigArr { |
|
|
|
|
containIp := utils.NewIpRange(ipConfig) |
|
|
|
|
if containIp != nil && singleIp.Type() == containIp.Type() { //只有ip类型相同才判断范围
|
|
|
|
|
if containIp.IsContain(singleIp) == true { |
|
|
|
|
if containIp.IsContain(singleIp) { |
|
|
|
|
return true, nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -30,3 +32,103 @@ func SingleIpInRange(ip, ipConfigStr string) (bool, error) { |
|
|
|
|
|
|
|
|
|
return false, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MultipleIpInRange 多个ip地址判断是否在配置ip范围内(该方法在ips很多,且配置ip很多的时候会有速度提升,单个ip的时候不建议使用该方法)
|
|
|
|
|
func MultipleIpInRange(ips, ipConfigStr []string) (bool, string, error) { |
|
|
|
|
ownerIpv4s, ownerIpv6s, errIp, err := FilterIpAndSort(ips) |
|
|
|
|
if err != nil { |
|
|
|
|
return false, errIp, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
containIpv4s, containIpv6s, errIp, err := FilterIpAndSort(strings.Split(strings.ReplaceAll(strings.Join(ipConfigStr, "\n"), "\r\n", "\n"), "\n")) |
|
|
|
|
if err != nil { |
|
|
|
|
return false, errIp, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//优化步骤
|
|
|
|
|
var ipv4Start uint32 = 0 //自己ip段重复也需要提示
|
|
|
|
|
//处理判断ipv4(双指针)
|
|
|
|
|
for i, j := 0, 0; i < len(ownerIpv4s) && j < len(containIpv4s); { |
|
|
|
|
ownerLeft := utils.Ipv4ToUint32(ownerIpv4s[i][0]) |
|
|
|
|
ownerRight := utils.Ipv4ToUint32(ownerIpv4s[i][1]) |
|
|
|
|
if ownerLeft > utils.Ipv4ToUint32(containIpv4s[j][1]) { //如果范围ip右边值都比目标ip的左边值小则增加范围ip的指针
|
|
|
|
|
j++ |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if containIpv4s[j].IsContain(ownerIpv4s[i]) || ownerIpv4s[i].IsContain(containIpv4s[j]) { |
|
|
|
|
return true, fmt.Sprintf("%s<-->%s", ownerIpv4s[i].IpString(), containIpv4s[j].IpString()), errors.New("输入ip与已存在ip配置范围重叠!") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ipv4Start >= ownerLeft { //判断自己ip段是否重复,重复就返回重复的ip
|
|
|
|
|
if i > 0 { |
|
|
|
|
return false, fmt.Sprintf("%s<-->%s", ownerIpv4s[i-1].IpString(), ownerIpv4s[i].IpString()), errors.New("输入ip范围重叠!") |
|
|
|
|
} |
|
|
|
|
return false, ownerIpv4s[i].IpString(), errors.New("请勿填写0.0.0.0和0:0:0:0:0:0:0:0等无效ip!") |
|
|
|
|
} |
|
|
|
|
ipv4Start = ownerRight |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ipv6Start = utils.Uint128{H: 0, L: 0} //自己ip段重复也需要提示
|
|
|
|
|
//处理判断ipv6(双指针)
|
|
|
|
|
for i, j := 0, 0; i < len(ownerIpv6s) && j < len(containIpv6s); { |
|
|
|
|
ownerLeft := utils.Ipv6ToUint128(ownerIpv6s[i][0]) |
|
|
|
|
ownerRight := utils.Ipv6ToUint128(ownerIpv6s[i][1]) |
|
|
|
|
containRight := utils.Ipv6ToUint128(containIpv6s[j][1]) |
|
|
|
|
if (ownerLeft.H > containRight.H) || (ownerLeft.H == containRight.H && ownerLeft.L > containRight.L) { |
|
|
|
|
j++ |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if containIpv6s[j].IsContain(ownerIpv6s[i]) || ownerIpv6s[i].IsContain(containIpv6s[j]) { |
|
|
|
|
return true, fmt.Sprintf("%s<-->%s", ownerIpv6s[i].IpString(), containIpv6s[j].IpString()), errors.New("输入ip与已存在ip配置范围重叠!") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ipv6Start.H > ownerLeft.H) || (ipv6Start.H == ownerLeft.H && ipv6Start.L >= ownerLeft.L) { //判断自己ip段是否重复,重复就返回重复的ip
|
|
|
|
|
if i > 0 { |
|
|
|
|
return false, fmt.Sprintf("%s<-->%s", ownerIpv6s[i-1].IpString(), ownerIpv6s[i].IpString()), errors.New("输入ip范围重叠!") |
|
|
|
|
} |
|
|
|
|
return false, ownerIpv6s[i].IpString(), errors.New("请勿填写0.0.0.0和0:0:0:0:0:0:0:0等无效ip!") |
|
|
|
|
} |
|
|
|
|
ipv6Start = ownerRight |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false, "", nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FilterIpAndSort 筛选出ipv4和ipv6并排序
|
|
|
|
|
func FilterIpAndSort(ips []string) (ipv4s []utils.Ipv4, ipv6s []utils.Ipv6, errIp string, err error) { |
|
|
|
|
for _, ip := range ips { |
|
|
|
|
ownerIp := utils.NewIpRange(ip) |
|
|
|
|
if ownerIp == nil { |
|
|
|
|
return ipv4s, ipv6s, ip, errors.New("ip格式错误!") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//判断ip范围是否满足从小到大的规则
|
|
|
|
|
if err := ownerIp.CheckIpRange(); err != nil { |
|
|
|
|
return ipv4s, ipv6s, ip, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ownerIp.Type() == utils.Ipv4Type { |
|
|
|
|
ipv4s = append(ipv4s, ownerIp.(utils.Ipv4)) |
|
|
|
|
} else { |
|
|
|
|
ipv6s = append(ipv6s, ownerIp.(utils.Ipv6)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//处理排序
|
|
|
|
|
sort.Slice(ipv4s, func(i, j int) bool { |
|
|
|
|
return utils.Ipv4ToUint32(ipv4s[i][0]) < utils.Ipv4ToUint32(ipv4s[j][0]) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
sort.Slice(ipv6s, func(i, j int) bool { |
|
|
|
|
if utils.Ipv6ToUint128(ipv6s[i][0]).H < utils.Ipv6ToUint128(ipv6s[j][0]).H { |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
return utils.Ipv6ToUint128(ipv6s[i][0]).H == utils.Ipv6ToUint128(ipv6s[j][0]).H && utils.Ipv6ToUint128(ipv6s[i][0]).L < utils.Ipv6ToUint128(ipv6s[j][0]).L |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|