Skip to content

Commit

Permalink
Add support for GeoLite2 ASN
Browse files Browse the repository at this point in the history
  • Loading branch information
oschwald committed Apr 23, 2017
1 parent 0fd242d commit 5b1dc16
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 26 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Expand Up @@ -13,12 +13,12 @@ matrix:
- go: tip

before_install:
- "if [[ $TRAVIS_GO_VERSION == 1.7 ]]; then go get -v github.com/golang/lint/golint; fi"
- "if [[ $TRAVIS_GO_VERSION == 1.8 ]]; then go get -v github.com/golang/lint/golint; fi"

script:
- go test -race -cpu 1,4 -v
- go test -race -v -tags appengine
- "if [[ $TRAVIS_GO_VERSION == 1.7 ]]; then go vet ./...; fi"
- "if [[ $TRAVIS_GO_VERSION == 1.7 ]]; then golint .; fi"
- "if [[ $TRAVIS_GO_VERSION == 1.8 ]]; then go vet ./...; fi"
- "if [[ $TRAVIS_GO_VERSION == 1.8 ]]; then golint .; fi"

sudo: false
20 changes: 20 additions & 0 deletions reader.go
Expand Up @@ -103,6 +103,12 @@ type AnonymousIP struct {
IsTorExitNode bool `maxminddb:"is_tor_exit_node"`
}

// The ASN struct corresponds to the data in the GeoLite2 ASN database.
type ASN struct {
AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
}

// The ConnectionType struct corresponds to the data in the GeoIP2
// Connection-Type database.
type ConnectionType struct {
Expand All @@ -126,6 +132,7 @@ type databaseType int

const (
isAnonymousIP = 1 << iota
isASN
isCity
isConnectionType
isCountry
Expand Down Expand Up @@ -194,6 +201,8 @@ func getDBType(reader *maxminddb.Reader) (databaseType, error) {
switch reader.Metadata.DatabaseType {
case "GeoIP2-Anonymous-IP":
return isAnonymousIP, nil
case "GeoLite2-ASN":
return isASN, nil
// We allow City lookups on Country for back compat
case "GeoLite2-City",
"GeoIP2-City",
Expand Down Expand Up @@ -255,6 +264,17 @@ func (r *Reader) AnonymousIP(ipAddress net.IP) (*AnonymousIP, error) {
return &anonIP, err
}

// ASN takes an IP address as a net.IP struct and returns a ASN struct and/or
// an error
func (r *Reader) ASN(ipAddress net.IP) (*ASN, error) {
if isASN&r.databaseType == 0 {
return nil, InvalidMethodError{"ASN", r.Metadata().DatabaseType}
}
var val ASN
err := r.mmdbReader.Lookup(ipAddress, &val)
return &val, err
}

// ConnectionType takes an IP address as a net.IP struct and returns a
// ConnectionType struct and/or an error
func (r *Reader) ConnectionType(ipAddress net.IP) (*ConnectionType, error) {
Expand Down
53 changes: 31 additions & 22 deletions reader_test.go
Expand Up @@ -26,15 +26,15 @@ func (s *MySuite) TestReader(c *C) {
m := reader.Metadata()
c.Assert(m.BinaryFormatMajorVersion, Equals, uint(2))
c.Assert(m.BinaryFormatMinorVersion, Equals, uint(0))
c.Assert(m.BuildEpoch, Equals, uint(1461706823))
c.Assert(m.BuildEpoch, Equals, uint(0x58f5327d))
c.Assert(m.DatabaseType, Equals, "GeoIP2-City")
c.Assert(m.Description, DeepEquals, map[string]string{
"en": "GeoIP2 City Test Database (fake GeoIP2 data, for example purposes only)",
"zh": "小型数据库",
})
c.Assert(m.IPVersion, Equals, uint(6))
c.Assert(m.Languages, DeepEquals, []string{"en", "zh"})
c.Assert(m.NodeCount, Equals, uint(1431))
c.Assert(m.NodeCount, Equals, uint(1240))
c.Assert(m.RecordSize, Equals, uint(28))

c.Assert(record.City.GeoNameID, Equals, uint(2643743))
Expand Down Expand Up @@ -112,6 +112,35 @@ func (s *MySuite) TestMetroCode(c *C) {
c.Assert(record.Location.MetroCode, Equals, uint(819))
}

func (s *MySuite) TestAnonymousIP(c *C) {
reader, err := Open("test-data/test-data/GeoIP2-Anonymous-IP-Test.mmdb")
c.Assert(err, IsNil)
defer reader.Close()

record, err := reader.AnonymousIP(net.ParseIP("1.2.0.0"))
c.Assert(err, IsNil)

c.Assert(record.IsAnonymous, Equals, true)

c.Assert(record.IsAnonymousVPN, Equals, true)
c.Assert(record.IsHostingProvider, Equals, false)
c.Assert(record.IsPublicProxy, Equals, false)
c.Assert(record.IsTorExitNode, Equals, false)
}

func (s *MySuite) TestASN(c *C) {
reader, err := Open("test-data/test-data/GeoLite2-ASN-Test.mmdb")
c.Assert(err, IsNil)
defer reader.Close()

record, err := reader.ASN(net.ParseIP("1.128.0.0"))
c.Assert(err, IsNil)

c.Assert(record.AutonomousSystemNumber, Equals, uint(1221))

c.Assert(record.AutonomousSystemOrganization, Equals, "Telstra Pty Ltd")
}

func (s *MySuite) TestConnectionType(c *C) {
reader, err := Open("test-data/test-data/GeoIP2-Connection-Type-Test.mmdb")
c.Assert(err, IsNil)
Expand All @@ -122,7 +151,6 @@ func (s *MySuite) TestConnectionType(c *C) {
c.Assert(err, IsNil)

c.Assert(record.ConnectionType, Equals, "Cable/DSL")

}

func (s *MySuite) TestDomain(c *C) {
Expand All @@ -133,7 +161,6 @@ func (s *MySuite) TestDomain(c *C) {
record, err := reader.Domain(net.ParseIP("1.2.0.0"))
c.Assert(err, IsNil)
c.Assert(record.Domain, Equals, "maxmind.com")

}

func (s *MySuite) TestISP(c *C) {
Expand All @@ -149,24 +176,6 @@ func (s *MySuite) TestISP(c *C) {
c.Assert(record.AutonomousSystemOrganization, Equals, "Telstra Pty Ltd")
c.Assert(record.ISP, Equals, "Telstra Internet")
c.Assert(record.Organization, Equals, "Telstra Internet")

}

func (s *MySuite) TestAnonymousIP(c *C) {
reader, err := Open("test-data/test-data/GeoIP2-Anonymous-IP-Test.mmdb")
c.Assert(err, IsNil)
defer reader.Close()

record, err := reader.AnonymousIP(net.ParseIP("1.2.0.0"))
c.Assert(err, IsNil)

c.Assert(record.IsAnonymous, Equals, true)

c.Assert(record.IsAnonymousVPN, Equals, true)
c.Assert(record.IsHostingProvider, Equals, false)
c.Assert(record.IsPublicProxy, Equals, false)
c.Assert(record.IsTorExitNode, Equals, false)

}

// This ensures the compiler does not optimize away the function call
Expand Down
2 changes: 1 addition & 1 deletion test-data
Submodule test-data updated 38 files
+14 −0 source-data/GeoIP2-DensityIncome-Test.json
+570 −0 source-data/GeoIP2-Enterprise-Test.json
+1 −1 source-data/GeoIP2-ISP-Test.json
+0 −12,697 source-data/GeoIP2-Precision-City-Test.json
+1,035 −0 source-data/GeoIP2-Precision-Enterprise-Test.json
+0 −12,593 source-data/GeoIP2-Precision-ISP-Test.json
+37 −0 source-data/GeoLite2-ASN-Test.json
+ test-data/GeoIP2-Anonymous-IP-Test.mmdb
+ test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb
+ test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb
+ test-data/GeoIP2-City-Test.mmdb
+ test-data/GeoIP2-Connection-Type-Test.mmdb
+ test-data/GeoIP2-Country-Test.mmdb
+ test-data/GeoIP2-DensityIncome-Test.mmdb
+ test-data/GeoIP2-Domain-Test.mmdb
+ test-data/GeoIP2-Enterprise-Test.mmdb
+ test-data/GeoIP2-ISP-Test.mmdb
+ test-data/GeoIP2-Precision-City-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Test.mmdb
+ test-data/GeoIP2-Precision-ISP-Test.mmdb
+ test-data/GeoLite2-ASN-Test.mmdb
+ test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
+ test-data/MaxMind-DB-string-value-entries.mmdb
+ test-data/MaxMind-DB-test-broken-pointers-24.mmdb
+ test-data/MaxMind-DB-test-broken-search-tree-24.mmdb
+ test-data/MaxMind-DB-test-decoder.mmdb
+ test-data/MaxMind-DB-test-ipv4-24.mmdb
+ test-data/MaxMind-DB-test-ipv4-28.mmdb
+ test-data/MaxMind-DB-test-ipv4-32.mmdb
+ test-data/MaxMind-DB-test-ipv6-24.mmdb
+ test-data/MaxMind-DB-test-ipv6-28.mmdb
+ test-data/MaxMind-DB-test-ipv6-32.mmdb
+ test-data/MaxMind-DB-test-metadata-pointers.mmdb
+ test-data/MaxMind-DB-test-mixed-24.mmdb
+ test-data/MaxMind-DB-test-mixed-28.mmdb
+ test-data/MaxMind-DB-test-mixed-32.mmdb
+ test-data/MaxMind-DB-test-nested.mmdb
+101 −58 test-data/write-test-data.pl

0 comments on commit 5b1dc16

Please sign in to comment.