almost done ackshually
This commit is contained in:
161
cmd/subnetter/main.go
Normal file
161
cmd/subnetter/main.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"go4.org/netipx"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strings"
|
||||
"subnetter/netsplit"
|
||||
|
||||
"github.com/jessevdk/go-flags"
|
||||
"r00t2.io/sysutils/paths"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var err error
|
||||
var b []byte
|
||||
var pfx *net.IPNet
|
||||
var resPfx *netip.Prefix
|
||||
var origPfx netip.Prefix
|
||||
var splitter netsplit.NetSplitter
|
||||
var cmnArgs common
|
||||
var nets []*netip.Prefix
|
||||
var remaining *netipx.IPSet
|
||||
var buf *bytes.Buffer
|
||||
var res *netsplit.StructuredResults
|
||||
var splitErr *netsplit.SplitErr = new(netsplit.SplitErr)
|
||||
var parser *flags.Parser = flags.NewParser(args, flags.Default)
|
||||
|
||||
if _, err = parser.Parse(); err != nil {
|
||||
switch flagsErr := err.(type) {
|
||||
case *flags.Error:
|
||||
switch flagsErr.Type {
|
||||
case flags.ErrHelp, flags.ErrCommandRequired, flags.ErrRequired: // These print their relevant messages by themselves.
|
||||
return
|
||||
default:
|
||||
log.Panicln(err)
|
||||
}
|
||||
default:
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
switch parser.Active.Name {
|
||||
case "table":
|
||||
// TODO: print table and exit
|
||||
return
|
||||
case "parse":
|
||||
// TODO: parse file/bytes, unmarshal, and render with new options then exit
|
||||
if strings.TrimSpace(args.Parse.InFile) == "-" {
|
||||
buf = new(bytes.Buffer)
|
||||
if _, err = io.Copy(buf, os.Stdin); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
b = buf.Bytes()
|
||||
} else {
|
||||
if err = paths.RealPath(&args.Parse.InFile); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if b, err = os.ReadFile(args.Parse.InFile); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
if res, err = netsplit.Parse(b); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if resPfx, nets, remaining, splitter, err = res.Uncontain(); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if resPfx != nil {
|
||||
origPfx = *resPfx
|
||||
}
|
||||
pfx = netipx.PrefixIPNet(origPfx.Masked())
|
||||
cmnArgs = common{
|
||||
outputOpts: args.Parse.outputOpts,
|
||||
AllowReserved: args.Parse.AllowReserved,
|
||||
AllowHostNet: args.Parse.AllowHostNet,
|
||||
}
|
||||
if err = printNets(&origPfx, pfx, nets, remaining, &cmnArgs, res.GetSplitter()); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
return
|
||||
default:
|
||||
// Actually subnet (and print results).
|
||||
/*
|
||||
A netsplit.NetSplitter is needed, along with:
|
||||
* prefix
|
||||
* verbosity
|
||||
* disable showing remaining
|
||||
* formatter
|
||||
These are all handily-dandily enclosed in a `common` struct type.
|
||||
*/
|
||||
switch parser.Active.Name {
|
||||
case "split-hosts":
|
||||
if err = validate.Struct(args.SplitHost); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
cmnArgs = args.SplitHost.common
|
||||
splitter = &netsplit.HostSplitter{
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
NumberHosts: args.SplitHost.Hosts,
|
||||
}
|
||||
case "split-nets":
|
||||
if err = validate.Struct(args.SplitSubnets); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
cmnArgs = args.SplitSubnets.common
|
||||
splitter = &netsplit.SubnetSplitter{
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
NumberSubnets: args.SplitSubnets.NumNets,
|
||||
}
|
||||
case "split-cidr":
|
||||
if err = validate.Struct(args.SplitCIDR); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
cmnArgs = args.SplitCIDR.common
|
||||
splitter = &netsplit.CIDRSplitter{
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
PrefixLength: args.SplitCIDR.Prefix,
|
||||
}
|
||||
case "vlsm":
|
||||
if err = validate.Struct(args.VLSM); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
cmnArgs = args.VLSM.common
|
||||
splitter = &netsplit.VLSMSplitter{
|
||||
BaseSplitter: new(netsplit.BaseSplitter),
|
||||
Ascending: args.VLSM.Asc,
|
||||
PrefixLengths: args.VLSM.Sizes,
|
||||
}
|
||||
}
|
||||
if origPfx, err = netip.ParsePrefix(cmnArgs.Network.Network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
// This can be a direct conversion. We have to make sure we mask off the host bits to avoid errors, though.
|
||||
/*
|
||||
if _, pfx, err = net.ParseCIDR(cmnArgs.network.network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
*/
|
||||
pfx = netipx.PrefixIPNet(origPfx.Masked())
|
||||
splitter.SetParent(*pfx)
|
||||
if nets, remaining, err = splitter.Split(); err != nil {
|
||||
if errors.As(err, &splitErr) {
|
||||
printSplitErr(splitErr)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
if err = printNets(&origPfx, pfx, nets, remaining, &cmnArgs, splitter); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user