aboutsummaryrefslogtreecommitdiff
path: root/six/participant_builder.go
blob: f18a6d12b9c5326c5f8a1aea982c00c46e05c23d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2020 Michael Crute <mike@crute.us>. All rights reserved.
//
// Use of this source code is governed by a license that can be found in the
// LICENSE file.

package six

import (
	"fmt"
	"strings"
)

// Create a new SIXParticipant struct from a map of data that was parsed from
// the participant CSV file. This assumes the column headers from that CSV file
// so it will not work with the other data formats avaiable.
//
// This uses the CSV file because it's both the most rich source of data and
// the easiest to parse.
func NewSIXParticipantFromData(d map[string]string) *SIXParticipant {
	r := &SIXParticipant{
		Organization:           d["Organization"],
		URL:                    d["URL"],
		ASN:                    mustParseInt(d["ASN"]),
		Speed:                  mustParseInt(d["Speed"]),
		Switch:                 d["Switch"],
		Contact:                d["Contact"],
		Comment:                d["Comment"],
		IsConnected:            parseYesNo(d["Conn?"]),
		IsVoter:                parseYesNo(d["Voter?"]),
		Update:                 mustParseTime(d["Update"]),
		Options:                strings.Split(d["Options"], " "),
		PeeringPolicy:          d["Policy"],
		ROACount:               mustParseInt(d["rpki:roa"]),
		PeeringDBPrefixCountv4: mustParseInt(d["pdb:v4"]),
		PeeringDBPrefixCountv6: mustParseInt(d["pdb:v6"]),
		Addresses: Addresses{
			IPv4: parseIPNetFromCIDR(d["IPv4"]),
			IPv6: parseIPNetFromCIDR(d["IPv6"]),
		},
		IRRv4: IRRData{
			PrefixCount: mustParseInt(d["irr:p4"]),
			ASNCount:    mustParseInt(d["irr:a4"]),
			ASSetCount:  mustParseInt(d["irr:ap4"]),
		},
		IRRv6: IRRData{
			PrefixCount: mustParseInt(d["irr:p6"]),
			ASNCount:    mustParseInt(d["irr:a6"]),
			ASSetCount:  mustParseInt(d["irr:ap6"]),
		},
		RouteServer2: getRSData(2, d),
		RouteServer3: getRSData(3, d),
	}

	// Not all participants use the MTU9k VLAN
	ja4 := parseIPNetFromCIDR(d["Jumbo IPv4"])
	ja6 := parseIPNetFromCIDR(d["Jumbo IPv6"])
	if ja4 != nil && ja6 != nil {
		r.JumboAddresses = &Addresses{IPv4: ja4, IPv6: ja6}
	}

	return r
}

func getRSData(server int, d map[string]string) *RouteServer {
	// Extract all the data and determine if it's all empty strings, if so then
	// the participant isn't using the route server. If any data is not empty
	// then they are. Do integer conversion afterward to avoid ambiguity about
	// zero vs empty string.
	pd := []string{
		d[fmt.Sprintf("rs%d:v4", server)],
		d[fmt.Sprintf("err%d:v4", server)],
		d[fmt.Sprintf("xerr%d:v4", server)],
		d[fmt.Sprintf("rs%d:v6", server)],
		d[fmt.Sprintf("err%d:v6", server)],
		d[fmt.Sprintf("xerr%d:v6", server)],
		d[fmt.Sprintf("rs%d:v4j", server)],
		d[fmt.Sprintf("err%d:v4j", server)],
		d[fmt.Sprintf("xerr%d:v4j", server)],
		d[fmt.Sprintf("rs%d:v6j", server)],
		d[fmt.Sprintf("err%d:v6j", server)],
		d[fmt.Sprintf("xerr%d:v6j", server)],
	}

	if allEmpty(pd) {
		return nil
	}

	return &RouteServer{
		Number: server,
		asn:    mustParseInt(d["ASN"]),
		IPv4: RouteServerStats{
			Prefixes:      mustParseInt(pd[0]),
			Errors:        mustParseInt(pd[1]),
			TransitErrors: mustParseInt(pd[2]),
		},
		IPv6: RouteServerStats{
			Prefixes:      mustParseInt(pd[3]),
			Errors:        mustParseInt(pd[4]),
			TransitErrors: mustParseInt(pd[5]),
		},
		IPv4Jumbo: RouteServerStats{
			Prefixes:      mustParseInt(pd[6]),
			Errors:        mustParseInt(pd[7]),
			TransitErrors: mustParseInt(pd[8]),
		},
		IPv6Jumbo: RouteServerStats{
			Prefixes:      mustParseInt(pd[9]),
			Errors:        mustParseInt(pd[10]),
			TransitErrors: mustParseInt(pd[11]),
		},
	}
}