bgpwtf/cccampix: add IRR daemon
We add a small IRR service for getting a parsed RPSL from IRRs. For now,
we only support RIPE and ARIN, and only the following attributes:
- remarks
- import
- export
Since RPSL/RFC2622 is fucking insane, there is no guarantee that the
parser, especially the import/export parser, is correct. But it should
be good enough for our use. We even throw in some tests for good
measure.
$ grpcurl -format text -plaintext -d 'as: "26625"' 127.0.0.1:4200 ix.IRR.Query
source: SOURCE_ARIN
attributes: <
import: <
expressions: <
peering: "AS6083"
actions: "pref=10"
>
filter: "ANY"
>
>
attributes: <
import: <
expressions: <
peering: "AS12491"
actions: "pref=10"
>
filter: "ANY"
>
>
Change-Id: I8b240ffe2cd3553a25ce33dbd3917c0aef64e804
diff --git a/bgpwtf/cccampix/irr/whois/whois.go b/bgpwtf/cccampix/irr/whois/whois.go
new file mode 100644
index 0000000..0e313b1
--- /dev/null
+++ b/bgpwtf/cccampix/irr/whois/whois.go
@@ -0,0 +1,32 @@
+package whois
+
+// Support for the WHOIS protocol.
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net"
+ "strings"
+)
+
+// Query returns a semi-raw response from a WHOIS server for a given query.
+// We only convert \r\n to \n, and then do no other transformation to the data.
+func Query(ctx context.Context, server string, query string) (string, error) {
+ var d net.Dialer
+ conn, err := d.DialContext(ctx, "tcp", server)
+ if err != nil {
+ return "", fmt.Errorf("while dialing %q: %v", server, err)
+ }
+
+ defer conn.Close()
+
+ fmt.Fprintf(conn, "%s\r\n", query)
+
+ data, err := ioutil.ReadAll(conn)
+ if err != nil {
+ return "", fmt.Errorf("while receiving data from %q: %v", server, err)
+ }
+
+ return strings.ReplaceAll(string(data), "\r", ""), nil
+}