blob: 1781198bfca097db9bf2036ff4be6cbc9a97b277 [file] [log] [blame]
Sergiusz Bazanski6eaaaf92019-08-02 01:25:31 +02001package provider
2
3// Support for the ARIN IRR.
4// ARIN is special. We have to query them via whois. It's also not the same
5// whois as you usually see. And also not many autnums (even big players like
6// AS15169 and AS112) have IRR entries at all.
7
8import (
9 "context"
10 "fmt"
11 "strings"
12
13 "code.hackerspace.pl/hscloud/bgpwtf/cccampix/irr/whois"
14 pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
15)
16
17const ARINWhois = "rr.arin.net:43"
18
19type arin struct {
20}
21
22func NewARIN() Provider {
23 return &arin{}
24}
25
26func (r *arin) Query(ctx context.Context, asn uint64) (*pb.IRRQueryResponse, error) {
27 data, err := whois.Query(ctx, ARINWhois, fmt.Sprintf("AS%d", asn))
28 if err != nil {
29 return nil, fmt.Errorf("could not contact ARIN IRR: %v", err)
30 }
31
32 lines := strings.Split(data, "\n")
33
34 // Convert possibly 'continued' RPSL entries into single-line entries.
35 // eg.
36 // import: from AS6083
37 // action pref=10;
38 // accept ANY
39 // into
40 // 'import', 'from AS6083, action pref=10; accept ANY'
41
42 attrs := []rpslRawAttribute{}
43 for _, line := range lines {
44 if strings.HasPrefix(strings.TrimSpace(line), "%") {
45 // Comment
46 continue
47 }
48 if strings.TrimSpace(line) == "" {
49 // Empty line
50 continue
51 }
52
53 if strings.HasPrefix(line, " ") {
54 // Continuation
55 if len(attrs) < 1 {
56 return nil, fmt.Errorf("unparseable IRR, continuation with no previous atribute name: %q", line)
57 }
58
59 attrs[len(attrs)-1].value += " " + strings.TrimSpace(line)
60 } else {
61 parts := strings.SplitN(line, ":", 2)
62 if len(parts) != 2 {
63 return nil, fmt.Errorf("unparseable IRR, line with no attribute key: %q", line)
64 }
65 name := strings.TrimSpace(parts[0])
66 value := strings.TrimSpace(parts[1])
67 attrs = append(attrs, rpslRawAttribute{
68 name: name,
69 value: value,
70 })
71 }
72 }
73
74 return &pb.IRRQueryResponse{
75 Source: pb.IRRQueryResponse_SOURCE_ARIN,
76 Attributes: parseAttributes(attrs),
77 }, nil
78}