2024-01-09 16:37:34 +08:00
|
|
|
package cidr
|
|
|
|
|
|
|
|
import (
|
2024-01-13 18:15:30 +08:00
|
|
|
"fmt"
|
2024-01-11 09:33:59 +08:00
|
|
|
"net/netip"
|
2024-01-13 18:15:30 +08:00
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
"go4.org/netipx"
|
2024-01-09 16:37:34 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type IpCidrSet struct {
|
2024-01-13 18:15:30 +08:00
|
|
|
// must same with netipx.IPSet
|
|
|
|
rr []netipx.IPRange
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewIpCidrSet() *IpCidrSet {
|
|
|
|
return &IpCidrSet{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (set *IpCidrSet) AddIpCidrForString(ipCidr string) error {
|
2024-01-11 09:33:59 +08:00
|
|
|
prefix, err := netip.ParsePrefix(ipCidr)
|
2024-01-09 16:37:34 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-01-13 18:15:30 +08:00
|
|
|
return set.AddIpCidr(prefix)
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
2024-01-11 09:33:59 +08:00
|
|
|
func (set *IpCidrSet) AddIpCidr(ipCidr netip.Prefix) (err error) {
|
2024-01-13 18:15:30 +08:00
|
|
|
if r := netipx.RangeOfPrefix(ipCidr); r.IsValid() {
|
|
|
|
set.rr = append(set.rr, r)
|
|
|
|
} else {
|
|
|
|
err = fmt.Errorf("not valid ipcidr range: %s", ipCidr)
|
|
|
|
}
|
2024-01-11 09:33:59 +08:00
|
|
|
return
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (set *IpCidrSet) IsContainForString(ipString string) bool {
|
2024-01-11 09:33:59 +08:00
|
|
|
ip, err := netip.ParseAddr(ipString)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
2024-01-11 09:33:59 +08:00
|
|
|
return set.IsContain(ip)
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
2024-01-11 09:33:59 +08:00
|
|
|
func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
|
2024-01-13 18:15:30 +08:00
|
|
|
return set.toIPSet().Contains(ip.WithZone(""))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (set *IpCidrSet) Merge() error {
|
|
|
|
var b netipx.IPSetBuilder
|
|
|
|
b.AddSet(set.toIPSet())
|
|
|
|
i, err := b.IPSet()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
2024-01-13 18:15:30 +08:00
|
|
|
set.fromIPSet(i)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (set *IpCidrSet) toIPSet() *netipx.IPSet {
|
|
|
|
return (*netipx.IPSet)(unsafe.Pointer(set))
|
2024-01-09 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
2024-01-13 18:15:30 +08:00
|
|
|
func (set *IpCidrSet) fromIPSet(i *netipx.IPSet) {
|
|
|
|
*set = *(*IpCidrSet)(unsafe.Pointer(i))
|
|
|
|
}
|