v0.1.2
FIXED: * Missing reservation checker
This commit is contained in:
@@ -5,5 +5,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrBadFmt error = errors.New("unknown output format")
|
||||
errBadNet error = errors.New("bad inet/addr family/version")
|
||||
)
|
||||
|
||||
@@ -471,7 +471,180 @@ func printNets(orig *netip.Prefix, origNet *net.IPNet, nets []*netip.Prefix, rem
|
||||
return
|
||||
}
|
||||
|
||||
func printReserved(nets []*netip.Prefix, remaining *netipx.IPSet, args *common) (err error) {
|
||||
func printReserved(records map[netip.Prefix]*netsplit.IANAAddrNetResRecord, origNet netip.Prefix, plain bool, fmtType string) (err error) {
|
||||
|
||||
var b []byte
|
||||
var idx int
|
||||
var pfx netip.Prefix
|
||||
var rec *netsplit.IANAAddrNetResRecord
|
||||
var sortedKeys []netip.Prefix
|
||||
var sb = new(strings.Builder)
|
||||
|
||||
switch fmtType {
|
||||
case "json":
|
||||
if b, err = json.MarshalIndent(records, "", " "); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
return
|
||||
case "xml":
|
||||
if b, err = xml.MarshalIndent(records, "", " "); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
return
|
||||
case "yml", "yaml":
|
||||
if b, err = yaml.Marshal(records); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
return
|
||||
}
|
||||
|
||||
if fmtType != "pretty" {
|
||||
err = ErrBadFmt
|
||||
return
|
||||
}
|
||||
|
||||
if records == nil || len(records) == 0 {
|
||||
fmt.Println("No IANA/IETF/RFC-reserved subnet(s) found.")
|
||||
return
|
||||
}
|
||||
|
||||
sortedKeys = make([]netip.Prefix, len(records))
|
||||
idx = 0
|
||||
for pfx, _ = range records {
|
||||
sortedKeys[idx] = pfx
|
||||
idx++
|
||||
}
|
||||
sort.SliceStable(
|
||||
sortedKeys,
|
||||
func(i, j int) (isBefore bool) {
|
||||
isBefore = (netipx.ComparePrefix(sortedKeys[i], sortedKeys[j])) <= 0
|
||||
return
|
||||
},
|
||||
)
|
||||
|
||||
fmt.Fprintf(sb, "= %s =\n", origNet.String())
|
||||
for _, pfx = range sortedKeys {
|
||||
rec = records[pfx]
|
||||
fmt.Fprint(sb, sectFmts[plain][0]+"\n")
|
||||
// Name
|
||||
fmt.Fprintf(sb, "Reservation Name:\t%s\n", rec.Name)
|
||||
fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Networks
|
||||
fmt.Fprint(sb, "\tCanonical Reserved Networks:")
|
||||
if rec.Networks != nil {
|
||||
fmt.Fprint(sb, "\n")
|
||||
for _, recPfx := range rec.Networks.Prefixes {
|
||||
fmt.Fprint(sb, "\t\t"+sectFmts[plain][2]+"\n")
|
||||
fmt.Fprintf(sb, "\t\t%s\n", recPfx.String())
|
||||
// TODO: Print footnotes/refs!
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "\t(N/A)\n")
|
||||
}
|
||||
fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Reference/Specification
|
||||
fmt.Fprint(sb, "\tSpecification:")
|
||||
if rec.Spec != nil {
|
||||
fmt.Fprint(sb, "\n")
|
||||
for _, line := range strings.Split(rec.Spec.Text, "\n") {
|
||||
fmt.Fprint(sb, "\t\t"+line+"\n")
|
||||
}
|
||||
if rec.Spec.References != nil {
|
||||
fmt.Fprintf(sb, "\t\t%s\n", sectFmts[plain][2])
|
||||
for rIdx, recref := range rec.Spec.References {
|
||||
if recref != nil {
|
||||
fmt.Fprintf(sb, "\t\t[%d] (%s) %s\n", rIdx, recref.Type, recref.Reference)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "\t(None)\n")
|
||||
}
|
||||
fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Allocated (always present)
|
||||
fmt.Fprintf(sb, "\tAllocated:\t%s\n", time.Time(rec.Allocation).String())
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Updated
|
||||
fmt.Fprint(sb, "\tUpdated:\t")
|
||||
if rec.Updated != nil {
|
||||
fmt.Fprintf(sb, "%s\n", time.Time(*rec.Updated).String())
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Termination
|
||||
fmt.Fprint(sb, "\tTerminated:\t")
|
||||
if rec.Termination != nil {
|
||||
fmt.Fprintf(sb, "%s\n", time.Time(*rec.Termination).String())
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Source
|
||||
fmt.Fprint(sb, "\tValid Source:\t\t\t")
|
||||
if rec.Source != nil {
|
||||
if rec.Source.Applicable != nil && !bool(*rec.Source.Applicable) {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(sb, "%v\n", bool(*rec.Source.Evaluated))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Destination
|
||||
fmt.Fprint(sb, "\tValid Destination:\t\t")
|
||||
if rec.Dest != nil {
|
||||
if rec.Dest.Applicable != nil && !bool(*rec.Dest.Applicable) {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(sb, "%v\n", bool(*rec.Dest.Evaluated))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Forwardable
|
||||
fmt.Fprint(sb, "\tForwardable:\t\t\t")
|
||||
if rec.Forwardable != nil {
|
||||
if rec.Forwardable.Applicable != nil && !bool(*rec.Forwardable.Applicable) {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(sb, "%v\n", bool(*rec.Forwardable.Evaluated))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Globally reachable
|
||||
fmt.Fprint(sb, "\tGlobally Routable/Reachable:\t")
|
||||
if rec.GlobalReach != nil {
|
||||
if rec.GlobalReach.Applicable != nil && !bool(*rec.GlobalReach.Applicable) {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(sb, "%v\n", bool(*rec.GlobalReach.Evaluated))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
// fmt.Fprint(sb, "\t"+sectFmts[plain][1]+"\n")
|
||||
// Reserved by Protocol
|
||||
fmt.Fprint(sb, "\tReserved by Protocol:\t\t")
|
||||
if rec.ProtoReserved != nil {
|
||||
if rec.ProtoReserved.Applicable != nil && !bool(*rec.ProtoReserved.Applicable) {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
} else {
|
||||
fmt.Fprintf(sb, "%v\n", bool(*rec.ProtoReserved.Evaluated))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(sb, "(N/A)\n")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Print(sb.String())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ func main() {
|
||||
var res *netsplit.StructuredResults
|
||||
var noStrict bool
|
||||
var strictErr error
|
||||
var reservations map[netip.Prefix]*netsplit.IANAAddrNetResRecord
|
||||
var splitErr *netsplit.SplitErr = new(netsplit.SplitErr)
|
||||
var parser *flags.Parser = flags.NewParser(args, flags.Default)
|
||||
|
||||
@@ -79,7 +80,25 @@ func main() {
|
||||
}
|
||||
return
|
||||
case "reserved":
|
||||
// TODO
|
||||
if origPfx, err = netip.ParsePrefix(args.Check.Network.Network); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
nets = make([]*netip.Prefix, 1)
|
||||
nets[0] = new(netip.Prefix)
|
||||
*nets[0] = origPfx
|
||||
if err = netsplit.SetCachePath(args.Check.CacheDir); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if err = netsplit.EnableCache(args.Check.DoResCache); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if reservations, err = netsplit.CheckReserved(nets, !args.Check.NoRevRecursive, !args.Check.NoRecursive, !args.Check.NoPrivate); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if err = printReserved(reservations, origPfx, args.Check.Plain, args.Check.Fmt); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
return
|
||||
case "table":
|
||||
// Account for a weird redundant CLI condition.
|
||||
if args.Table.NoIpv4 && args.Table.NoIpv6 {
|
||||
|
||||
Reference in New Issue
Block a user