Skip to content

Commit

Permalink
PeeringDB draft and ASN lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
maxmouchet committed Aug 27, 2019
1 parent 98fafff commit 24c7d09
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 2 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ It supports the following sources:

It reads and store IP addresses in a radix tree ([kentik/patricia](https://github.com/kentik/patricia)) for fast lookups.

It supports multiple origin ASes in opposition to pyasn [(pyasn#46)](https://github.com/hadiasghari/pyasn/issues/46).

*WIP. The API is not stable*

## Quick Start


Expand Down
10 changes: 9 additions & 1 deletion cmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,16 @@ to quickly create a Cobra application.`,
db := goasn.ASNDatabase{}
err = db.UnmarshalText(b)
check(err)
fmt.Println(len(db.Entries))

fmt.Println(db)
tree, err := goasn.NewASNTreeFromFile(path + ".txt")
check(err)
fmt.Println(tree.LookupStr("2001:660:7302:5:6153:a38:4c2d:5b3b"))
fmt.Println(tree.LookupStrMultiple([]string{
"2001:660:7302:5:6153:a38:4c2d:5b3b",
"2001:4860:4860::8888",
"2405:9800:b000::1",
}))
}
},
}
Expand Down
59 changes: 59 additions & 0 deletions pkg/goasn/asn.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package goasn

import (
"errors"
"io/ioutil"
"net"

"github.com/kentik/patricia"
Expand Down Expand Up @@ -51,6 +53,21 @@ func NewASNTree(prefixes []PrefixOrigin) (*ASNTree, error) {
return &db, nil
}

func NewASNTreeFromFile(path string) (*ASNTree, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

var db ASNDatabase
err = db.UnmarshalText(b)
if err != nil {
return nil, err
}

return NewASNTree(db.Entries)
}

func NewPrefixOrigin(e RIBEntry) PrefixOrigin {
var origin []uint32
segment := e.Path[len(e.Path)-1]
Expand All @@ -66,3 +83,45 @@ func NewPrefixOrigin(e RIBEntry) PrefixOrigin {
Origin: origin,
}
}

func (t ASNTree) LookupIP(ip net.IP) ([]uint32, error) {
if addrV4 := ip.To4(); addrV4 != nil {
addr := patricia.NewIPv4AddressFromBytes(addrV4, uint(32))
_, asn, err := t.treeV4.FindDeepestTags(addr)
return asn, err
}
if addrV6 := ip.To16(); addrV6 != nil {
addr := patricia.NewIPv6Address(addrV6, 128)
_, asn, err := t.treeV6.FindDeepestTags(addr)
return asn, err
}
return nil, errors.New("Invalid IP address")
}

func (t ASNTree) LookupIPMultiple(ips []net.IP) ([][]uint32, error) {
asns := make([][]uint32, len(ips))
for i, ip := range ips {
asn, err := t.LookupIP(ip)
if err != nil {
return nil, err
}
asns[i] = asn
}
return asns, nil
}

func (t ASNTree) LookupStr(str string) ([]uint32, error) {
return t.LookupIP(net.ParseIP(str))
}

func (t ASNTree) LookupStrMultiple(strs []string) ([][]uint32, error) {
asns := make([][]uint32, len(strs))
for i, str := range strs {
asn, err := t.LookupStr(str)
if err != nil {
return nil, err
}
asns[i] = asn
}
return asns, nil
}
83 changes: 82 additions & 1 deletion pkg/peeringdb/peeringdb.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,85 @@
package peeringdb

type IXP struct {
import (
"encoding/json"
"log"
"net/http"
"time"
)

type IX struct {
ID int `json:"id"`
Name string `json:"name"`
}

type LAN struct {
ID int `json:"id"`
IXID int `json:"ix_id"`
}

type Prefix struct {
ID int `json:"id"`
IXLanID int `json:"ixlan_id"`
Prefix string `json:"prefix"`
}

type DB struct {
IXs []IX
LANs []LAN
Prefixes []Prefix
}

func (db *DB) FromAPI() error {
var ixResponse struct {
Data []IX `json:"data"`
}

var lanResponse struct {
Data []LAN `json:"data"`
}

var pfxResponse struct {
Data []Prefix `json:"data"`
}

err := getJSON("https://peeringdb.com/api/ix.json", &ixResponse)
if err != nil {
return err
}

err = getJSON("https://peeringdb.com/api/ixlan.json", &lanResponse)
if err != nil {
return err
}

err = getJSON("https://peeringdb.com/api/ixpfx.json", &pfxResponse)
if err != nil {
return err
}

db.IXs = ixResponse.Data
db.LANs = lanResponse.Data
db.Prefixes = pfxResponse.Data

return nil
}

func getJSON(url_ string, v interface{}) error {
client := http.Client{
Timeout: time.Second * 30,
}

req, err := http.NewRequest("GET", url_, nil)
if err != nil {
return err
}

log.Printf("GET %s", req.URL)

resp, err := client.Do(req)
if err != nil {
return err
}

return json.NewDecoder(resp.Body).Decode(&v)
}

0 comments on commit 24c7d09

Please sign in to comment.