almost done ackshually
This commit is contained in:
97
netsplit/funcs_vlsmsplitter.go
Normal file
97
netsplit/funcs_vlsmsplitter.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
"net/netip"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Split splits the network defined in a VLSMSplitter alongside its configuration and performs the subnetting.
|
||||
func (v *VLSMSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
var ok bool
|
||||
var pfxLen int
|
||||
var pfxLen8 uint8
|
||||
var base netip.Prefix
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
|
||||
if err = ValidateSizes(v.network, v.PrefixLengths...); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
I thought about using the following:
|
||||
|
||||
* https://pkg.go.dev/net/netip
|
||||
* https://pkg.go.dev/github.com/sacloud/packages-go/cidr
|
||||
* https://pkg.go.dev/github.com/projectdiscovery/mapcidr
|
||||
* https://pkg.go.dev/github.com/EvilSuperstars/go-cidrman
|
||||
|
||||
But, as I expected, netipx ftw again.
|
||||
*/
|
||||
|
||||
if v == nil || v.PrefixLengths == nil || len(v.PrefixLengths) == 0 || v.BaseSplitter == nil || v.network == nil {
|
||||
return
|
||||
}
|
||||
|
||||
sort.SliceStable(
|
||||
v.PrefixLengths,
|
||||
func(i, j int) (isBefore bool) { // We use a reverse sorting by default so we get larger prefixes at the beginning.
|
||||
if v.Ascending {
|
||||
isBefore = v.PrefixLengths[i] > v.PrefixLengths[j]
|
||||
} else {
|
||||
isBefore = v.PrefixLengths[i] < v.PrefixLengths[j]
|
||||
}
|
||||
return
|
||||
},
|
||||
)
|
||||
|
||||
pfxLen, _ = v.network.Mask.Size()
|
||||
pfxLen8 = uint8(pfxLen)
|
||||
|
||||
if base, ok = netipx.FromStdIPNet(v.network); !ok {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
if !base.IsValid() {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
|
||||
ipsb.AddPrefix(base)
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, size := range v.PrefixLengths {
|
||||
if size < pfxLen8 {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBigPrefix,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: &sub,
|
||||
RequestedPrefixLen: size,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if sub, remaining, ok = remaining.RemoveFreePrefix(size); !ok {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrNoNetSpace,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: &sub,
|
||||
RequestedPrefixLen: size,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user