SegmentFrom parser is ready for CIDR and IP range

This commit is contained in:
lionsoul2014 2026-05-16 10:14:20 +08:00
parent 353524325a
commit f939363a19
3 changed files with 54 additions and 12 deletions

View File

@ -34,12 +34,16 @@ func SegmentFrom(seg string, cRegion func(string) *Region) (*Segment, error) {
case 2: case 2:
// CIDR format // CIDR format
rIdx = 1 rIdx = 1
sip, eip, err = CIDR2Range(ps[0])
if err != nil {
return nil, fmt.Errorf("parse cidr: %s", err)
}
case 3: case 3:
// triditional ip range // triditional ip range
rIdx = 2 rIdx = 2
sip, err = ParseIP(ps[0]) sip, err = ParseIP(ps[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("parser start ip `%s`: %s", ps[0], err) return nil, fmt.Errorf("parse start ip `%s`: %s", ps[0], err)
} }
eip, err = ParseIP(ps[1]) eip, err = ParseIP(ps[1])

View File

@ -56,18 +56,19 @@ func CIDR2Range(cidrStr string) ([]byte, []byte, error) {
// Get the start IP (Network Address) // Get the start IP (Network Address)
// Masked() zeros out the host bits, which gives the starting IP of the subnet. // Masked() zeros out the host bits, which gives the starting IP of the subnet.
sip := prefix.Masked().Addr().AsSlice() sip := prefix.Masked().Addr().AsSlice()
eip := make([]byte, len(sip)) ipl := len(sip)
eip := make([]byte, ipl)
copy(eip, sip) copy(eip, sip)
// Calculate the end IP (Broadcast Address) // Calculate the end IP (Broadcast Address)
bits := prefix.Bits() bits := prefix.Bits()
// border byte rest bit filled with 1 // border byte rest bit filled with 1
bByteIdx := bits / 8 byteIdx := bits / 8
eip[bByteIdx] |= bitMaskList[bits-(bByteIdx*8)] eip[byteIdx] |= bitMaskList[bits-(byteIdx*8)]
// fill all the rest bits with 1 // fill all the rest bits with 1
for bi := bByteIdx + 1; bi < len(sip); bi++ { for bi := byteIdx + 1; bi < ipl; bi++ {
eip[bi] |= 0b1111_1111 eip[bi] |= 0b1111_1111
} }

View File

@ -197,6 +197,39 @@ func TestIPMiddle(t *testing.T) {
t.Logf("test done with %d ips", counter) t.Logf("test done with %d ips", counter)
} }
func TestSegmentFromt(t *testing.T) {
var lines = []string{
// ipv4 range
"2.10.222.0|2.10.223.255|France|Brittany|0|Orange S.A.|FR",
"8.35.35.0|8.35.159.255|United States|Colorado|0|ZSCALER, INC.|US",
"223.104.64.128|223.104.64.159|中国|广东省|深圳市|移动|CN",
// ipv4 CIDR
"1.0.4.0/24|2497 6453 7545 2764 38803|IGP",
"2.18.209.0/24|14537 3356 1299 34164 34164|IGP",
"14.32.46.0/24|2497 4766 9696|IGP",
// IPv6 range
"2001:200:17c::|2001:200:180:ffff:ffff:ffff:ffff:ffff|Japan|Tokyo|Tokyo|WIDE Project|JP",
"2001:506:100:226e::8|2001:506:100:226f::7|United States|Michigan|Detroit|Transact Ltd.|US",
"2a13:aac4:1000::|2a13:aac4:ffff:ffff:ffff:ffff:ffff:ffff|中国|广东省|深圳市|MLGT|CN",
// IPv6 CIDR
"2c0f:fc89:8081::/48|32590 9002 3257 8452 36992 36992 36992 36992 36992 36992 36992 36992 36992|EGP",
"2c0f:fe08:20a::/48|2497 6939 36914|IGP",
"2c0f:ffc8::/32|14537 23764 37468 22355|IGP",
}
for _, str := range lines {
seg, err := SegmentFrom(str, NewRegion)
if err != nil {
t.Fatalf("parse segment: %s", err)
}
fmt.Printf("seg={%s, %s, %s}\n", IP2String(seg.StartIP), IP2String(seg.EndIP), seg.Region.Str)
}
}
func TestSplitSegmentV4(t *testing.T) { func TestSplitSegmentV4(t *testing.T) {
// var str = "1.1.0.0|1.3.3.24|中国|广东|深圳|电信" // var str = "1.1.0.0|1.3.3.24|中国|广东|深圳|电信"
// var str = "0.0.0.0|1.255.225.254|0|0|0|内网IP|内网IP" // var str = "0.0.0.0|1.255.225.254|0|0|0|内网IP|内网IP"
@ -309,16 +342,20 @@ func TestCIDR2Range(t *testing.T) {
t.Fatalf("CIDR2Range: %s", err) t.Fatalf("CIDR2Range: %s", err)
} }
sStr := IP2String(sip) tSip, err := ParseIP(item[1])
eStr := IP2String(eip) if err != nil {
if sStr != item[1] { t.Fatalf("parse start ip: %s", err)
t.Fatalf("start ip %s != %s", sStr, item[1]) } else if IPCompare(sip, tSip) != 0 {
t.Fatalf("start ip %s != %s", IP2String(sip), item[1])
} }
if eStr != item[2] { tEip, err := ParseIP(item[2])
t.Fatalf("end ip %s != %s", eStr, item[2]) if err != nil {
t.Fatalf("parse end ip: %s", err)
} else if IPCompare(eip, tEip) != 0 {
t.Fatalf("end ip %s != %s", IP2String(eip), item[2])
} }
fmt.Printf("cidr=%s: {sip=%s, eip=%s}\n", item[0], sStr, eStr) fmt.Printf("cidr=%s: {sip=%s, eip=%s}\n", item[0], item[1], item[2])
} }
} }