frontend: use ASN as bgpmap node identifier (instead of resolved whois result)
This commit is contained in:
parent
7efa3237a9
commit
5625058e71
82
frontend/asn_cache.go
Normal file
82
frontend/asn_cache.go
Normal file
@ -0,0 +1,82 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ASNCache map[string]string
|
||||
|
||||
func (cache ASNCache) _lookup(asn string) string {
|
||||
|
||||
if setting.dnsInterface != "" {
|
||||
// get ASN representation using DNS
|
||||
records, err := net.LookupTXT(fmt.Sprintf("AS%s.%s", asn, setting.dnsInterface))
|
||||
if err == nil {
|
||||
result := strings.Join(records, " ")
|
||||
if resultSplit := strings.Split(result, " | "); len(resultSplit) > 1 {
|
||||
result = strings.Join(resultSplit[1:], "\n")
|
||||
}
|
||||
return fmt.Sprintf("AS%s\n%s", asn, result)
|
||||
}
|
||||
} else if setting.whoisServer != "" {
|
||||
// get ASN representation using WHOIS
|
||||
if setting.bgpmapInfo == "" {
|
||||
setting.bgpmapInfo = "asn,as-name,ASName,descr"
|
||||
}
|
||||
records := whois(fmt.Sprintf("AS%s", asn))
|
||||
if records != "" {
|
||||
recordsSplit := strings.Split(records, "\n")
|
||||
var result []string
|
||||
for _, title := range strings.Split(setting.bgpmapInfo, ",") {
|
||||
if title == "asn" {
|
||||
result = append(result, "AS"+asn)
|
||||
}
|
||||
}
|
||||
for _, title := range strings.Split(setting.bgpmapInfo, ",") {
|
||||
allow_multiline := false
|
||||
if title[0] == ':' && len(title) >= 2 {
|
||||
title = title[1:]
|
||||
allow_multiline = true
|
||||
}
|
||||
for _, line := range recordsSplit {
|
||||
if len(line) == 0 || line[0] == '%' || !strings.Contains(line, ":") {
|
||||
continue
|
||||
}
|
||||
linearr := strings.SplitN(line, ":", 2)
|
||||
line_title := linearr[0]
|
||||
content := strings.TrimSpace(linearr[1])
|
||||
if line_title != title {
|
||||
continue
|
||||
}
|
||||
result = append(result, content)
|
||||
if !allow_multiline {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if len(result) > 0 {
|
||||
return strings.Join(result, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (cache ASNCache) Lookup(asn string) string {
|
||||
cachedValue, cacheOk := cache[asn]
|
||||
if cacheOk {
|
||||
return cachedValue
|
||||
}
|
||||
|
||||
result := cache._lookup(asn)
|
||||
if len(result) == 0 {
|
||||
result = fmt.Sprintf("AS%s", asn)
|
||||
}
|
||||
|
||||
cache[asn] = result
|
||||
return result
|
||||
}
|
40
frontend/asn_cache_test.go
Normal file
40
frontend/asn_cache_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetASNRepresentationDNS(t *testing.T) {
|
||||
checkNetwork(t)
|
||||
|
||||
setting.dnsInterface = "asn.cymru.com"
|
||||
setting.whoisServer = ""
|
||||
cache := make(ASNCache)
|
||||
result := cache.Lookup("6939")
|
||||
if !strings.Contains(result, "HURRICANE") {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetASNRepresentationWhois(t *testing.T) {
|
||||
checkNetwork(t)
|
||||
|
||||
setting.dnsInterface = ""
|
||||
setting.whoisServer = "whois.arin.net"
|
||||
cache := make(ASNCache)
|
||||
result := cache.Lookup("6939")
|
||||
if !strings.Contains(result, "HURRICANE") {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetASNRepresentationFallback(t *testing.T) {
|
||||
setting.dnsInterface = ""
|
||||
setting.whoisServer = ""
|
||||
cache := make(ASNCache)
|
||||
result := cache.Lookup("6939")
|
||||
if result != "AS6939" {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
@ -20,89 +17,7 @@ var routeSplitRe = regexp.MustCompile("(unicast|blackhole|unreachable|prohibited
|
||||
var routeViaRe = regexp.MustCompile(`(?m)^\t(via .*?)$`)
|
||||
var routeASPathRe = regexp.MustCompile(`(?m)^\tBGP\.as_path: (.*?)$`)
|
||||
|
||||
func graphvizEscape(s string) string {
|
||||
result, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
} else {
|
||||
return string(result)
|
||||
}
|
||||
}
|
||||
|
||||
type ASNCache map[string]string
|
||||
|
||||
func (cache ASNCache) lookup(asn string) string {
|
||||
var representation string
|
||||
|
||||
cachedValue, cacheOk := cache[asn]
|
||||
if cacheOk {
|
||||
return cachedValue
|
||||
}
|
||||
|
||||
if setting.dnsInterface != "" {
|
||||
// get ASN representation using DNS
|
||||
records, err := net.LookupTXT(fmt.Sprintf("AS%s.%s", asn, setting.dnsInterface))
|
||||
if err == nil {
|
||||
result := strings.Join(records, " ")
|
||||
if resultSplit := strings.Split(result, " | "); len(resultSplit) > 1 {
|
||||
result = strings.Join(resultSplit[1:], "\n")
|
||||
}
|
||||
representation = fmt.Sprintf("AS%s\n%s", asn, result)
|
||||
}
|
||||
} else if setting.whoisServer != "" {
|
||||
// get ASN representation using WHOIS
|
||||
if setting.bgpmapInfo == "" {
|
||||
setting.bgpmapInfo = "asn,as-name,ASName,descr"
|
||||
}
|
||||
records := whois(fmt.Sprintf("AS%s", asn))
|
||||
if records != "" {
|
||||
recordsSplit := strings.Split(records, "\n")
|
||||
var result []string
|
||||
for _, title := range strings.Split(setting.bgpmapInfo, ",") {
|
||||
if title == "asn" {
|
||||
result = append(result, "AS"+asn)
|
||||
}
|
||||
}
|
||||
for _, title := range strings.Split(setting.bgpmapInfo, ",") {
|
||||
allow_multiline := false
|
||||
if title[0] == ':' && len(title) >= 2 {
|
||||
title = title[1:]
|
||||
allow_multiline = true
|
||||
}
|
||||
for _, line := range recordsSplit {
|
||||
if len(line) == 0 || line[0] == '%' || !strings.Contains(line, ":") {
|
||||
continue
|
||||
}
|
||||
linearr := strings.SplitN(line, ":", 2)
|
||||
line_title := linearr[0]
|
||||
content := strings.TrimSpace(linearr[1])
|
||||
if line_title != title {
|
||||
continue
|
||||
}
|
||||
result = append(result, content)
|
||||
if !allow_multiline {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if len(result) > 0 {
|
||||
representation = strings.Join(result, "\n")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
representation = fmt.Sprintf("AS%s", asn)
|
||||
}
|
||||
|
||||
cache[asn] = representation
|
||||
return representation
|
||||
}
|
||||
|
||||
func birdRouteToGraphviz(servers []string, responses []string, targetName string) string {
|
||||
asnCache := make(ASNCache)
|
||||
graph := makeRouteGraph()
|
||||
|
||||
makeEdgeAttrs := func(preferred bool) RouteAttrs {
|
||||
func makeEdgeAttrs(preferred bool) RouteAttrs {
|
||||
result := RouteAttrs{
|
||||
"fontsize": "12.0",
|
||||
}
|
||||
@ -110,24 +25,27 @@ func birdRouteToGraphviz(servers []string, responses []string, targetName string
|
||||
result["color"] = "red"
|
||||
}
|
||||
return result
|
||||
}
|
||||
makePointAttrs := func(preferred bool) RouteAttrs {
|
||||
}
|
||||
|
||||
func makePointAttrs(preferred bool) RouteAttrs {
|
||||
result := RouteAttrs{}
|
||||
if preferred {
|
||||
result["color"] = "red"
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
target := "Target: " + targetName
|
||||
graph.AddPoint(target, RouteAttrs{"color": "red", "shape": "diamond"})
|
||||
func birdRouteToGraph(servers []string, responses []string, target string) RouteGraph {
|
||||
graph := makeRouteGraph()
|
||||
|
||||
graph.AddPoint(target, false, RouteAttrs{"color": "red", "shape": "diamond"})
|
||||
|
||||
for serverID, server := range servers {
|
||||
response := responses[serverID]
|
||||
if len(response) == 0 {
|
||||
continue
|
||||
}
|
||||
graph.AddPoint(server, RouteAttrs{"color": "blue", "shape": "box"})
|
||||
graph.AddPoint(server, false, RouteAttrs{"color": "blue", "shape": "box"})
|
||||
routes := routeSplitRe.Split(response, -1)
|
||||
|
||||
for routeIndex, route := range routes {
|
||||
@ -175,97 +93,25 @@ func birdRouteToGraphviz(servers []string, responses []string, targetName string
|
||||
if i == 0 {
|
||||
src = server
|
||||
} else {
|
||||
src = asnCache.lookup(paths[i-1])
|
||||
src = paths[i-1]
|
||||
}
|
||||
dst := asnCache.lookup(paths[i])
|
||||
dst := paths[i]
|
||||
|
||||
graph.AddEdge(src, dst, strings.TrimSpace(protocolName+"\n"+via), makeEdgeAttrs(routePreferred))
|
||||
// Only set color for next step, origin color is set to blue above
|
||||
graph.AddPoint(dst, makePointAttrs(routePreferred))
|
||||
graph.AddPoint(dst, true, makePointAttrs(routePreferred))
|
||||
}
|
||||
|
||||
// Last AS to destination
|
||||
src := asnCache.lookup(paths[len(paths)-1])
|
||||
src := paths[len(paths)-1]
|
||||
graph.AddEdge(src, target, "", makeEdgeAttrs(routePreferred))
|
||||
}
|
||||
}
|
||||
|
||||
return graph
|
||||
}
|
||||
|
||||
func birdRouteToGraphviz(servers []string, responses []string, targetName string) string {
|
||||
graph := birdRouteToGraph(servers, responses, targetName)
|
||||
return graph.ToGraphviz()
|
||||
}
|
||||
|
||||
type RouteGraph struct {
|
||||
points map[string]RouteAttrs
|
||||
edges map[RouteEdge]RouteAttrs
|
||||
}
|
||||
type RouteEdge struct {
|
||||
src string
|
||||
dest string
|
||||
label string
|
||||
}
|
||||
type RouteAttrs map[string]string
|
||||
|
||||
func attrsToString(attrs RouteAttrs) string {
|
||||
if len(attrs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
result := ""
|
||||
isFirst := true
|
||||
for k, v := range attrs {
|
||||
if isFirst {
|
||||
isFirst = false
|
||||
} else {
|
||||
result += ","
|
||||
}
|
||||
result += graphvizEscape(k) + "=" + graphvizEscape(v) + ""
|
||||
}
|
||||
|
||||
return "[" + result + "]"
|
||||
}
|
||||
|
||||
func makeRouteGraph() RouteGraph {
|
||||
return RouteGraph{
|
||||
points: make(map[string]RouteAttrs),
|
||||
edges: make(map[RouteEdge]RouteAttrs),
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) AddEdge(src string, dest string, label string, attrs RouteAttrs) {
|
||||
// Add edges with same src/dest separately, multiple edges with same src/dest could exist
|
||||
edge := RouteEdge{
|
||||
src: src,
|
||||
dest: dest,
|
||||
label: label,
|
||||
}
|
||||
|
||||
_, exists := graph.edges[edge]
|
||||
if !exists {
|
||||
graph.edges[edge] = make(RouteAttrs)
|
||||
}
|
||||
|
||||
for k, v := range attrs {
|
||||
graph.edges[edge][k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) AddPoint(name string, attrs RouteAttrs) {
|
||||
graph.points[name] = attrs
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) ToGraphviz() string {
|
||||
var result string
|
||||
for name, attrs := range graph.points {
|
||||
result += fmt.Sprintf("%s %s;\n", graphvizEscape(name), attrsToString(attrs))
|
||||
}
|
||||
for edge, attrs := range graph.edges {
|
||||
attrsCopy := attrs
|
||||
if attrsCopy == nil {
|
||||
attrsCopy = make(RouteAttrs)
|
||||
}
|
||||
if len(edge.label) > 0 {
|
||||
attrsCopy["label"] = edge.label
|
||||
}
|
||||
result += fmt.Sprintf("%s -> %s %s;\n", graphvizEscape(edge.src), graphvizEscape(edge.dest), attrsToString(attrsCopy))
|
||||
}
|
||||
return "digraph {\n" + result + "}\n"
|
||||
}
|
||||
|
171
frontend/bgpmap_graph.go
Normal file
171
frontend/bgpmap_graph.go
Normal file
@ -0,0 +1,171 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RouteAttrs map[string]string
|
||||
|
||||
type RoutePoint struct {
|
||||
performLookup bool
|
||||
attrs RouteAttrs
|
||||
}
|
||||
|
||||
type RouteEdgeKey struct {
|
||||
src string
|
||||
dest string
|
||||
}
|
||||
|
||||
type RouteEdgeValue struct {
|
||||
label []string
|
||||
attrs RouteAttrs
|
||||
}
|
||||
|
||||
type RouteGraph struct {
|
||||
points map[string]RoutePoint
|
||||
edges map[RouteEdgeKey]RouteEdgeValue
|
||||
}
|
||||
|
||||
func makeRouteGraph() RouteGraph {
|
||||
return RouteGraph{
|
||||
points: make(map[string]RoutePoint),
|
||||
edges: make(map[RouteEdgeKey]RouteEdgeValue),
|
||||
}
|
||||
}
|
||||
|
||||
func makeRoutePoint() RoutePoint {
|
||||
return RoutePoint{
|
||||
performLookup: false,
|
||||
attrs: make(RouteAttrs),
|
||||
}
|
||||
}
|
||||
|
||||
func makeRouteEdgeValue() RouteEdgeValue {
|
||||
return RouteEdgeValue{
|
||||
label: []string{},
|
||||
attrs: make(RouteAttrs),
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) attrsToString(attrs RouteAttrs) string {
|
||||
if len(attrs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
result := ""
|
||||
isFirst := true
|
||||
for k, v := range attrs {
|
||||
if isFirst {
|
||||
isFirst = false
|
||||
} else {
|
||||
result += ","
|
||||
}
|
||||
result += graph.escape(k) + "=" + graph.escape(v) + ""
|
||||
}
|
||||
|
||||
return "[" + result + "]"
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) escape(s string) string {
|
||||
result, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
} else {
|
||||
return string(result)
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) AddEdge(src string, dest string, label string, attrs RouteAttrs) {
|
||||
// Add edges with same src/dest separately, multiple edges with same src/dest could exist
|
||||
edge := RouteEdgeKey{
|
||||
src: src,
|
||||
dest: dest,
|
||||
}
|
||||
|
||||
newValue, exists := graph.edges[edge]
|
||||
if !exists {
|
||||
newValue = makeRouteEdgeValue()
|
||||
}
|
||||
|
||||
newValue.label = append(newValue.label, label)
|
||||
for k, v := range attrs {
|
||||
newValue.attrs[k] = v
|
||||
}
|
||||
|
||||
graph.edges[edge] = newValue
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) AddPoint(name string, performLookup bool, attrs RouteAttrs) {
|
||||
newValue, exists := graph.points[name]
|
||||
if !exists {
|
||||
newValue = makeRoutePoint()
|
||||
}
|
||||
|
||||
newValue.performLookup = performLookup
|
||||
for k, v := range attrs {
|
||||
newValue.attrs[k] = v
|
||||
}
|
||||
|
||||
graph.points[name] = newValue
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) GetEdge(src string, dest string) *RouteEdgeValue {
|
||||
key := RouteEdgeKey{
|
||||
src: src,
|
||||
dest: dest,
|
||||
}
|
||||
value, ok := graph.edges[key]
|
||||
if ok {
|
||||
return &value
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) GetPoint(name string) *RoutePoint {
|
||||
value, ok := graph.points[name]
|
||||
if ok {
|
||||
return &value
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (graph *RouteGraph) ToGraphviz() string {
|
||||
var result string
|
||||
|
||||
asnCache := make(ASNCache)
|
||||
|
||||
for name, value := range graph.points {
|
||||
var representation string
|
||||
|
||||
if value.performLookup {
|
||||
representation = asnCache.Lookup(name)
|
||||
} else {
|
||||
representation = name
|
||||
}
|
||||
|
||||
attrsCopy := value.attrs
|
||||
if attrsCopy == nil {
|
||||
attrsCopy = make(RouteAttrs)
|
||||
}
|
||||
attrsCopy["label"] = representation
|
||||
|
||||
result += fmt.Sprintf("%s %s;\n", graph.escape(name), graph.attrsToString(value.attrs))
|
||||
}
|
||||
|
||||
for key, value := range graph.edges {
|
||||
attrsCopy := value.attrs
|
||||
if attrsCopy == nil {
|
||||
attrsCopy = make(RouteAttrs)
|
||||
}
|
||||
if len(value.label) > 0 {
|
||||
attrsCopy["label"] = strings.Join(value.label, "\n")
|
||||
}
|
||||
result += fmt.Sprintf("%s -> %s %s;\n", graph.escape(key.src), graph.escape(key.dest), graph.attrsToString(attrsCopy))
|
||||
}
|
||||
|
||||
return "digraph {\n" + result + "}\n"
|
||||
}
|
@ -1,86 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func contains(s []string, str string) bool {
|
||||
for _, v := range s {
|
||||
if v == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func TestGetASNRepresentationDNS(t *testing.T) {
|
||||
checkNetwork(t)
|
||||
|
||||
setting.dnsInterface = "asn.cymru.com"
|
||||
setting.whoisServer = ""
|
||||
cache := make(ASNCache)
|
||||
result := cache.lookup("6939")
|
||||
if !strings.Contains(result, "HURRICANE") {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetASNRepresentationWhois(t *testing.T) {
|
||||
checkNetwork(t)
|
||||
|
||||
setting.dnsInterface = ""
|
||||
setting.whoisServer = "whois.arin.net"
|
||||
cache := make(ASNCache)
|
||||
result := cache.lookup("6939")
|
||||
if !strings.Contains(result, "HURRICANE") {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetASNRepresentationFallback(t *testing.T) {
|
||||
setting.dnsInterface = ""
|
||||
setting.whoisServer = ""
|
||||
cache := make(ASNCache)
|
||||
result := cache.lookup("6939")
|
||||
if result != "AS6939" {
|
||||
t.Errorf("Lookup AS6939 failed, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
// Broken due to random order of attributes
|
||||
func TestBirdRouteToGraphviz(t *testing.T) {
|
||||
setting.dnsInterface = ""
|
||||
|
||||
// Don't change formatting of the following strings!
|
||||
|
||||
fakeResult := `192.168.0.1/32 unicast [alpha 2021-01-14 from 192.168.0.2] * (100) [AS12345i]
|
||||
via 192.168.0.2 on eth0
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422601
|
||||
BGP.next_hop: 172.18.0.2`
|
||||
|
||||
expectedLinesInResult := []string{
|
||||
`"AS4242422601" [`,
|
||||
`"AS4242422601" -> "Target: 192.168.0.1" [`,
|
||||
`"Target: 192.168.0.1" [`,
|
||||
`"alpha" [`,
|
||||
`"alpha" -> "AS4242422601" [`,
|
||||
}
|
||||
|
||||
result := birdRouteToGraphviz([]string{
|
||||
"alpha",
|
||||
}, []string{
|
||||
fakeResult,
|
||||
}, "192.168.0.1")
|
||||
|
||||
for _, line := range expectedLinesInResult {
|
||||
if !strings.Contains(result, line) {
|
||||
t.Errorf("Expected line in result not found: %s", line)
|
||||
}
|
||||
func readDataFile(filename string) string {
|
||||
_, sourceName, _, _ := runtime.Caller(0)
|
||||
projectRoot := path.Join(path.Dir(sourceName), "..")
|
||||
dir := path.Join(projectRoot, filename)
|
||||
|
||||
data, err := ioutil.ReadFile(dir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func TestBirdRouteToGraphvizXSS(t *testing.T) {
|
||||
@ -100,3 +37,37 @@ func TestBirdRouteToGraphvizXSS(t *testing.T) {
|
||||
t.Errorf("XSS injection succeeded: %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBirdRouteToGraph(t *testing.T) {
|
||||
setting.dnsInterface = ""
|
||||
|
||||
input := readDataFile("frontend/test_data/bgpmap_case1.txt")
|
||||
result := birdRouteToGraph([]string{"node"}, []string{input}, "target")
|
||||
|
||||
// Source node must exist
|
||||
if result.GetPoint("node") == nil {
|
||||
t.Error("Result doesn't contain point node")
|
||||
}
|
||||
// Last hop must exist
|
||||
if result.GetPoint("4242423914") == nil {
|
||||
t.Error("Result doesn't contain point 4242423914")
|
||||
}
|
||||
// Destination must exist
|
||||
if result.GetPoint("target") == nil {
|
||||
t.Error("Result doesn't contain point target")
|
||||
}
|
||||
|
||||
// Verify that a few paths exist
|
||||
if result.GetEdge("node", "4242423914") == nil {
|
||||
t.Error("Result doesn't contain edge from node to 4242423914")
|
||||
}
|
||||
if result.GetEdge("node", "4242422688") == nil {
|
||||
t.Error("Result doesn't contain edge from node to 4242422688")
|
||||
}
|
||||
if result.GetEdge("4242422688", "4242423914") == nil {
|
||||
t.Error("Result doesn't contain edge from 4242422688 to 4242423914")
|
||||
}
|
||||
if result.GetEdge("4242423914", "target") == nil {
|
||||
t.Error("Result doesn't contain edge from 4242423914 to target")
|
||||
}
|
||||
}
|
||||
|
151
frontend/test_data/bgpmap_case1.txt
Normal file
151
frontend/test_data/bgpmap_case1.txt
Normal file
@ -0,0 +1,151 @@
|
||||
Table master4:
|
||||
172.20.0.53/32 unicast [ibgp_sjc2 2023-04-29 from fd86:bad:11b7:22::1] * (100/38) [AS4242423914i]
|
||||
via 169.254.108.122 on igp-sjc2
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423914
|
||||
BGP.next_hop: 172.20.229.122
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 101, 44) (4242421080, 103, 122) (4242421080, 104, 1)
|
||||
unicast [miaotony_2688 2023-04-29 from fe80::2688] (100) [AS4242423914i]
|
||||
via 172.23.6.6 on dn42las-miaoton
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422688 4242423914
|
||||
BGP.next_hop: 172.23.6.6
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,3) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [imlonghao_1888 2023-04-17] (100) [AS4242423914i]
|
||||
via fe80::1888 on dn42-imlonghao
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242421888 4242423914
|
||||
BGP.next_hop: :: fe80::1888
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [ciplc_3021 2023-04-29 from fe80::943e] (100) [AS4242423914i]
|
||||
via 172.23.33.161 on dn42-ciplc
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423021 4242423914
|
||||
BGP.next_hop: 172.23.33.161
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [iedon_2189 2023-04-29 from fe80::2189:ef] (100) [AS4242423914i]
|
||||
via 172.23.91.114 on dn42-iedon
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422189 4242423914
|
||||
BGP.next_hop: 172.23.91.114
|
||||
BGP.med: 65
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,24) (64511,33) (64511,3)
|
||||
BGP.large_community: (4242422189, 1, 4) (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [prevarinite_2475 2023-04-19] (100) [AS4242423914i]
|
||||
via fe80::7072:6576:6172:1 on dn42-prevarinit
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422475 4242423192 4242423914
|
||||
BGP.next_hop: :: fe80::7072:6576:6172:1
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [lare_3035 2023-04-29] (100) [AS4242423914i]
|
||||
via fe80::3035:132 on dn42-lare
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423035 4242423914
|
||||
BGP.next_hop: :: fe80::3035:132
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,3) (64511,34) (64511,24)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [hinata_3724 2023-04-29 from fe80::3724] (100) [AS4242423914i]
|
||||
via 172.23.215.228 on dn42las-hinata
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423724 4201271111 4242423914
|
||||
BGP.next_hop: 172.23.215.228
|
||||
BGP.med: 70
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,22) (64511,1) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [liki4_0927 2023-04-21] (100) [AS4242423914i]
|
||||
via fe80::927 on dn42-liki4
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242420927 4242421888 4242423914
|
||||
BGP.next_hop: :: fe80::927
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,2) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [eastbound_2633 2023-04-29 from fe80::2633] (100) [AS4242423914i]
|
||||
via 172.23.250.42 on dn42las-eastbnd
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422633 4242423914
|
||||
BGP.next_hop: 172.23.250.42
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,24) (64511,34) (64511,3)
|
||||
BGP.large_community: (4242422633, 101, 44) (4242422633, 103, 36) (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [yura_2464 2023-04-29] (100) [AS4242423914i]
|
||||
via fe80::2464 on dn42las-yura
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242422464 4242423914
|
||||
BGP.next_hop: :: fe80::2464
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242422464, 2, 4242423914) (4242422464, 64511, 44) (4242422464, 64511, 1840) (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
||||
unicast [ibgp_fra 2023-04-29 from fd86:bad:11b7:117::1] (100/186) [AS4242423914i]
|
||||
via 169.254.108.113 on igp-chi
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423914
|
||||
BGP.next_hop: 172.20.229.117
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,1) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 101, 41) (4242421080, 103, 117) (4242421080, 104, 3)
|
||||
unicast [ibgp_sgp 2023-04-29 from fd86:bad:11b7:239::1] (100/200) [AS4242423914i]
|
||||
via 169.254.108.39 on igp-sgp
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423914
|
||||
BGP.next_hop: 172.22.108.39
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,4) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 101, 51) (4242421080, 103, 39) (4242421080, 104, 4)
|
||||
unicast [ibgp_ymq 2023-04-30 from fd86:bad:11b7:23::1] (100/105) [AS4242423914i]
|
||||
via 169.254.108.113 on igp-chi
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423914
|
||||
BGP.next_hop: 172.20.229.123
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,3) (64511,24) (64511,34)
|
||||
BGP.large_community: (4242421080, 101, 42) (4242421080, 103, 123) (4242421080, 104, 2)
|
||||
unicast [cola_3391 18:41:16.608 from fe80::3391] (100) [AS4242423914i]
|
||||
via 172.22.96.65 on dn42-cola
|
||||
Type: BGP univ
|
||||
BGP.origin: IGP
|
||||
BGP.as_path: 4242423391 4242420604 4242423914
|
||||
BGP.next_hop: 172.22.96.65
|
||||
BGP.med: 50
|
||||
BGP.local_pref: 100
|
||||
BGP.community: (64511,4) (64511,34) (64511,24)
|
||||
BGP.large_community: (4242420604, 2, 50) (4242420604, 501, 4242423914) (4242420604, 502, 44) (4242420604, 504, 4) (4242421080, 104, 1) (4242421080, 101, 44) (4242421080, 103, 126)
|
Loading…
x
Reference in New Issue
Block a user