Newer
Older
// NewPrefixFromProtoPrefix creates a Prefix from a proto Prefix
func NewPrefixFromProtoPrefix(pfx api.Prefix) Prefix {
return Prefix{
addr: IPFromProtoIP(*pfx.Address),
pfxlen: uint8(pfx.Pfxlen),
}
}
// ToProto converts prefix to proto prefix
func (pfx Prefix) ToProto() api.Prefix {
return api.Prefix{
Address: pfx.addr.ToProto(),
Pfxlen: uint32(pfx.pfxlen),
}
}
func NewPfx(addr IP, pfxlen uint8) Prefix {
addr: addr,
pfxlen: pfxlen,
}
}
// StrToAddr converts an IP address string to it's uint32 representation
func StrToAddr(x string) (uint32, error) {
parts := strings.Split(x, ".")
if len(parts) != 4 {
return 0, fmt.Errorf("Invalid format")
}
ret := uint32(0)
for i := 0; i < 4; i++ {
y, err := strconv.Atoi(parts[i])
if err != nil {
return 0, fmt.Errorf("Unable to convert %q to int: %v", parts[i], err)
}
if y > 255 {
return 0, fmt.Errorf("%d is too big for a uint8", y)
}
ret += uint32(math.Pow(256, float64(3-i))) * uint32(y)
}
return ret, nil
}
// Addr returns the address of the prefix
return pfx.addr
}
// Pfxlen returns the length of the prefix
func (pfx Prefix) Pfxlen() uint8 {
return pfx.pfxlen
}
// String returns a string representation of pfx
func (pfx Prefix) String() string {
return fmt.Sprintf("%s/%d", pfx.addr, pfx.pfxlen)
func (pfx Prefix) Contains(x Prefix) bool {
return pfx.containsIPv4(x)
}
}
func (pfx Prefix) containsIPv4(x Prefix) bool {
mask := uint32((math.MaxUint32 << (32 - pfx.pfxlen)))
return (pfx.addr.ToUint32() & mask) == (x.addr.ToUint32() & mask)
func (pfx Prefix) containsIPv6(x Prefix) bool {
var maskHigh, maskLow uint64
if pfx.pfxlen <= 64 {
maskHigh = math.MaxUint32 << (64 - pfx.pfxlen)
maskLow = uint64(0)
} else {
maskHigh = math.MaxUint32
maskLow = math.MaxUint32 << (128 - pfx.pfxlen)
}
return pfx.addr.higher&maskHigh&maskHigh == x.addr.higher&maskHigh&maskHigh &&
pfx.addr.lower&maskHigh&maskLow == x.addr.lower&maskHigh&maskLow
}
func (pfx Prefix) Equal(x Prefix) bool {
return pfx == x
func (pfx Prefix) GetSupernet(x Prefix) Prefix {
return pfx.supernetIPv4(x)
}
return pfx.supernetIPv6(x)
}
func (pfx Prefix) supernetIPv4(x Prefix) Prefix {
a := pfx.addr.ToUint32() >> (32 - maxPfxLen)
b := x.addr.ToUint32() >> (32 - maxPfxLen)
for i := 0; a != b; i++ {
a = a >> 1
b = b >> 1
maxPfxLen--
}
addr: IPv4(a << (32 - maxPfxLen)),
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
func (pfx Prefix) supernetIPv6(x Prefix) Prefix {
maxPfxLen := min(pfx.pfxlen, x.pfxlen)
a := pfx.addr.BitAtPosition(1)
b := x.addr.BitAtPosition(1)
pfxLen := uint8(0)
mask := uint64(0)
for a == b && pfxLen < maxPfxLen {
a = pfx.addr.BitAtPosition(pfxLen + 2)
b = x.addr.BitAtPosition(pfxLen + 2)
pfxLen++
if pfxLen == 64 {
mask = 0
}
m := pfxLen % 64
mask = mask + uint64(1)<<(64-m)
}
if pfxLen == 0 {
return NewPfx(IPv6(0, 0), pfxLen)
}
if pfxLen > 64 {
return NewPfx(IPv6(pfx.addr.higher, pfx.addr.lower&mask), pfxLen)
}
return NewPfx(IPv6(pfx.addr.higher&mask, 0), pfxLen)
}