diff options
Diffstat (limited to 'six/participant_builder.go')
-rw-r--r-- | six/participant_builder.go | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/six/participant_builder.go b/six/participant_builder.go new file mode 100644 index 0000000..f18a6d1 --- /dev/null +++ b/six/participant_builder.go | |||
@@ -0,0 +1,113 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | // Copyright (C) 2020 Michael Crute <mike@crute.us>. All rights reserved. | ||
3 | // | ||
4 | // Use of this source code is governed by a license that can be found in the | ||
5 | // LICENSE file. | ||
6 | |||
7 | package six | ||
8 | |||
9 | import ( | ||
10 | "fmt" | ||
11 | "strings" | ||
12 | ) | ||
13 | |||
14 | // Create a new SIXParticipant struct from a map of data that was parsed from | ||
15 | // the participant CSV file. This assumes the column headers from that CSV file | ||
16 | // so it will not work with the other data formats avaiable. | ||
17 | // | ||
18 | // This uses the CSV file because it's both the most rich source of data and | ||
19 | // the easiest to parse. | ||
20 | func NewSIXParticipantFromData(d map[string]string) *SIXParticipant { | ||
21 | r := &SIXParticipant{ | ||
22 | Organization: d["Organization"], | ||
23 | URL: d["URL"], | ||
24 | ASN: mustParseInt(d["ASN"]), | ||
25 | Speed: mustParseInt(d["Speed"]), | ||
26 | Switch: d["Switch"], | ||
27 | Contact: d["Contact"], | ||
28 | Comment: d["Comment"], | ||
29 | IsConnected: parseYesNo(d["Conn?"]), | ||
30 | IsVoter: parseYesNo(d["Voter?"]), | ||
31 | Update: mustParseTime(d["Update"]), | ||
32 | Options: strings.Split(d["Options"], " "), | ||
33 | PeeringPolicy: d["Policy"], | ||
34 | ROACount: mustParseInt(d["rpki:roa"]), | ||
35 | PeeringDBPrefixCountv4: mustParseInt(d["pdb:v4"]), | ||
36 | PeeringDBPrefixCountv6: mustParseInt(d["pdb:v6"]), | ||
37 | Addresses: Addresses{ | ||
38 | IPv4: parseIPNetFromCIDR(d["IPv4"]), | ||
39 | IPv6: parseIPNetFromCIDR(d["IPv6"]), | ||
40 | }, | ||
41 | IRRv4: IRRData{ | ||
42 | PrefixCount: mustParseInt(d["irr:p4"]), | ||
43 | ASNCount: mustParseInt(d["irr:a4"]), | ||
44 | ASSetCount: mustParseInt(d["irr:ap4"]), | ||
45 | }, | ||
46 | IRRv6: IRRData{ | ||
47 | PrefixCount: mustParseInt(d["irr:p6"]), | ||
48 | ASNCount: mustParseInt(d["irr:a6"]), | ||
49 | ASSetCount: mustParseInt(d["irr:ap6"]), | ||
50 | }, | ||
51 | RouteServer2: getRSData(2, d), | ||
52 | RouteServer3: getRSData(3, d), | ||
53 | } | ||
54 | |||
55 | // Not all participants use the MTU9k VLAN | ||
56 | ja4 := parseIPNetFromCIDR(d["Jumbo IPv4"]) | ||
57 | ja6 := parseIPNetFromCIDR(d["Jumbo IPv6"]) | ||
58 | if ja4 != nil && ja6 != nil { | ||
59 | r.JumboAddresses = &Addresses{IPv4: ja4, IPv6: ja6} | ||
60 | } | ||
61 | |||
62 | return r | ||
63 | } | ||
64 | |||
65 | func getRSData(server int, d map[string]string) *RouteServer { | ||
66 | // Extract all the data and determine if it's all empty strings, if so then | ||
67 | // the participant isn't using the route server. If any data is not empty | ||
68 | // then they are. Do integer conversion afterward to avoid ambiguity about | ||
69 | // zero vs empty string. | ||
70 | pd := []string{ | ||
71 | d[fmt.Sprintf("rs%d:v4", server)], | ||
72 | d[fmt.Sprintf("err%d:v4", server)], | ||
73 | d[fmt.Sprintf("xerr%d:v4", server)], | ||
74 | d[fmt.Sprintf("rs%d:v6", server)], | ||
75 | d[fmt.Sprintf("err%d:v6", server)], | ||
76 | d[fmt.Sprintf("xerr%d:v6", server)], | ||
77 | d[fmt.Sprintf("rs%d:v4j", server)], | ||
78 | d[fmt.Sprintf("err%d:v4j", server)], | ||
79 | d[fmt.Sprintf("xerr%d:v4j", server)], | ||
80 | d[fmt.Sprintf("rs%d:v6j", server)], | ||
81 | d[fmt.Sprintf("err%d:v6j", server)], | ||
82 | d[fmt.Sprintf("xerr%d:v6j", server)], | ||
83 | } | ||
84 | |||
85 | if allEmpty(pd) { | ||
86 | return nil | ||
87 | } | ||
88 | |||
89 | return &RouteServer{ | ||
90 | Number: server, | ||
91 | asn: mustParseInt(d["ASN"]), | ||
92 | IPv4: RouteServerStats{ | ||
93 | Prefixes: mustParseInt(pd[0]), | ||
94 | Errors: mustParseInt(pd[1]), | ||
95 | TransitErrors: mustParseInt(pd[2]), | ||
96 | }, | ||
97 | IPv6: RouteServerStats{ | ||
98 | Prefixes: mustParseInt(pd[3]), | ||
99 | Errors: mustParseInt(pd[4]), | ||
100 | TransitErrors: mustParseInt(pd[5]), | ||
101 | }, | ||
102 | IPv4Jumbo: RouteServerStats{ | ||
103 | Prefixes: mustParseInt(pd[6]), | ||
104 | Errors: mustParseInt(pd[7]), | ||
105 | TransitErrors: mustParseInt(pd[8]), | ||
106 | }, | ||
107 | IPv6Jumbo: RouteServerStats{ | ||
108 | Prefixes: mustParseInt(pd[9]), | ||
109 | Errors: mustParseInt(pd[10]), | ||
110 | TransitErrors: mustParseInt(pd[11]), | ||
111 | }, | ||
112 | } | ||
113 | } | ||