mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-06 18:10:26 +08:00
增加IP动作
This commit is contained in:
85
internal/iplibrary/action_utils.go
Normal file
85
internal/iplibrary/action_utils.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package iplibrary
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Convert IPv4 range into CIDR
|
||||
// 来自:https://gist.github.com/P-A-R-U-S/a090dd90c5104ce85a29c32669dac107
|
||||
func iPv4RangeToCIDRRange(ipStart string, ipEnd string) (cidrs []string, err error) {
|
||||
|
||||
cidr2mask := []uint32{
|
||||
0x00000000, 0x80000000, 0xC0000000,
|
||||
0xE0000000, 0xF0000000, 0xF8000000,
|
||||
0xFC000000, 0xFE000000, 0xFF000000,
|
||||
0xFF800000, 0xFFC00000, 0xFFE00000,
|
||||
0xFFF00000, 0xFFF80000, 0xFFFC0000,
|
||||
0xFFFE0000, 0xFFFF0000, 0xFFFF8000,
|
||||
0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
|
||||
0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00,
|
||||
0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0,
|
||||
0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8,
|
||||
0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
}
|
||||
|
||||
ipStartUint32 := iPv4ToUint32(ipStart)
|
||||
ipEndUint32 := iPv4ToUint32(ipEnd)
|
||||
|
||||
if ipStartUint32 > ipEndUint32 {
|
||||
log.Fatalf("start IP:%s must be less than end IP:%s", ipStart, ipEnd)
|
||||
}
|
||||
|
||||
for ipEndUint32 >= ipStartUint32 {
|
||||
maxSize := 32
|
||||
for maxSize > 0 {
|
||||
|
||||
maskedBase := ipStartUint32 & cidr2mask[maxSize-1]
|
||||
|
||||
if maskedBase != ipStartUint32 {
|
||||
break
|
||||
}
|
||||
maxSize--
|
||||
|
||||
}
|
||||
|
||||
x := math.Log(float64(ipEndUint32-ipStartUint32+1)) / math.Log(2)
|
||||
maxDiff := 32 - int(math.Floor(x))
|
||||
if maxSize < maxDiff {
|
||||
maxSize = maxDiff
|
||||
}
|
||||
|
||||
cidrs = append(cidrs, uInt32ToIPv4(ipStartUint32)+"/"+strconv.Itoa(maxSize))
|
||||
|
||||
ipStartUint32 += uint32(math.Exp2(float64(32 - maxSize)))
|
||||
}
|
||||
|
||||
return cidrs, err
|
||||
}
|
||||
|
||||
//Convert IPv4 to uint32
|
||||
func iPv4ToUint32(iPv4 string) uint32 {
|
||||
|
||||
ipOctets := [4]uint64{}
|
||||
|
||||
for i, v := range strings.SplitN(iPv4, ".", 4) {
|
||||
ipOctets[i], _ = strconv.ParseUint(v, 10, 32)
|
||||
}
|
||||
|
||||
result := (ipOctets[0] << 24) | (ipOctets[1] << 16) | (ipOctets[2] << 8) | ipOctets[3]
|
||||
|
||||
return uint32(result)
|
||||
}
|
||||
|
||||
//Convert uint32 to IP
|
||||
func uInt32ToIPv4(iPuInt32 uint32) (iP string) {
|
||||
iP = fmt.Sprintf("%d.%d.%d.%d",
|
||||
iPuInt32>>24,
|
||||
(iPuInt32&0x00FFFFFF)>>16,
|
||||
(iPuInt32&0x0000FFFF)>>8,
|
||||
iPuInt32&0x000000FF)
|
||||
return iP
|
||||
}
|
||||
Reference in New Issue
Block a user