v0.2.4
FIXED: * IPv6 split-nets splitter didn't work. It does not. https://github.com/projectdiscovery/mapcidr/issues/628 Noticed. As such, this library/program has *completely removed* ALL use of the mapcidr library as it cannot be expected to be accurate.
This commit is contained in:
parent
4ab83c9069
commit
c05f9c4d47
@ -77,7 +77,7 @@ type SplitHostArgs struct {
|
||||
}
|
||||
|
||||
type SplitSubnetArgs struct {
|
||||
Strict bool `short:"t" long:"strict" description:"If specified, an error will occur if the number of possible equally-sized subnets is not exactly -n/--num-nets."`
|
||||
Strict bool `short:"t" long:"strict" description:"If specified, an error will occur if the number of subnets is not exactly -n/--num-nets."`
|
||||
NumNets uint `short:"n" long:"num-nets" required:"true" description:"Number of networks." validate:"required"`
|
||||
splitArgs
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import "errors"
|
||||
var (
|
||||
ErrBadBoundary error = errors.New("subnet does not align on bit boundary")
|
||||
ErrBadNumHosts error = errors.New("bad number of hosts; cannot split into prefix exactly")
|
||||
ErrBadNumNets error = errors.New("bad number of nets; cannot split into prefix exactly")
|
||||
ErrBadPrefix error = errors.New("prefix is invalid")
|
||||
ErrBadPrefixLen error = errors.New("prefix length exceeds maximum possible for prefix's inet family")
|
||||
ErrBadSplitter error = errors.New("invalid or unknown splitter when containing")
|
||||
|
@ -1,10 +1,9 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
`net`
|
||||
`math`
|
||||
"net/netip"
|
||||
|
||||
`github.com/projectdiscovery/mapcidr`
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
@ -22,10 +21,7 @@ func (s *SubnetSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet,
|
||||
var ok bool
|
||||
var pfxLen int
|
||||
var base netip.Prefix
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var split []*net.IPNet
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
var vlsm *VLSMSplitter
|
||||
|
||||
if s == nil || s.BaseSplitter == nil || s.network == nil || s.NumberSubnets == 0 {
|
||||
return
|
||||
@ -40,65 +36,48 @@ func (s *SubnetSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet,
|
||||
return
|
||||
}
|
||||
|
||||
if split, err = mapcidr.SplitIPNetIntoN(s.network, int(s.NumberSubnets)); err != nil {
|
||||
// Previously, this used (github.com/projectdiscovery/mapcidr).SplitIPNetIntoN.
|
||||
// It no longer does: https://github.com/projectdiscovery/mapcidr/issues/628
|
||||
// I am Noticing.
|
||||
|
||||
// First the number of bits needed is calculated.
|
||||
pfxLen = int(math.Ceil(math.Log2(float64(s.NumberSubnets))))
|
||||
// And this is then added to the original prefix length to get the new prefix size.
|
||||
pfxLen = pfxLen + base.Bits()
|
||||
// I don't know how this would happen, but it'd be bad if it did.
|
||||
if pfxLen < base.Bits() {
|
||||
err = ErrBigPrefix
|
||||
return
|
||||
}
|
||||
// Likewise.
|
||||
if base.Addr().Is6() {
|
||||
ok = pfxLen <= int(maxBitsv6)
|
||||
} else {
|
||||
ok = pfxLen <= int(maxBitsv4)
|
||||
}
|
||||
if !ok {
|
||||
err = ErrBadPrefix
|
||||
return
|
||||
}
|
||||
|
||||
for _, n := range split {
|
||||
if sub, ok = netipx.FromStdIPNet(n); !ok {
|
||||
// We bail early on this error.
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadBoundary,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: subPtr,
|
||||
RequestedPrefixLen: 0,
|
||||
}
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
if sub.String() == base.String() {
|
||||
continue
|
||||
}
|
||||
if pfxLen == 0 {
|
||||
pfxLen = sub.Bits()
|
||||
if nets == nil {
|
||||
nets = make([]*netip.Prefix, 0)
|
||||
}
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
} else {
|
||||
if sub.Bits() != pfxLen {
|
||||
if err == nil {
|
||||
// Return this err but don't return early; wait for the populate.
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrNoNetSpace,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: subPtr,
|
||||
RequestedPrefixLen: uint8(pfxLen),
|
||||
}
|
||||
}
|
||||
ipsb.AddPrefix(sub)
|
||||
} else {
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
}
|
||||
}
|
||||
// We can now VLSM.
|
||||
vlsm = &VLSMSplitter{
|
||||
// Ascenting and Explicit are pointless to set as all defined sizes are the same.
|
||||
Ascending: false,
|
||||
Explicit: false,
|
||||
PrefixLengths: make([]uint8, s.NumberSubnets),
|
||||
BaseSplitter: s.BaseSplitter,
|
||||
}
|
||||
for i := 0; i < int(s.NumberSubnets); i++ {
|
||||
vlsm.PrefixLengths[i] = uint8(pfxLen)
|
||||
}
|
||||
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
if nets, remaining, err = vlsm.Split(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(nets) < int(s.NumberSubnets) {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrNoNetSpace,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
}
|
||||
if s.Strict && remaining != nil && remaining.Prefixes() != nil && len(remaining.Prefixes()) > 0 {
|
||||
err = ErrBadNumNets
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user