v0.2.1
FIXED: * host splitter wasn't working quite correctly; this has been fixed.
This commit is contained in:
parent
fd344f3b8e
commit
3c1bc832c0
2
TODO
2
TODO
@ -3,5 +3,3 @@
|
||||
- when checking/rendering reserved networks, currently the footnotes aren't returned.
|
||||
-- netsplit.IANARegistryFootnote
|
||||
-- encapsulated in the IANARegistry.Footnotes
|
||||
|
||||
- split-hosts returns the entire original subnet as an unallocated subnet if hosts exceed the number of assignable addrs.
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
type Args struct {
|
||||
Version verArgs `command:"version" alias:"v" description:"Show version information." validate:"omitempty"`
|
||||
SplitCIDR SplitCIDRArgs `command:"split-cidr" alias:"se" description:"Split a network into as many equal subnets of prefix size N as possible." validate:"omitempty"`
|
||||
SplitHost SplitHostArgs `command:"split-hosts" alias:"sh" description:"Split a network into N total number of hosts *per subnet* as cleanly/evenly as possible. (VERY easy to run out of memory for IPv6 prefixes; be sure to specify very small network!)" validate:"omitempty"`
|
||||
SplitCIDR SplitCIDRArgs `command:"split-cidr" alias:"sc" description:"Split a network into as many equal subnets of prefix size N as possible." validate:"omitempty"`
|
||||
SplitHost SplitHostArgs `command:"split-hosts" alias:"sh" description:"Split a network into N total number of hosts *per subnet* as cleanly/evenly as possible." validate:"omitempty"`
|
||||
SplitSubnets SplitSubnetArgs `command:"split-nets" alias:"sn" description:"Split a network into N number of subnets as cleanly as possible." validate:"omitempty"`
|
||||
VLSM VLSMArgs `command:"split-vlsm" alias:"sv" alias:"vlsm" description:"Use VLSM (Variable-Length Subnet Masks) to split a network into differently sized subnets." validate:"omitempty"`
|
||||
ExplicitNetwork XNetArgs `command:"net" alias:"xn" alias:"net" description:"Print information about an explicit network address." validate:"omitempty"`
|
||||
@ -36,8 +36,8 @@ type common struct {
|
||||
|
||||
type reservedArgs struct {
|
||||
NoRecursive bool `short:"u" long:"no-recursive" description:"Don't show reservations that are children subnets of the subnet(s). Only if -f/--format=pretty, always false for other formats."`
|
||||
NoRevRecursive bool `short:"U" long:"no-rev-recursive" description:"Don't show reservations that are parents of the subnet(s). Only if -f/--format=pretty, always false for other formats."`
|
||||
NoPrivate bool `short:"e" long:"no-private" description:"Consider private subnets of the subnet(s) to be reserved. If you are subnetting private address space, you probably want to leave this disabled. Only if -f/--format=pretty, always true otherwise."`
|
||||
NoRevRecursive bool `short:"U" long:"no-rev-recursive" description:"Don't show reservations that are parents of the subnet(s) -- you almost definitely don't want to suppress this. Only if -f/--format=pretty, always false for other formats."`
|
||||
NoPrivate bool `short:"e" long:"no-private" description:"Consider private subnets to be reserved. If you are subnetting private address space, you probably want to leave this disabled. Only if -f/--format=pretty, always true otherwise."`
|
||||
}
|
||||
|
||||
type splitArgs struct {
|
||||
@ -53,8 +53,8 @@ type NNetArgs struct {
|
||||
Verbose bool `short:"v" long:"verbose" description:"Be verbose (more ideal for logging)."`
|
||||
NoV6Check bool `short:"6" long:"no-v6" description:"If specified, do not indicate if the subnetting is IPv6 only (true) or not (false; dual-stack/IPv4 supported)."`
|
||||
Sizes struct {
|
||||
SubnetSize uint8 `required:"1" validate:"required,le=128,gtefield=NetworkSize"`
|
||||
NetworkSize uint8 `required:"1" validate:"required,le=128,ltefield=SubnetSize"`
|
||||
SubnetSize uint8 `positional-arg-name:"<subnet prefix>" required:"1" validate:"lte=128,gtefield=NetworkSize"`
|
||||
NetworkSize uint8 `positional-arg-name:"<parent prefix>" required:"1" validate:"lte=128,ltefield=SubnetSize"`
|
||||
} `positional-args:"yes" required:"2" validate:"required"`
|
||||
}
|
||||
|
||||
@ -69,8 +69,10 @@ type SplitCIDRArgs struct {
|
||||
}
|
||||
|
||||
type SplitHostArgs struct {
|
||||
Strict bool `short:"t" long:"strict" description:"If specified, an error will occur if the number of hosts/assignable addresses in a subnet is not exactly -n/--num-hosts."`
|
||||
Hosts uint `short:"n" long:"num-hosts" required:"true" description:"Number of hosts (usable addresses) per subnet." validate:"required"`
|
||||
InclNetAddr bool `short:"N" long:"incl-net" description:"If specified, -n/--num-hosts is interpreted to include the network address in the count."`
|
||||
InclBcastAddr bool `short:"B" long:"incl-bcast" description:"If specified, -n/--num-hosts is interpreted to include the broadcast/reserved broadcast address in the count."`
|
||||
Strict bool `short:"t" long:"strict" description:"If specified, an error will occur if the number of hosts/assignable addresses in a subnet is not exactly -n/--num-hosts."`
|
||||
Hosts uint `short:"n" long:"num-hosts" required:"true" description:"Number of hosts (usable addresses) per subnet." validate:"required"`
|
||||
splitArgs
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,9 @@ func printNets(orig *netip.Prefix, origNet *net.IPNet, nets []*netip.Prefix, rem
|
||||
|
||||
// Remaining
|
||||
if !args.SuppressRemaining {
|
||||
if verb >= 1 {
|
||||
if verb <= 0 {
|
||||
fmt.Println("#")
|
||||
} else {
|
||||
fmt.Println()
|
||||
fmt.Println(sectSep1)
|
||||
fmt.Println("Remaining/Left Over/Unallocated:")
|
||||
@ -660,7 +662,7 @@ func printSplitErr(e *netsplit.SplitErr) {
|
||||
os.Stderr.WriteString("\n!! ERROR !!!\n")
|
||||
|
||||
os.Stderr.WriteString("\t" + e.Wrapped.Error() + "\n")
|
||||
os.Stderr.WriteString("\nnetwork Iteration Details\n(when error was encountered):\n\n")
|
||||
os.Stderr.WriteString("\nNetwork Iteration Details\n(when error was encountered):\n\n")
|
||||
if e.Nets == nil {
|
||||
os.Stderr.WriteString("Nets:\t\t\t(N/A)\n")
|
||||
} else {
|
||||
@ -669,7 +671,7 @@ func printSplitErr(e *netsplit.SplitErr) {
|
||||
fmt.Fprintf(os.Stderr, "\t%s\n", n.String())
|
||||
}
|
||||
}
|
||||
if e.Remaining == nil {
|
||||
if e.Remaining == nil || e.Remaining.Prefixes() == nil || len(e.Remaining.Prefixes()) == 0 {
|
||||
os.Stderr.WriteString("Remaining:\t\t(N/A)\n")
|
||||
} else {
|
||||
os.Stderr.WriteString("Remaining:\n")
|
||||
@ -678,7 +680,7 @@ func printSplitErr(e *netsplit.SplitErr) {
|
||||
}
|
||||
}
|
||||
if e.LastSubnet == nil {
|
||||
os.Stderr.WriteString("Last Subnet:\t\t(N/A)")
|
||||
os.Stderr.WriteString("Last Subnet:\t\t(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Last Subnet:\t\t%s\n", e.LastSubnet.String())
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ func main() {
|
||||
return
|
||||
}
|
||||
case "net":
|
||||
if err = validate.Struct(args.ExplicitNetwork.Network.Network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if origPfx, err = netip.ParsePrefix(args.ExplicitNetwork.Network.Network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
@ -82,6 +85,9 @@ func main() {
|
||||
}
|
||||
return
|
||||
case "num-nets":
|
||||
if err = validate.Struct(args.NumNets); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if numNets, v6Only, err = netsplit.NumNets(
|
||||
args.NumNets.Sizes.SubnetSize,
|
||||
args.NumNets.Sizes.NetworkSize,
|
||||
@ -103,6 +109,9 @@ func main() {
|
||||
}
|
||||
return
|
||||
case "reserved":
|
||||
if err = validate.Struct(args.Check); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if origPfx, err = netip.ParsePrefix(args.Check.Network.Network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
@ -123,6 +132,9 @@ func main() {
|
||||
}
|
||||
return
|
||||
case "table":
|
||||
if err = validate.Struct(args.Table); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
// Account for a weird redundant CLI condition.
|
||||
if args.Table.NoIpv4 && args.Table.NoIpv6 {
|
||||
args.Table.NoIpv6 = false
|
||||
@ -135,6 +147,9 @@ func main() {
|
||||
os.Stdout.Write(buf.Bytes())
|
||||
return
|
||||
case "parse":
|
||||
if err = validate.Struct(args.Parse); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if strings.TrimSpace(args.Parse.InFile) == "-" {
|
||||
buf = new(bytes.Buffer)
|
||||
if _, err = io.Copy(buf, os.Stdin); err != nil {
|
||||
@ -186,9 +201,11 @@ func main() {
|
||||
}
|
||||
cmnArgs = args.SplitHost.common
|
||||
splitter = &netsplit.HostSplitter{
|
||||
NumberHosts: args.SplitHost.Hosts,
|
||||
Strict: args.SplitHost.Strict,
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
InclNetAddr: args.SplitHost.InclNetAddr,
|
||||
InclBcastAddr: args.SplitHost.InclBcastAddr,
|
||||
NumberHosts: args.SplitHost.Hosts,
|
||||
Strict: args.SplitHost.Strict,
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
}
|
||||
noStrict = !args.SplitHost.Strict
|
||||
strictErr = netsplit.ErrBadNumHosts
|
||||
|
@ -193,25 +193,26 @@ func CheckReserved(nets []*netip.Prefix, revRecursive, recursive, excludePrivate
|
||||
reservations = make(map[netip.Prefix]*IANAAddrNetResRecord)
|
||||
}
|
||||
reservations[*n] = res
|
||||
if !revRecursive && !recursive {
|
||||
continue
|
||||
}
|
||||
for p, r := range reserved {
|
||||
// This... *should* be safe? I don't think any reservations overlap.
|
||||
// Anyways, revRecursive works because n.Addr() returns the network address, which should be the canonical boundary.
|
||||
// recursive works for the same reason, just the other end.
|
||||
// Math!
|
||||
if revRecursive && p.Contains(n.Addr()) {
|
||||
if reservations == nil {
|
||||
reservations = make(map[netip.Prefix]*IANAAddrNetResRecord)
|
||||
}
|
||||
reservations[p] = r
|
||||
} else if recursive && n.Contains(p.Addr()) {
|
||||
if reservations == nil {
|
||||
reservations = make(map[netip.Prefix]*IANAAddrNetResRecord)
|
||||
}
|
||||
reservations[p] = r
|
||||
}
|
||||
if !revRecursive && !recursive {
|
||||
continue
|
||||
}
|
||||
for p, r := range reserved {
|
||||
// This... *should* be safe? I don't think any reservations overlap.
|
||||
// Anyways, revRecursive works because n.Addr() returns the network address, which should be the canonical boundary.
|
||||
// recursive works for the same reason, just the other end.
|
||||
// Math!
|
||||
if revRecursive && p.Contains(n.Addr()) {
|
||||
if reservations == nil {
|
||||
reservations = make(map[netip.Prefix]*IANAAddrNetResRecord)
|
||||
}
|
||||
reservations[p] = r
|
||||
}
|
||||
if recursive && n.Bits() < p.Bits() && n.Contains(p.Addr()) {
|
||||
if reservations == nil {
|
||||
reservations = make(map[netip.Prefix]*IANAAddrNetResRecord)
|
||||
}
|
||||
reservations[p] = r
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,7 +224,7 @@ func CheckReserved(nets []*netip.Prefix, revRecursive, recursive, excludePrivate
|
||||
func Contain(origPfx *netip.Prefix, nets []*netip.Prefix, remaining *netipx.IPSet, splitter NetSplitter) (s *StructuredResults, err error) {
|
||||
|
||||
var rem []netip.Prefix
|
||||
var reserved map[netip.Prefix]*IANAAddrNetResRecord
|
||||
// var reserved map[netip.Prefix]*IANAAddrNetResRecord
|
||||
var sr = StructuredResults{
|
||||
Original: origPfx,
|
||||
}
|
||||
@ -276,19 +277,21 @@ func Contain(origPfx *netip.Prefix, nets []*netip.Prefix, remaining *netipx.IPSe
|
||||
}
|
||||
}
|
||||
|
||||
if nets != nil {
|
||||
if reserved, err = CheckReserved(nets, true, true, false); err != nil {
|
||||
return
|
||||
}
|
||||
if reserved != nil && len(reserved) > 0 {
|
||||
s.Reservations = make([]*IANAAddrNetResRecord, len(reserved))
|
||||
idx := 0
|
||||
for _, r := range reserved {
|
||||
s.Reservations[idx] = r
|
||||
idx++
|
||||
/*
|
||||
if nets != nil {
|
||||
if reserved, err = CheckReserved(nets, true, true, false); err != nil {
|
||||
return
|
||||
}
|
||||
if reserved != nil && len(reserved) > 0 {
|
||||
s.Reservations = make([]*IANAAddrNetResRecord, len(reserved))
|
||||
idx := 0
|
||||
for _, r := range reserved {
|
||||
s.Reservations[idx] = r
|
||||
idx++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
s = &sr
|
||||
|
||||
@ -377,27 +380,105 @@ func MaskInvert(mask net.IPMask) (inverted net.IPMask) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
NumAddrsIn returns the number of addresses in a given prefix length
|
||||
and inet family.
|
||||
|
||||
If isIpv6 is false, it is assumed to be IPv4 (...duh).
|
||||
|
||||
inclNet and inclBcast have the same meanings as in NumAddrsNet and NumAddrsPfx.
|
||||
|
||||
Note that for the single-host prefix (/32 for IPv4, /128 for IPv6), numAddrs will *always* be 1.
|
||||
For point-to-point prefix (IPv4 /31, IPv6 /127), numAddrs will *ALWAYS* be 2.
|
||||
*/
|
||||
func NumAddrsIn(prefixLen uint8, isIpv6, inclNet, inclBcast bool) (numAddrs *big.Int, err error) {
|
||||
|
||||
var numBits uint
|
||||
var numRemoved int64
|
||||
var maxBitLen uint8 = maxBitsv4
|
||||
|
||||
if isIpv6 {
|
||||
maxBitLen = maxBitsv6
|
||||
}
|
||||
if prefixLen > maxBitLen {
|
||||
err = ErrBadPrefixLen
|
||||
return
|
||||
}
|
||||
if prefixLen == maxBitLen {
|
||||
numAddrs = big.NewInt(1)
|
||||
return
|
||||
}
|
||||
if (prefixLen + 1) == maxBitLen {
|
||||
numAddrs = big.NewInt(2)
|
||||
return
|
||||
}
|
||||
|
||||
numBits = uint(maxBitLen - prefixLen)
|
||||
|
||||
numAddrs = new(big.Int).Lsh(big.NewInt(1), numBits)
|
||||
|
||||
if !inclNet {
|
||||
numRemoved++
|
||||
}
|
||||
if !inclBcast {
|
||||
numRemoved++
|
||||
}
|
||||
if numRemoved > 0 {
|
||||
_ = numAddrs.Sub(numAddrs, big.NewInt(numRemoved))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
NumAddrsNet returns the number of IP addresses in a net.IPNet.
|
||||
|
||||
# The network address is included in the count if inclNet is true, otherwise it is excluded
|
||||
The network address is included in the count if inclNet is true, otherwise it is excluded.
|
||||
|
||||
Only assignable addresses ("hosts") are considered if hostsOnly is true,
|
||||
otherwise all addresses are counted (depending on inclNet).
|
||||
The broadcast (or reserved broadcast, in the case of IPv6) address will be included in
|
||||
the count if inclBcast is true, otherwise it is excluded.
|
||||
|
||||
numAddrs will be nil if pfx is nil or invalid.
|
||||
*/
|
||||
func NumAddrsNet(pfx *net.IPNet, inclNet, hostsOnly bool) (numAddrs *big.Int) {
|
||||
func NumAddrsNet(pfx *net.IPNet, inclNet, inclBcast bool) (numAddrs *big.Int) {
|
||||
|
||||
var nPfx netip.Prefix
|
||||
var ok bool
|
||||
|
||||
if pfx == nil {
|
||||
return
|
||||
}
|
||||
if nPfx, ok = netipx.FromStdIPNet(pfx); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO
|
||||
numAddrs = NumAddrsPfx(nPfx, inclNet, inclBcast)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NumAddrsPfx is the exact same as NumAddrsNet but for a net/netip.Prefix instead.
|
||||
// TODO
|
||||
func NumAddrsPfx(pfx netip.Prefix, inclNet, inclBcast bool) (numAddrs *big.Int) {
|
||||
|
||||
var numBits uint
|
||||
var numRemoved int64
|
||||
|
||||
numBits = uint(pfx.Addr().BitLen() - pfx.Bits())
|
||||
|
||||
numAddrs = new(big.Int).Lsh(big.NewInt(1), numBits)
|
||||
|
||||
if !inclNet {
|
||||
numRemoved++
|
||||
}
|
||||
if !inclBcast {
|
||||
numRemoved++
|
||||
}
|
||||
if numRemoved > 0 {
|
||||
_ = numAddrs.Sub(numAddrs, big.NewInt(numRemoved))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
NumNets returns the number of times prefix size subnet fits into prefix size network.
|
||||
|
@ -1,12 +1,9 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/projectdiscovery/mapcidr"
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
@ -16,54 +13,84 @@ This strategy attempts to split the network into subnets of equal number of host
|
||||
|
||||
remaining may or may not be nil depending on if the number of hosts can fit cleanly within equal network sizes on boundaries.
|
||||
|
||||
An ErrBadNumHosts will be returned if the number of hosts does not match the *addressable* range in a prefix.
|
||||
An ErrBadNumHosts will be returned if the number of hosts does not match the *exact* number of addresses per spec in a prefix.
|
||||
*/
|
||||
func (h *HostSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
var pfx netip.Prefix
|
||||
var tgt *big.Int
|
||||
var splitCidr int
|
||||
var hosts *big.Int
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var split []*net.IPNet
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
var found bool
|
||||
var cs *CIDRSplitter
|
||||
|
||||
if h == nil || h.NumberHosts == 0 || h.BaseSplitter == nil || h.network == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if split, err = mapcidr.SplitIPNetByNumber(h.network, int(h.NumberHosts)); err != nil {
|
||||
pfx, _ = netipx.FromStdIPNet(h.network)
|
||||
tgt = new(big.Int)
|
||||
tgt.SetUint64(uint64(h.NumberHosts))
|
||||
|
||||
if NumAddrsPfx(pfx, h.InclNetAddr, h.InclBcastAddr).Cmp(tgt) < 0 {
|
||||
// The number of hosts per-subnet exceeds the number of addresses in the specified network.
|
||||
err = ErrNoNetSpace
|
||||
return
|
||||
}
|
||||
/*
|
||||
Iterate up through prefix lengths for the inet family's maximum length, getting larger and larger,
|
||||
until we reach the first prefix that can contain tgt.
|
||||
If we reach h.network.Bits(), we are forced to use that.
|
||||
(Any case otherwise should be handled by the above checks.)
|
||||
*/
|
||||
for splitCidr = pfx.Addr().BitLen(); splitCidr >= pfx.Bits(); splitCidr-- {
|
||||
if hosts, err = NumAddrsIn(uint8(splitCidr), pfx.Addr().Is6(), h.InclNetAddr, h.InclBcastAddr); err != nil {
|
||||
return
|
||||
}
|
||||
if hosts.Cmp(tgt) >= 0 {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// Pragmatically, we should never be able to get to this code.
|
||||
err = ErrNoNetSpace
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(split)
|
||||
|
||||
tgt = big.NewInt(0)
|
||||
tgt.SetUint64(uint64(h.NumberHosts))
|
||||
|
||||
nets = make([]*netip.Prefix, len(split))
|
||||
for idx, n := range split {
|
||||
sub, _ = netipx.FromStdIPNet(n)
|
||||
hosts = mapcidr.CountIPsInCIDR(false, false, n)
|
||||
if hosts == nil || tgt.Cmp(hosts) != 0 {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadNumHosts,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: &sub,
|
||||
RequestedPrefixLen: uint8(sub.Bits()),
|
||||
}
|
||||
ipsb.AddPrefix(sub)
|
||||
} else {
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
// Now that we have an appropriate prefix length for splitting, we can offload a huge portion of that to a CIDRSplitter.
|
||||
cs = &CIDRSplitter{
|
||||
PrefixLength: uint8(splitCidr),
|
||||
BaseSplitter: h.BaseSplitter,
|
||||
}
|
||||
if nets, remaining, err = cs.Split(); err != nil {
|
||||
return
|
||||
}
|
||||
// If strict mode is enabled, we then need to match the number of hosts exactly in the subnet.
|
||||
if !h.Strict {
|
||||
return
|
||||
}
|
||||
// First off, if remaining is not nil/empty, that immediately fails strict.
|
||||
if remaining != nil && remaining.Prefixes() != nil && len(remaining.Prefixes()) != 0 {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadNumHosts,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: nil,
|
||||
RequestedPrefixLen: uint8(splitCidr),
|
||||
}
|
||||
|
||||
nets[idx] = new(netip.Prefix)
|
||||
*nets[idx] = sub
|
||||
return
|
||||
}
|
||||
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
// Then we check the cidr we split on, and check its number of hosts.
|
||||
if hosts.Cmp(tgt) != 0 {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadNumHosts,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: nil,
|
||||
RequestedPrefixLen: uint8(splitCidr),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,10 @@ It attempts to evenly distribute addresses amoungs subnets.
|
||||
type HostSplitter struct {
|
||||
// NumberHosts is the number of hosts to be placed in each subnet to split out.
|
||||
NumberHosts uint `json:"hosts" xml:"hosts,attr" yaml:"Number of Hosts Per Subnet"`
|
||||
// InclNetAddr, if true, specifies that NumberHosts includes the network address.
|
||||
InclNetAddr bool `json:"net_addr" xml:"netAddr,attr,omitempty" yaml:"Network Address Included,omitempty"`
|
||||
// InclBcastAddr, if true, specifies that NumberHosts includes the broadcast address.
|
||||
InclBcastAddr bool `json:"bcast_addr" xml:"bcast,attr,omitempty" yaml:"Broadcast Address Included,omitempty"`
|
||||
// Strict, if true, will return an error from Split if the network cannot split into subnets of NumberHosts-addressable networks exactly.
|
||||
Strict bool `json:"strict" xml:"strict,attr,omitempty" yaml:"Strictly Equal Hosts Per Subnet"`
|
||||
*BaseSplitter `json:"net" xml:"net,omitempty" yaml:"network,omitempty"`
|
||||
@ -78,14 +82,14 @@ type VLSMSplitter struct {
|
||||
(ascending order) instead of larger networks/smaller prefixes (descending order).
|
||||
You almost assuredly do not want to do this.
|
||||
*/
|
||||
Ascending bool
|
||||
Ascending bool `json:"asc,omitempty" xml:"asc,attr,omitempty" yaml:"Ascending Order,omitempty"`
|
||||
/*
|
||||
Explicit, if true, will ignore Ascending completely and split in the explicit order of PrefixLengths.
|
||||
|
||||
This has the potential to be *extremely* wasteful of addressing space as the resulting blocks are
|
||||
VERY unoptimized.
|
||||
*/
|
||||
Explicit bool
|
||||
Explicit bool `json:"explicit,omitempty" xml:"explicit,attr,omitempty" yaml:"Explicit Ordering,omitempty"`
|
||||
// PrefixLengths contains the prefix lengths of each subnet to split out from the network.
|
||||
PrefixLengths []uint8 `json:"prefixes" xml:"prefixes>prefix" yaml:"Prefix Lengths"`
|
||||
*BaseSplitter `json:"net" xml:"net,omitempty" yaml:"network,omitempty"`
|
||||
|
Loading…
x
Reference in New Issue
Block a user