diff --git a/go.mod b/go.mod index 55bd876..3e9c29f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/nscuro/traefik-plugin-geoblock go 1.17 require ( - github.com/ip2location/ip2location-go v8.3.0+incompatible + github.com/ip2location/ip2location-go/v9 v9.1.0 github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index 456e31e..0b7c8a8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ip2location/ip2location-go v8.3.0+incompatible h1:QwUE+FlSbo6bjOWZpv2Grb57vJhWYFNPyBj2KCvfWaM= -github.com/ip2location/ip2location-go v8.3.0+incompatible/go.mod h1:3JUY1TBjTx1GdA7oRT7Zeqfc0bg3lMMuU5lXmzdpuME= +github.com/ip2location/ip2location-go/v9 v9.1.0 h1:DVlKxIcjA7CsA0cgzbidwe6eKzpbkS313LsH9ceutxI= +github.com/ip2location/ip2location-go/v9 v9.1.0/go.mod h1:s5SV6YZL10TpfPpXw//7fEJC65G/yH7Oh+Tjq9JcQEQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/plugin.go b/plugin.go index 40796c9..ed0eb76 100644 --- a/plugin.go +++ b/plugin.go @@ -5,7 +5,7 @@ import ( _ "embed" "errors" "fmt" - "github.com/ip2location/ip2location-go" + "github.com/ip2location/ip2location-go/v9" "log" "net/http" "strings" diff --git a/vendor/github.com/ip2location/ip2location-go/LICENSE.TXT b/vendor/github.com/ip2location/ip2location-go/v9/LICENSE.TXT similarity index 96% rename from vendor/github.com/ip2location/ip2location-go/LICENSE.TXT rename to vendor/github.com/ip2location/ip2location-go/v9/LICENSE.TXT index 1f446b9..a54dedb 100644 --- a/vendor/github.com/ip2location/ip2location-go/LICENSE.TXT +++ b/vendor/github.com/ip2location/ip2location-go/v9/LICENSE.TXT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 IP2Location.com +Copyright (c) 2021 IP2Location.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/ip2location/ip2location-go/README.md b/vendor/github.com/ip2location/ip2location-go/v9/README.md similarity index 87% rename from vendor/github.com/ip2location/ip2location-go/README.md rename to vendor/github.com/ip2location/ip2location-go/v9/README.md index d7a9c20..8f8966c 100644 --- a/vendor/github.com/ip2location/ip2location-go/README.md +++ b/vendor/github.com/ip2location/ip2location-go/v9/README.md @@ -4,7 +4,7 @@ IP2Location Go Package ====================== -This Go package provides a fast lookup of country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code, station name, mcc, mnc, mobile brand, elevation, and usage type from IP address by using IP2Location database. This package uses a file based database available at IP2Location.com. This database simply contains IP blocks as keys, and other information such as country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code, station name, mcc, mnc, mobile brand, elevation, and usage type as values. It supports both IP address in IPv4 and IPv6. +This Go package provides a fast lookup of country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code, station name, mcc, mnc, mobile brand, elevation, and usage type from IP address by using IP2Location database. This package uses a file based database available at IP2Location.com. This database simply contains IP blocks as keys, and other information such as country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code, station name, mcc, mnc, mobile brand, elevation, usage type, address type and IAB category as values. It supports both IP address in IPv4 and IPv6. This package can be used in many types of projects such as: @@ -25,7 +25,7 @@ Installation ======= ``` -go get github.com/ip2location/ip2location-go +go get github.com/ip2location/ip2location-go/v9 ``` Example @@ -40,9 +40,10 @@ import ( ) func main() { - db, err := ip2location.OpenDB("./IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-ISP-DOMAIN-NETSPEED-AREACODE-WEATHER-MOBILE-ELEVATION-USAGETYPE.BIN") + db, err := ip2location.OpenDB("./IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-ISP-DOMAIN-NETSPEED-AREACODE-WEATHER-MOBILE-ELEVATION-USAGETYPE-ADDRESSTYPE-CATEGORY.BIN") if err != nil { + fmt.Print(err) return } ip := "8.8.8.8" @@ -73,6 +74,8 @@ func main() { fmt.Printf("mobilebrand: %s\n", results.Mobilebrand) fmt.Printf("elevation: %f\n", results.Elevation) fmt.Printf("usagetype: %s\n", results.Usagetype) + fmt.Printf("addresstype: %s\n", results.Addresstype) + fmt.Printf("category: %s\n", results.Category) fmt.Printf("api version: %s\n", ip2location.Api_version()) db.Close() @@ -95,4 +98,4 @@ Use the IPv6 BIN file if you need to query BOTH IPv4 and IPv6 addresses. Copyright ========= -Copyright (C) 2020 by IP2Location.com, support@ip2location.com +Copyright (C) 2021 by IP2Location.com, support@ip2location.com diff --git a/vendor/github.com/ip2location/ip2location-go/ip2location.go b/vendor/github.com/ip2location/ip2location-go/v9/ip2location.go similarity index 78% rename from vendor/github.com/ip2location/ip2location-go/ip2location.go rename to vendor/github.com/ip2location/ip2location-go/v9/ip2location.go index 0b634b9..5a03a22 100644 --- a/vendor/github.com/ip2location/ip2location-go/ip2location.go +++ b/vendor/github.com/ip2location/ip2location-go/v9/ip2location.go @@ -1,12 +1,14 @@ // This ip2location package provides a fast lookup of country, region, city, latitude, longitude, ZIP code, time zone, // ISP, domain name, connection type, IDD code, area code, weather station code, station name, MCC, MNC, -// mobile brand, elevation, and usage type from IP address by using IP2Location database. +// mobile brand, elevation, usage type, address type and IAB category from IP address by using IP2Location database. package ip2location import ( "bytes" "encoding/binary" + "errors" "fmt" + "io" "math" "math/big" "net" @@ -14,6 +16,11 @@ import ( "strconv" ) +type DBReader interface { + io.ReadCloser + io.ReaderAt +} + type ip2locationmeta struct { databasetype uint8 databasecolumn uint8 @@ -28,6 +35,9 @@ type ip2locationmeta struct { ipv6indexbaseaddr uint32 ipv4columnsize uint32 ipv6columnsize uint32 + productcode uint8 + producttype uint8 + filesize uint32 } // The IP2Locationrecord struct stores all of the available @@ -53,10 +63,12 @@ type IP2Locationrecord struct { Mobilebrand string Elevation float32 Usagetype string + Addresstype string + Category string } type DB struct { - f *os.File + f DBReader meta ip2locationmeta country_position_offset uint32 @@ -78,6 +90,8 @@ type DB struct { mobilebrand_position_offset uint32 elevation_position_offset uint32 usagetype_position_offset uint32 + addresstype_position_offset uint32 + category_position_offset uint32 country_enabled bool region_enabled bool @@ -98,33 +112,37 @@ type DB struct { mobilebrand_enabled bool elevation_enabled bool usagetype_enabled bool + addresstype_enabled bool + category_enabled bool metaok bool } var defaultDB = &DB{} -var country_position = [25]uint8{0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} -var region_position = [25]uint8{0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} -var city_position = [25]uint8{0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4} -var isp_position = [25]uint8{0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9, 0, 9, 0, 9, 7, 9, 0, 9, 7, 9} -var latitude_position = [25]uint8{0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5} -var longitude_position = [25]uint8{0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6} -var domain_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10, 0, 10, 0, 10, 0, 10, 8, 10, 0, 10, 8, 10} -var zipcode_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, 7, 0, 7} -var timezone_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8, 8, 8, 7, 8, 0, 8, 8, 8, 0, 8} -var netspeed_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 11, 8, 11, 0, 11, 0, 11, 0, 11} -var iddcode_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 0, 12, 0, 12, 9, 12, 0, 12} -var areacode_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 13, 0, 13, 0, 13, 10, 13, 0, 13} -var weatherstationcode_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 0, 14, 0, 14, 0, 14} -var weatherstationname_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 15, 0, 15, 0, 15, 0, 15} -var mcc_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 0, 16, 9, 16} -var mnc_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 17, 0, 17, 10, 17} -var mobilebrand_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 18, 0, 18, 11, 18} -var elevation_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19} -var usagetype_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20} - -const api_version string = "8.3.0" +var country_position = [26]uint8{0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} +var region_position = [26]uint8{0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} +var city_position = [26]uint8{0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4} +var isp_position = [26]uint8{0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9, 0, 9, 0, 9, 7, 9, 0, 9, 7, 9, 9} +var latitude_position = [26]uint8{0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5} +var longitude_position = [26]uint8{0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6} +var domain_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10, 0, 10, 0, 10, 0, 10, 8, 10, 0, 10, 8, 10, 10} +var zipcode_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, 7, 0, 7, 7} +var timezone_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8, 8, 8, 7, 8, 0, 8, 8, 8, 0, 8, 8} +var netspeed_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 11, 8, 11, 0, 11, 0, 11, 0, 11, 11} +var iddcode_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 0, 12, 0, 12, 9, 12, 0, 12, 12} +var areacode_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 13, 0, 13, 0, 13, 10, 13, 0, 13, 13} +var weatherstationcode_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 0, 14, 0, 14, 0, 14, 14} +var weatherstationname_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 15, 0, 15, 0, 15, 0, 15, 15} +var mcc_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 0, 16, 9, 16, 16} +var mnc_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 17, 0, 17, 10, 17, 17} +var mobilebrand_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 18, 0, 18, 11, 18, 18} +var elevation_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19, 19} +var usagetype_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20, 20} +var addresstype_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21} +var category_position = [26]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22} + +const api_version string = "9.1.0" var max_ipv4_range = big.NewInt(4294967295) var max_ipv6_range = big.NewInt(0) @@ -136,32 +154,35 @@ var from_teredo = big.NewInt(0) var to_teredo = big.NewInt(0) var last_32bits = big.NewInt(4294967295) -const countryshort uint32 = 0x00001 -const countrylong uint32 = 0x00002 -const region uint32 = 0x00004 -const city uint32 = 0x00008 -const isp uint32 = 0x00010 -const latitude uint32 = 0x00020 -const longitude uint32 = 0x00040 -const domain uint32 = 0x00080 -const zipcode uint32 = 0x00100 -const timezone uint32 = 0x00200 -const netspeed uint32 = 0x00400 -const iddcode uint32 = 0x00800 -const areacode uint32 = 0x01000 -const weatherstationcode uint32 = 0x02000 -const weatherstationname uint32 = 0x04000 -const mcc uint32 = 0x08000 -const mnc uint32 = 0x10000 -const mobilebrand uint32 = 0x20000 -const elevation uint32 = 0x40000 -const usagetype uint32 = 0x80000 - -const all uint32 = countryshort | countrylong | region | city | isp | latitude | longitude | domain | zipcode | timezone | netspeed | iddcode | areacode | weatherstationcode | weatherstationname | mcc | mnc | mobilebrand | elevation | usagetype +const countryshort uint32 = 0x000001 +const countrylong uint32 = 0x000002 +const region uint32 = 0x000004 +const city uint32 = 0x000008 +const isp uint32 = 0x000010 +const latitude uint32 = 0x000020 +const longitude uint32 = 0x000040 +const domain uint32 = 0x000080 +const zipcode uint32 = 0x000100 +const timezone uint32 = 0x000200 +const netspeed uint32 = 0x000400 +const iddcode uint32 = 0x000800 +const areacode uint32 = 0x001000 +const weatherstationcode uint32 = 0x002000 +const weatherstationname uint32 = 0x004000 +const mcc uint32 = 0x008000 +const mnc uint32 = 0x010000 +const mobilebrand uint32 = 0x020000 +const elevation uint32 = 0x040000 +const usagetype uint32 = 0x080000 +const addresstype uint32 = 0x100000 +const category uint32 = 0x200000 + +const all uint32 = countryshort | countrylong | region | city | isp | latitude | longitude | domain | zipcode | timezone | netspeed | iddcode | areacode | weatherstationcode | weatherstationname | mcc | mnc | mobilebrand | elevation | usagetype | addresstype | category const invalid_address string = "Invalid IP address." const missing_file string = "Invalid database file." const not_supported string = "This parameter is unavailable for selected data file. Please upgrade the data file." +const invalid_bin string = "Incorrect IP2Location BIN file format. Please make sure that you are using the latest IP2Location BIN file." // get IP type and calculate IP number; calculates index too if exists func (d *DB) checkip(ip string) (iptype uint32, ipnum *big.Int, ipindex uint32) { @@ -301,23 +322,6 @@ func (d *DB) readfloat_row(row []byte, pos uint32) float32 { return retval } -// read float -func (d *DB) readfloat(pos uint32) (float32, error) { - pos2 := int64(pos) - var retval float32 - data := make([]byte, 4) - _, err := d.f.ReadAt(data, pos2-1) - if err != nil { - return 0, err - } - buf := bytes.NewReader(data) - err = binary.Read(buf, binary.LittleEndian, &retval) - if err != nil { - fmt.Printf("binary read failed: %v", err) - } - return retval, nil -} - func fatal(db *DB, err error) (*DB, error) { _ = db.f.Close() return nil, err @@ -326,6 +330,17 @@ func fatal(db *DB, err error) (*DB, error) { // Open takes the path to the IP2Location BIN database file. It will read all the metadata required to // be able to extract the embedded geolocation data, and return the underlining DB object. func OpenDB(dbpath string) (*DB, error) { + f, err := os.Open(dbpath) + if err != nil { + return nil, err + } + + return OpenDBWithReader(f) +} + +// OpenDBWithReader takes a DBReader to the IP2Location BIN database file. It will read all the metadata required to +// be able to extract the embedded geolocation data, and return the underlining DB object. +func OpenDBWithReader(reader DBReader) (*DB, error) { var db = &DB{} max_ipv6_range.SetString("340282366920938463463374607431768211455", 10) @@ -334,12 +349,9 @@ func OpenDB(dbpath string) (*DB, error) { from_teredo.SetString("42540488161975842760550356425300246528", 10) to_teredo.SetString("42540488241204005274814694018844196863", 10) - var err error - db.f, err = os.Open(dbpath) - if err != nil { - return nil, err - } + db.f = reader + var err error db.meta.databasetype, err = db.readuint8(1) if err != nil { return fatal(db, err) @@ -384,88 +396,27 @@ func OpenDB(dbpath string) (*DB, error) { if err != nil { return fatal(db, err) } + db.meta.productcode, err = db.readuint8(30) + if err != nil { + return fatal(db, err) + } + db.meta.producttype, err = db.readuint8(31) + if err != nil { + return fatal(db, err) + } + db.meta.filesize, err = db.readuint32(32) + if err != nil { + return fatal(db, err) + } + // check if is correct BIN (should be 1 for IP2Location BIN file), also checking for zipped file (PK being the first 2 chars) + if (db.meta.productcode != 1 && db.meta.databaseyear >= 21) || (db.meta.databasetype == 80 && db.meta.databasecolumn == 75) { // only BINs from Jan 2021 onwards have this byte set + return fatal(db, errors.New(invalid_bin)) + } db.meta.ipv4columnsize = uint32(db.meta.databasecolumn << 2) // 4 bytes each column db.meta.ipv6columnsize = uint32(16 + ((db.meta.databasecolumn - 1) << 2)) // 4 bytes each column, except IPFrom column which is 16 bytes dbt := db.meta.databasetype - // since both IPv4 and IPv6 use 4 bytes for the below columns, can just do it once here - // if country_position[dbt] != 0 { - // country_position_offset = uint32(country_position[dbt] - 1) << 2 - // country_enabled = true - // } - // if region_position[dbt] != 0 { - // region_position_offset = uint32(region_position[dbt] - 1) << 2 - // region_enabled = true - // } - // if city_position[dbt] != 0 { - // city_position_offset = uint32(city_position[dbt] - 1) << 2 - // city_enabled = true - // } - // if isp_position[dbt] != 0 { - // isp_position_offset = uint32(isp_position[dbt] - 1) << 2 - // isp_enabled = true - // } - // if domain_position[dbt] != 0 { - // domain_position_offset = uint32(domain_position[dbt] - 1) << 2 - // domain_enabled = true - // } - // if zipcode_position[dbt] != 0 { - // zipcode_position_offset = uint32(zipcode_position[dbt] - 1) << 2 - // zipcode_enabled = true - // } - // if latitude_position[dbt] != 0 { - // latitude_position_offset = uint32(latitude_position[dbt] - 1) << 2 - // latitude_enabled = true - // } - // if longitude_position[dbt] != 0 { - // longitude_position_offset = uint32(longitude_position[dbt] - 1) << 2 - // longitude_enabled = true - // } - // if timezone_position[dbt] != 0 { - // timezone_position_offset = uint32(timezone_position[dbt] - 1) << 2 - // timezone_enabled = true - // } - // if netspeed_position[dbt] != 0 { - // netspeed_position_offset = uint32(netspeed_position[dbt] - 1) << 2 - // netspeed_enabled = true - // } - // if iddcode_position[dbt] != 0 { - // iddcode_position_offset = uint32(iddcode_position[dbt] - 1) << 2 - // iddcode_enabled = true - // } - // if areacode_position[dbt] != 0 { - // areacode_position_offset = uint32(areacode_position[dbt] - 1) << 2 - // areacode_enabled = true - // } - // if weatherstationcode_position[dbt] != 0 { - // weatherstationcode_position_offset = uint32(weatherstationcode_position[dbt] - 1) << 2 - // weatherstationcode_enabled = true - // } - // if weatherstationname_position[dbt] != 0 { - // weatherstationname_position_offset = uint32(weatherstationname_position[dbt] - 1) << 2 - // weatherstationname_enabled = true - // } - // if mcc_position[dbt] != 0 { - // mcc_position_offset = uint32(mcc_position[dbt] - 1) << 2 - // mcc_enabled = true - // } - // if mnc_position[dbt] != 0 { - // mnc_position_offset = uint32(mnc_position[dbt] - 1) << 2 - // mnc_enabled = true - // } - // if mobilebrand_position[dbt] != 0 { - // mobilebrand_position_offset = uint32(mobilebrand_position[dbt] - 1) << 2 - // mobilebrand_enabled = true - // } - // if elevation_position[dbt] != 0 { - // elevation_position_offset = uint32(elevation_position[dbt] - 1) << 2 - // elevation_enabled = true - // } - // if usagetype_position[dbt] != 0 { - // usagetype_position_offset = uint32(usagetype_position[dbt] - 1) << 2 - // usagetype_enabled = true - // } if country_position[dbt] != 0 { db.country_position_offset = uint32(country_position[dbt]-2) << 2 db.country_enabled = true @@ -542,6 +493,14 @@ func OpenDB(dbpath string) (*DB, error) { db.usagetype_position_offset = uint32(usagetype_position[dbt]-2) << 2 db.usagetype_enabled = true } + if addresstype_position[dbt] != 0 { + db.addresstype_position_offset = uint32(addresstype_position[dbt]-2) << 2 + db.addresstype_enabled = true + } + if category_position[dbt] != 0 { + db.category_position_offset = uint32(category_position[dbt]-2) << 2 + db.category_enabled = true + } db.metaok = true @@ -594,6 +553,8 @@ func loadmessage(mesg string) IP2Locationrecord { x.Mnc = mesg x.Mobilebrand = mesg x.Usagetype = mesg + x.Addresstype = mesg + x.Category = mesg return x } @@ -857,6 +818,16 @@ func (d *DB) Get_usagetype(ipaddress string) (IP2Locationrecord, error) { return d.query(ipaddress, usagetype) } +// Get_addresstype will return the address type based on the queried IP address. +func (d *DB) Get_addresstype(ipaddress string) (IP2Locationrecord, error) { + return d.query(ipaddress, addresstype) +} + +// Get_category will return the category based on the queried IP address. +func (d *DB) Get_category(ipaddress string) (IP2Locationrecord, error) { + return d.query(ipaddress, category) +} + // main query func (d *DB) query(ipaddress string, mode uint32) (IP2Locationrecord, error) { x := loadmessage(not_supported) // default message @@ -949,7 +920,6 @@ func (d *DB) query(ipaddress string, mode uint32) (IP2Locationrecord, error) { var firstcol uint32 = 4 // 4 bytes for ip from if iptype == 6 { firstcol = 16 // 16 bytes for ipv6 - // rowoffset = rowoffset + 12 // coz below is assuming all columns are 4 bytes, so got 12 left to go to make 16 bytes total } row := make([]byte, colsize-firstcol) // exclude the ip from field @@ -959,129 +929,110 @@ func (d *DB) query(ipaddress string, mode uint32) (IP2Locationrecord, error) { } if mode&countryshort == 1 && d.country_enabled { - // x.Country_short = readstr(readuint32(rowoffset + country_position_offset)) if x.Country_short, err = d.readstr(d.readuint32_row(row, d.country_position_offset)); err != nil { return x, err } } if mode&countrylong != 0 && d.country_enabled { - // x.Country_long = readstr(readuint32(rowoffset + country_position_offset) + 3) if x.Country_long, err = d.readstr(d.readuint32_row(row, d.country_position_offset) + 3); err != nil { return x, err } } if mode®ion != 0 && d.region_enabled { - // x.Region = readstr(readuint32(rowoffset + region_position_offset)) if x.Region, err = d.readstr(d.readuint32_row(row, d.region_position_offset)); err != nil { return x, err } } if mode&city != 0 && d.city_enabled { - // x.City = readstr(readuint32(rowoffset + city_position_offset)) if x.City, err = d.readstr(d.readuint32_row(row, d.city_position_offset)); err != nil { return x, err } } if mode&isp != 0 && d.isp_enabled { - // x.Isp = readstr(readuint32(rowoffset + isp_position_offset)) if x.Isp, err = d.readstr(d.readuint32_row(row, d.isp_position_offset)); err != nil { return x, err } } if mode&latitude != 0 && d.latitude_enabled { - // x.Latitude = readfloat(rowoffset + latitude_position_offset) x.Latitude = d.readfloat_row(row, d.latitude_position_offset) } if mode&longitude != 0 && d.longitude_enabled { - // x.Longitude = readfloat(rowoffset + longitude_position_offset) x.Longitude = d.readfloat_row(row, d.longitude_position_offset) } if mode&domain != 0 && d.domain_enabled { - // x.Domain = readstr(readuint32(rowoffset + domain_position_offset)) if x.Domain, err = d.readstr(d.readuint32_row(row, d.domain_position_offset)); err != nil { return x, err } } if mode&zipcode != 0 && d.zipcode_enabled { - // x.Zipcode = readstr(readuint32(rowoffset + zipcode_position_offset)) if x.Zipcode, err = d.readstr(d.readuint32_row(row, d.zipcode_position_offset)); err != nil { return x, err } } if mode&timezone != 0 && d.timezone_enabled { - // x.Timezone = readstr(readuint32(rowoffset + timezone_position_offset)) if x.Timezone, err = d.readstr(d.readuint32_row(row, d.timezone_position_offset)); err != nil { return x, err } } if mode&netspeed != 0 && d.netspeed_enabled { - // x.Netspeed = readstr(readuint32(rowoffset + netspeed_position_offset)) if x.Netspeed, err = d.readstr(d.readuint32_row(row, d.netspeed_position_offset)); err != nil { return x, err } } if mode&iddcode != 0 && d.iddcode_enabled { - // x.Iddcode = readstr(readuint32(rowoffset + iddcode_position_offset)) if x.Iddcode, err = d.readstr(d.readuint32_row(row, d.iddcode_position_offset)); err != nil { return x, err } } if mode&areacode != 0 && d.areacode_enabled { - // x.Areacode = readstr(readuint32(rowoffset + areacode_position_offset)) if x.Areacode, err = d.readstr(d.readuint32_row(row, d.areacode_position_offset)); err != nil { return x, err } } if mode&weatherstationcode != 0 && d.weatherstationcode_enabled { - // x.Weatherstationcode = readstr(readuint32(rowoffset + weatherstationcode_position_offset)) if x.Weatherstationcode, err = d.readstr(d.readuint32_row(row, d.weatherstationcode_position_offset)); err != nil { return x, err } } if mode&weatherstationname != 0 && d.weatherstationname_enabled { - // x.Weatherstationname = readstr(readuint32(rowoffset + weatherstationname_position_offset)) if x.Weatherstationname, err = d.readstr(d.readuint32_row(row, d.weatherstationname_position_offset)); err != nil { return x, err } } if mode&mcc != 0 && d.mcc_enabled { - // x.Mcc = readstr(readuint32(rowoffset + mcc_position_offset)) if x.Mcc, err = d.readstr(d.readuint32_row(row, d.mcc_position_offset)); err != nil { return x, err } } if mode&mnc != 0 && d.mnc_enabled { - // x.Mnc = readstr(readuint32(rowoffset + mnc_position_offset)) if x.Mnc, err = d.readstr(d.readuint32_row(row, d.mnc_position_offset)); err != nil { return x, err } } if mode&mobilebrand != 0 && d.mobilebrand_enabled { - // x.Mobilebrand = readstr(readuint32(rowoffset + mobilebrand_position_offset)) if x.Mobilebrand, err = d.readstr(d.readuint32_row(row, d.mobilebrand_position_offset)); err != nil { return x, err } } if mode&elevation != 0 && d.elevation_enabled { - // f, _ := strconv.ParseFloat(readstr(readuint32(rowoffset + elevation_position_offset)), 32) res, err := d.readstr(d.readuint32_row(row, d.elevation_position_offset)) if err != nil { return x, err @@ -1092,12 +1043,23 @@ func (d *DB) query(ipaddress string, mode uint32) (IP2Locationrecord, error) { } if mode&usagetype != 0 && d.usagetype_enabled { - // x.Usagetype = readstr(readuint32(rowoffset + usagetype_position_offset)) if x.Usagetype, err = d.readstr(d.readuint32_row(row, d.usagetype_position_offset)); err != nil { return x, err } } + if mode&addresstype != 0 && d.addresstype_enabled { + if x.Addresstype, err = d.readstr(d.readuint32_row(row, d.addresstype_position_offset)); err != nil { + return x, err + } + } + + if mode&category != 0 && d.category_enabled { + if x.Category, err = d.readstr(d.readuint32_row(row, d.category_position_offset)); err != nil { + return x, err + } + } + return x, nil } else { if ipno.Cmp(ipfrom) < 0 { @@ -1136,4 +1098,6 @@ func Printrecord(x IP2Locationrecord) { fmt.Printf("mobilebrand: %s\n", x.Mobilebrand) fmt.Printf("elevation: %f\n", x.Elevation) fmt.Printf("usagetype: %s\n", x.Usagetype) + fmt.Printf("addresstype: %s\n", x.Addresstype) + fmt.Printf("category: %s\n", x.Category) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 414cdbf..304c28d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,9 +1,9 @@ # github.com/davecgh/go-spew v1.1.0 ## explicit github.com/davecgh/go-spew/spew -# github.com/ip2location/ip2location-go v8.3.0+incompatible -## explicit -github.com/ip2location/ip2location-go +# github.com/ip2location/ip2location-go/v9 v9.1.0 +## explicit; go 1.14 +github.com/ip2location/ip2location-go/v9 # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib