FIXED:
* Missing reservation checker
This commit is contained in:
brent saner
2025-04-04 14:29:07 -04:00
parent d37aa3eb6b
commit 32297d1bba
7 changed files with 208 additions and 8 deletions

View File

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