FIXED:
* host splitter wasn't working quite correctly; this has been fixed.
This commit is contained in:
brent saner
2025-04-06 18:26:18 -04:00
parent fd344f3b8e
commit 3c1bc832c0
7 changed files with 221 additions and 90 deletions

View File

@@ -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
}

View File

@@ -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())
}

View File

@@ -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