Files
EdgeCommon/pkg/iputils/cidr.go

79 lines
1.5 KiB
Go

// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iputils
import (
"net"
)
type CIDR struct {
rawIPNet *net.IPNet
}
func ParseCIDR(s string) (*CIDR, error) {
_, ipNet, err := net.ParseCIDR(s)
if err != nil {
return nil, err
}
return &CIDR{
rawIPNet: ipNet,
}, nil
}
func (this *CIDR) IsIPv4() bool {
return this.rawIPNet.IP.To4() != nil
}
func (this *CIDR) IsIPv6() bool {
return this.rawIPNet.IP.To4() == nil
}
func (this *CIDR) From() net.IP {
return this.rawIPNet.IP
}
func (this *CIDR) To() net.IP {
var start = this.rawIPNet.IP.To4()
if start != nil {
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:4], []byte{0xff, 0xff, 0xff, 0xff}))
}
start = this.rawIPNet.IP.To16()
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:16], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
}
func (this *CIDR) Contains(ip net.IP) bool {
return this.rawIPNet.Contains(ip)
}
func (this *CIDR) String() string {
return this.rawIPNet.String()
}
func bitsAnd(x []byte, y []byte) []byte {
var l = len(x)
var z = make([]byte, l)
for i := 0; i < l; i++ {
z[i] = x[i] & y[i]
}
return z
}
func bitsOr(x []byte, y []byte) []byte {
var l = len(x)
var z = make([]byte, l)
for i := 0; i < l; i++ {
z[i] = x[i] | y[i]
}
return z
}
func bitsXor(x []byte, y []byte) []byte {
var l = len(x)
var z = make([]byte, l)
for i := 0; i < l; i++ {
z[i] = x[i] ^ y[i]
}
return z
}