geoip2

package module
v2.0.0-beta.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2025 License: ISC Imports: 3 Imported by: 5

README

GeoIP2 Reader for Go

PkgGoDev

This library reads MaxMind GeoLite2 and GeoIP2 databases.

This library is built using the Go maxminddb reader. All data for the database record is decoded using this library. Version 2.0 provides significant performance improvements with 56% fewer allocations and 34% less memory usage compared to v1. Version 2.0 also adds Network and IPAddress fields to all result structs, and includes a HasData() method to easily check if data was found. If you only need several fields, you may get superior performance by using maxminddb's Lookup directly with a result struct that only contains the required fields. (See example_test.go in the maxminddb repository for an example of this.)

Installation

go get github.com/oschwald/geoip2-golang/v2

New in v2

Version 2.0 includes several major improvements:

  • Performance: 56% fewer allocations and 34% less memory usage
  • Modern API: Uses netip.Addr instead of net.IP for better performance
  • Network Information: All result structs now include Network and IPAddress fields
  • Data Validation: New HasData() method to easily check if data was found
  • Structured Names: Replaced map[string]string with typed Names struct for better performance
  • Go 1.24 Support: Uses omitzero JSON tags to match MaxMind database behavior

Usage

See GoDoc for documentation and examples.

Example

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	// If you are using strings that may be invalid, use netip.ParseAddr and check for errors
	ip, err := netip.ParseAddr("81.2.69.142")
	if err != nil {
		log.Fatal(err)
	}
	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}
	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}
	fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names.BrazilianPortuguese)
	if len(record.Subdivisions) > 0 {
		fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names.English)
	}
	fmt.Printf("Russian country name: %v\n", record.Country.Names.Russian)
	fmt.Printf("ISO country code: %v\n", record.Country.ISOCode)
	fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
	if record.Location.HasCoordinates() {
		fmt.Printf("Coordinates: %v, %v\n", *record.Location.Latitude, *record.Location.Longitude)
	}
	// Output:
	// Portuguese (BR) city name: Londres
	// English subdivision name: England
	// Russian country name: Великобритания
	// ISO country code: GB
	// Time zone: Europe/London
	// Coordinates: 51.5142, -0.0931
}

Requirements

  • Go 1.24 or later
  • MaxMind GeoIP2 or GeoLite2 database files (.mmdb format)

Getting Database Files

GeoLite2 (Free)

Download free GeoLite2 databases from MaxMind's website. Registration required.

GeoIP2 (Commercial)

Purchase GeoIP2 databases from MaxMind for enhanced accuracy and additional features.

Database Examples

This library supports all MaxMind GeoIP2 and GeoLite2 database types. Below are examples for each database type:

City Database

The City database provides the most comprehensive geolocation data, including city, subdivision, country, and precise location information.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("128.101.101.101")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("City: %v\n", record.City.Names.English)
	fmt.Printf("Subdivision: %v\n", record.Subdivisions[0].Names.English)
	fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
	fmt.Printf("Continent: %v (%v)\n", record.Continent.Names.English, record.Continent.Code)
	fmt.Printf("Postal Code: %v\n", record.Postal.Code)
	if record.Location.HasCoordinates() {
		fmt.Printf("Location: %v, %v\n", *record.Location.Latitude, *record.Location.Longitude)
	}
	fmt.Printf("Time Zone: %v\n", record.Location.TimeZone)
	fmt.Printf("Network: %v\n", record.Traits.Network)
	fmt.Printf("IP Address: %v\n", record.Traits.IPAddress)
}
Country Database

The Country database provides country-level geolocation data.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-Country.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("81.2.69.142")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.Country(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
	fmt.Printf("Continent: %v (%v)\n", record.Continent.Names.English, record.Continent.Code)
	fmt.Printf("Is in EU: %v\n", record.Country.IsInEuropeanUnion)
	fmt.Printf("Network: %v\n", record.Traits.Network)
	fmt.Printf("IP Address: %v\n", record.Traits.IPAddress)

	if record.RegisteredCountry.Names.English != "" {
		fmt.Printf("Registered Country: %v (%v)\n",
			record.RegisteredCountry.Names.English, record.RegisteredCountry.ISOCode)
	}
}
ASN Database

The ASN database provides Autonomous System Number and organization information.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoLite2-ASN.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("1.128.0.0")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.ASN(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("ASN: %v\n", record.AutonomousSystemNumber)
	fmt.Printf("Organization: %v\n", record.AutonomousSystemOrganization)
	fmt.Printf("Network: %v\n", record.Network)
	fmt.Printf("IP Address: %v\n", record.IPAddress)
}
Anonymous IP Database

The Anonymous IP database identifies various types of anonymous and proxy networks.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-Anonymous-IP.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("81.2.69.142")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.AnonymousIP(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("Is Anonymous: %v\n", record.IsAnonymous)
	fmt.Printf("Is Anonymous VPN: %v\n", record.IsAnonymousVPN)
	fmt.Printf("Is Hosting Provider: %v\n", record.IsHostingProvider)
	fmt.Printf("Is Public Proxy: %v\n", record.IsPublicProxy)
	fmt.Printf("Is Residential Proxy: %v\n", record.IsResidentialProxy)
	fmt.Printf("Is Tor Exit Node: %v\n", record.IsTorExitNode)
	fmt.Printf("Network: %v\n", record.Network)
	fmt.Printf("IP Address: %v\n", record.IPAddress)
}
Enterprise Database

The Enterprise database provides the most comprehensive data, including all City database fields plus additional enterprise features.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-Enterprise.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("128.101.101.101")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.Enterprise(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	// Basic location information
	fmt.Printf("City: %v\n", record.City.Names.English)
	fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
	if record.Location.HasCoordinates() {
		fmt.Printf("Location: %v, %v\n", *record.Location.Latitude, *record.Location.Longitude)
	}

	// Enterprise-specific fields
	fmt.Printf("ISP: %v\n", record.Traits.ISP)
	fmt.Printf("Organization: %v\n", record.Traits.Organization)
	fmt.Printf("ASN: %v (%v)\n", record.Traits.AutonomousSystemNumber,
		record.Traits.AutonomousSystemOrganization)
	fmt.Printf("Connection Type: %v\n", record.Traits.ConnectionType)
	fmt.Printf("Domain: %v\n", record.Traits.Domain)
	fmt.Printf("User Type: %v\n", record.Traits.UserType)
	fmt.Printf("Static IP Score: %v\n", record.Traits.StaticIPScore)
	fmt.Printf("Is Anycast: %v\n", record.Traits.IsAnycast)
	fmt.Printf("Is Legitimate Proxy: %v\n", record.Traits.IsLegitimateProxy)

	// Mobile carrier information (if available)
	if record.Traits.MobileCountryCode != "" {
		fmt.Printf("Mobile Country Code: %v\n", record.Traits.MobileCountryCode)
		fmt.Printf("Mobile Network Code: %v\n", record.Traits.MobileNetworkCode)
	}

	fmt.Printf("Network: %v\n", record.Traits.Network)
	fmt.Printf("IP Address: %v\n", record.Traits.IPAddress)
}
ISP Database

The ISP database provides ISP, organization, and ASN information.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-ISP.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("1.128.0.0")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.ISP(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("ISP: %v\n", record.ISP)
	fmt.Printf("Organization: %v\n", record.Organization)
	fmt.Printf("ASN: %v (%v)\n", record.AutonomousSystemNumber,
		record.AutonomousSystemOrganization)

	// Mobile carrier information (if available)
	if record.MobileCountryCode != "" {
		fmt.Printf("Mobile Country Code: %v\n", record.MobileCountryCode)
		fmt.Printf("Mobile Network Code: %v\n", record.MobileNetworkCode)
	}

	fmt.Printf("Network: %v\n", record.Network)
	fmt.Printf("IP Address: %v\n", record.IPAddress)
}
Domain Database

The Domain database provides the second-level domain associated with an IP address.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-Domain.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("1.2.0.0")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.Domain(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("Domain: %v\n", record.Domain)
	fmt.Printf("Network: %v\n", record.Network)
	fmt.Printf("IP Address: %v\n", record.IPAddress)
}
Connection Type Database

The Connection Type database identifies the connection type of an IP address.

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-Connection-Type.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("1.0.128.0")
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.ConnectionType(ip)
	if err != nil {
		log.Fatal(err)
	}

	if !record.HasData() {
		fmt.Println("No data found for this IP")
		return
	}

	fmt.Printf("Connection Type: %v\n", record.ConnectionType)
	fmt.Printf("Network: %v\n", record.Network)
	fmt.Printf("IP Address: %v\n", record.IPAddress)
}
Error Handling

All database lookups can return errors and should be handled appropriately:

package main

import (
	"fmt"
	"log"
	"net/netip"

	"github.com/oschwald/geoip2-golang/v2"
)

func main() {
	db, err := geoip2.Open("GeoIP2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ip, err := netip.ParseAddr("10.0.0.1") // Private IP
	if err != nil {
		log.Fatal(err)
	}

	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}

	// Always check if data was found
	if !record.HasData() {
		fmt.Println("No data found for this IP address")
		return
	}

	// Check individual fields before using them
	if record.City.Names.English != "" {
		fmt.Printf("City: %v\n", record.City.Names.English)
	} else {
		fmt.Println("City name not available")
	}

	// Check array bounds for subdivisions
	if len(record.Subdivisions) > 0 {
		fmt.Printf("Subdivision: %v\n", record.Subdivisions[0].Names.English)
	} else {
		fmt.Println("No subdivision data available")
	}

	fmt.Printf("Country: %v\n", record.Country.Names.English)
}

Performance Tips

Database Reuse

Always reuse database instances across requests rather than opening/closing repeatedly:

// Good: Create once, use many times
db, err := geoip2.Open("GeoIP2-City.mmdb")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

// Use db for multiple lookups...
Memory Usage

For applications needing only specific fields, consider using the lower-level maxminddb library with custom result structs to reduce memory allocation.

Concurrent Usage

The Reader is safe for concurrent use by multiple goroutines.

JSON Serialization

All result structs include JSON tags and support marshaling to JSON:

record, err := db.City(ip)
if err != nil {
    log.Fatal(err)
}

jsonData, err := json.Marshal(record)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(jsonData))

Migration from v1

Breaking Changes
  • Import Path: Change from github.com/oschwald/geoip2-golang to github.com/oschwald/geoip2-golang/v2
  • IP Type: Use netip.Addr instead of net.IP
  • Field Names: IsoCodeISOCode
  • Names Access: Use struct fields instead of map access
  • Data Validation: Use HasData() method to check for data availability
Migration Example
// v1
import "github.com/oschwald/geoip2-golang"

ip := net.ParseIP("81.2.69.142")
record, err := db.City(ip)
cityName := record.City.Names["en"]

// v2
import "github.com/oschwald/geoip2-golang/v2"

ip, err := netip.ParseAddr("81.2.69.142")
if err != nil {
    // handle error
}
record, err := db.City(ip)
if !record.HasData() {
    // handle no data found
}
cityName := record.City.Names.English

Troubleshooting

Common Issues

Database not found: Ensure the .mmdb file path is correct and readable.

No data returned: Check if HasData() returns false - the IP may not be in the database or may be a private/reserved IP.

Performance issues: Ensure you're reusing the database instance rather than opening it for each lookup.

Testing

Make sure you checked out test data submodule:

git submodule init
git submodule update

Execute test suite:

go test

Contributing

Contributions welcome! Please fork the repository and open a pull request with your changes.

License

This is free software, licensed under the ISC license.

Documentation

Overview

Package geoip2 provides an easy-to-use API for the MaxMind GeoIP2 and GeoLite2 databases; this package does not support GeoIP Legacy databases.

Basic Usage

db, err := geoip2.Open("GeoIP2-City.mmdb")
if err != nil {
	log.Fatal(err)
}
defer db.Close()

ip, err := netip.ParseAddr("81.2.69.142")
if err != nil {
	log.Fatal(err)
}

record, err := db.City(ip)
if err != nil {
	log.Fatal(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("City: %v\n", record.City.Names.English)
fmt.Printf("Country: %v\n", record.Country.Names.English)

Database Types

This library supports all MaxMind database types:

  • City: Most comprehensive geolocation data
  • Country: Country-level geolocation
  • ASN: Autonomous system information
  • AnonymousIP: Anonymous network detection
  • Enterprise: Enhanced City data with additional fields
  • ISP: Internet service provider information
  • Domain: Second-level domain data
  • ConnectionType: Connection type identification

Version 2.0 Features

Version 2.0 introduces significant improvements:

  • Modern API using netip.Addr instead of net.IP
  • Network and IPAddress fields in all result structs
  • HasData() method for data validation
  • Structured Names type for localized names
  • JSON serialization support

See github.com/oschwald/maxminddb-golang/v2 for more advanced use cases.

Example

Example provides a basic example of using the API. Use of the Country method is analogous to that of the City method.

db, err := Open("test-data/test-data/GeoIP2-City-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()
// If you are using strings that may be invalid, use netip.ParseAddr and check for errors
ip, err := netip.ParseAddr("81.2.69.142")
if err != nil {
	log.Panic(err)
}
record, err := db.City(ip)
if err != nil {
	log.Panic(err)
}
fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names.BrazilianPortuguese)
fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names.English)
fmt.Printf("Russian country name: %v\n", record.Country.Names.Russian)
fmt.Printf("ISO country code: %v\n", record.Country.ISOCode)
fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
if record.Location.HasCoordinates() {
	fmt.Printf("Coordinates: %v, %v\n", *record.Location.Latitude, *record.Location.Longitude)
} else {
	fmt.Println("Coordinates: unavailable")
}
Output:

Portuguese (BR) city name: Londres
English subdivision name: England
Russian country name: Великобритания
ISO country code: GB
Time zone: Europe/London
Coordinates: 51.5142, -0.0931

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ASN

type ASN struct {
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// AutonomousSystemOrganization for the registered autonomous system number.
	AutonomousSystemOrganization string `json:"autonomous_system_organization,omitzero" maxminddb:"autonomous_system_organization"` //nolint:lll
	// AutonomousSystemNumber for the IP address.
	AutonomousSystemNumber uint `json:"autonomous_system_number,omitzero"       maxminddb:"autonomous_system_number"` //nolint:lll
}

The ASN struct corresponds to the data in the GeoLite2 ASN database.

func (ASN) HasData

func (a ASN) HasData() bool

HasData returns true if any data was found for the IP in the ASN database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type AnonymousIP

type AnonymousIP struct {
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// IsAnonymous is true if the IP address belongs to any sort of anonymous network.
	IsAnonymous bool `json:"is_anonymous,omitzero"         maxminddb:"is_anonymous"`
	// IsAnonymousVPN is true if the IP address is registered to an anonymous
	// VPN provider. If a VPN provider does not register subnets under names
	// associated with them, we will likely only flag their IP ranges using the
	// IsHostingProvider attribute.
	IsAnonymousVPN bool `json:"is_anonymous_vpn,omitzero"     maxminddb:"is_anonymous_vpn"`
	// IsHostingProvider is true if the IP address belongs to a hosting or VPN provider
	// (see description of IsAnonymousVPN attribute).
	IsHostingProvider bool `json:"is_hosting_provider,omitzero"  maxminddb:"is_hosting_provider"`
	// IsPublicProxy is true if the IP address belongs to a public proxy.
	IsPublicProxy bool `json:"is_public_proxy,omitzero"      maxminddb:"is_public_proxy"`
	// IsResidentialProxy is true if the IP address is on a suspected
	// anonymizing network and belongs to a residential ISP.
	IsResidentialProxy bool `json:"is_residential_proxy,omitzero" maxminddb:"is_residential_proxy"`
	// IsTorExitNode is true if the IP address is a Tor exit node.
	IsTorExitNode bool `json:"is_tor_exit_node,omitzero"     maxminddb:"is_tor_exit_node"`
}

The AnonymousIP struct corresponds to the data in the GeoIP2 Anonymous IP database.

func (AnonymousIP) HasData

func (a AnonymousIP) HasData() bool

HasData returns true if any data was found for the IP in the AnonymousIP database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type City

type City struct {
	// Traits contains various traits associated with the IP address
	Traits CityTraits `json:"traits,omitzero"              maxminddb:"traits"`
	// Postal contains data for the postal record associated with the IP address
	Postal CityPostal `json:"postal,omitzero"              maxminddb:"postal"`
	// Continent contains data for the continent record associated with the IP address
	Continent Continent `json:"continent,omitzero"           maxminddb:"continent"`
	// City contains data for the city record associated with the IP address
	City CityRecord `json:"city,omitzero"                maxminddb:"city"`
	// Subdivisions contains data for the subdivisions associated with the IP
	// address. The subdivisions array is ordered from largest to smallest. For
	// instance, the response for Oxford in the United Kingdom would have England
	// as the first element and Oxfordshire as the second element.
	Subdivisions []CitySubdivision `json:"subdivisions,omitzero"        maxminddb:"subdivisions"`
	// RepresentedCountry contains data for the represented country associated
	// with the IP address. The represented country is the country represented
	// by something like a military base or embassy.
	RepresentedCountry RepresentedCountry `json:"represented_country,omitzero" maxminddb:"represented_country"`
	// Country contains data for the country record associated with the IP
	// address. This record represents the country where MaxMind believes the IP
	// is located.
	Country CountryRecord `json:"country,omitzero"             maxminddb:"country"`
	// RegisteredCountry contains data for the registered country associated
	// with the IP address. This record represents the country where the ISP has
	// registered the IP block and may differ from the user's country.
	RegisteredCountry CountryRecord `json:"registered_country,omitzero"  maxminddb:"registered_country"`
	// Location contains data for the location record associated with the IP
	// address
	Location Location `json:"location,omitzero"            maxminddb:"location"`
}

The City struct corresponds to the data in the GeoIP2/GeoLite2 City databases.

func (City) HasData

func (c City) HasData() bool

HasData returns true if any GeoIP data was found for the IP in the City database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type CityPostal

type CityPostal struct {
	// Code is the postal code of the location. Postal codes are not
	// available for all countries.
	// In some countries, this will only contain part of the postal code.
	Code string `json:"code,omitzero" maxminddb:"code"`
}

CityPostal contains postal data for City database records.

func (CityPostal) HasData

func (p CityPostal) HasData() bool

HasData returns true if the CityPostal has any data.

type CityRecord

type CityRecord struct {
	// Names contains localized names for the city
	Names Names `json:"names,omitzero"      maxminddb:"names"`
	// GeoNameID for the city
	GeoNameID uint `json:"geoname_id,omitzero" maxminddb:"geoname_id"`
}

CityRecord contains city data for City database records.

func (CityRecord) HasData

func (c CityRecord) HasData() bool

HasData returns true if the CityRecord has any data.

type CitySubdivision

type CitySubdivision struct {
	Names     Names  `json:"names,omitzero"      maxminddb:"names"`
	ISOCode   string `json:"iso_code,omitzero"   maxminddb:"iso_code"`
	GeoNameID uint   `json:"geoname_id,omitzero" maxminddb:"geoname_id"`
}

CitySubdivision contains subdivision data for City database records.

func (CitySubdivision) HasData

func (s CitySubdivision) HasData() bool

HasData returns true if the CitySubdivision has any data.

type CityTraits

type CityTraits struct {
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the network prefix for this record. This is the largest
	// network where all of the fields besides IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// IsAnycast is true if the IP address belongs to an anycast network.
	// See https://en.wikipedia.org/wiki/Anycast
	IsAnycast bool `json:"is_anycast,omitzero" maxminddb:"is_anycast"`
}

CityTraits contains traits data for City database records.

func (CityTraits) HasData

func (t CityTraits) HasData() bool

HasData returns true if the CityTraits has any data (excluding Network and IPAddress).

type ConnectionType

type ConnectionType struct {
	// ConnectionType indicates the connection type. May be Dialup, Cable/DSL,
	// Corporate, Cellular, or Satellite. Additional values may be added in the
	// future.
	ConnectionType string `json:"connection_type,omitzero" maxminddb:"connection_type"`
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
}

The ConnectionType struct corresponds to the data in the GeoIP2 Connection-Type database.

func (ConnectionType) HasData

func (c ConnectionType) HasData() bool

HasData returns true if any data was found for the IP in the ConnectionType database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type Continent

type Continent struct {
	// Names contains localized names for the continent
	Names Names `json:"names,omitzero"      maxminddb:"names"`
	// Code is a two character continent code like "NA" (North America) or
	// "OC" (Oceania)
	Code string `json:"code,omitzero"       maxminddb:"code"`
	// GeoNameID for the continent
	GeoNameID uint `json:"geoname_id,omitzero" maxminddb:"geoname_id"`
}

Continent contains data for the continent record associated with an IP address.

func (Continent) HasData

func (c Continent) HasData() bool

HasData returns true if the Continent has any data.

type Country

type Country struct {
	// Traits contains various traits associated with the IP address
	Traits CountryTraits `json:"traits,omitzero"              maxminddb:"traits"`
	// Continent contains data for the continent record associated with the IP address
	Continent Continent `json:"continent,omitzero"           maxminddb:"continent"`
	// RepresentedCountry contains data for the represented country associated
	// with the IP address. The represented country is the country represented
	// by something like a military base or embassy.
	RepresentedCountry RepresentedCountry `json:"represented_country,omitzero" maxminddb:"represented_country"`
	// Country contains data for the country record associated with the IP
	// address. This record represents the country where MaxMind believes the IP
	// is located.
	Country CountryRecord `json:"country,omitzero"             maxminddb:"country"`
	// RegisteredCountry contains data for the registered country associated
	// with the IP address. This record represents the country where the ISP has
	// registered the IP block and may differ from the user's country.
	RegisteredCountry CountryRecord `json:"registered_country,omitzero"  maxminddb:"registered_country"`
}

The Country struct corresponds to the data in the GeoIP2/GeoLite2 Country databases.

func (Country) HasData

func (c Country) HasData() bool

HasData returns true if any GeoIP data was found for the IP in the Country database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type CountryRecord

type CountryRecord struct {
	// Names contains localized names for the country
	Names Names `json:"names,omitzero"                maxminddb:"names"`
	// ISOCode is the two-character ISO 3166-1 alpha code for the country.
	// See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
	ISOCode string `json:"iso_code,omitzero"             maxminddb:"iso_code"`
	// GeoNameID for the country
	GeoNameID uint `json:"geoname_id,omitzero"           maxminddb:"geoname_id"`
	// IsInEuropeanUnion is true if the country is a member state of the
	// European Union
	IsInEuropeanUnion bool `json:"is_in_european_union,omitzero" maxminddb:"is_in_european_union"`
}

CountryRecord contains country data for City and Country database records.

func (CountryRecord) HasData

func (c CountryRecord) HasData() bool

HasData returns true if the CountryRecord has any data.

type CountryTraits

type CountryTraits struct {
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// IsAnycast is true if the IP address belongs to an anycast network.
	// See https://en.wikipedia.org/wiki/Anycast
	IsAnycast bool `json:"is_anycast,omitzero" maxminddb:"is_anycast"`
}

CountryTraits contains traits data for Country database records.

func (CountryTraits) HasData

func (t CountryTraits) HasData() bool

HasData returns true if the CountryTraits has any data (excluding Network and IPAddress).

type Domain

type Domain struct {
	// Domain is the second level domain associated with the IP address
	// (e.g., "example.com")
	Domain string `json:"domain,omitzero"     maxminddb:"domain"`
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
}

The Domain struct corresponds to the data in the GeoIP2 Domain database.

func (Domain) HasData

func (d Domain) HasData() bool

HasData returns true if any data was found for the IP in the Domain database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type Enterprise

type Enterprise struct {
	// Continent contains data for the continent record associated with the IP
	// address.
	Continent Continent `json:"continent,omitzero"           maxminddb:"continent"`
	// Subdivisions contains data for the subdivisions associated with the IP
	// address. The subdivisions array is ordered from largest to smallest. For
	// instance, the response for Oxford in the United Kingdom would have England
	// as the first element and Oxfordshire as the second element.
	Subdivisions []EnterpriseSubdivision `json:"subdivisions,omitzero"        maxminddb:"subdivisions"`
	// Postal contains data for the postal record associated with the IP address.
	Postal EnterprisePostal `json:"postal,omitzero"              maxminddb:"postal"`
	// RepresentedCountry contains data for the represented country associated
	// with the IP address. The represented country is the country represented
	// by something like a military base or embassy.
	RepresentedCountry RepresentedCountry `json:"represented_country,omitzero" maxminddb:"represented_country"`
	// Country contains data for the country record associated with the IP
	// address. This record represents the country where MaxMind believes the IP
	// is located.
	Country EnterpriseCountryRecord `json:"country,omitzero"             maxminddb:"country"`
	// RegisteredCountry contains data for the registered country associated
	// with the IP address. This record represents the country where the ISP has
	// registered the IP block and may differ from the user's country.
	RegisteredCountry CountryRecord `json:"registered_country,omitzero"  maxminddb:"registered_country"`
	// City contains data for the city record associated with the IP address.
	City EnterpriseCityRecord `json:"city,omitzero"                maxminddb:"city"`
	// Location contains data for the location record associated with the IP
	// address
	Location Location `json:"location,omitzero"            maxminddb:"location"`
	// Traits contains various traits associated with the IP address
	Traits EnterpriseTraits `json:"traits,omitzero"              maxminddb:"traits"`
}

The Enterprise struct corresponds to the data in the GeoIP2 Enterprise database.

func (Enterprise) HasData

func (e Enterprise) HasData() bool

HasData returns true if any GeoIP data was found for the IP in the Enterprise database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type EnterpriseCityRecord

type EnterpriseCityRecord struct {
	// Names contains localized names for the city
	Names Names `json:"names,omitzero"      maxminddb:"names"`
	// GeoNameID for the city
	GeoNameID uint `json:"geoname_id,omitzero" maxminddb:"geoname_id"`
	// Confidence is a value from 0-100 indicating MaxMind's confidence that
	// the city is correct
	Confidence uint8 `json:"confidence,omitzero" maxminddb:"confidence"`
}

EnterpriseCityRecord contains city data for Enterprise database records.

func (EnterpriseCityRecord) HasData

func (c EnterpriseCityRecord) HasData() bool

HasData returns true if the EnterpriseCityRecord has any data.

type EnterpriseCountryRecord

type EnterpriseCountryRecord struct {
	// Names contains localized names for the country
	Names Names `json:"names,omitzero"                maxminddb:"names"`
	// ISOCode is the two-character ISO 3166-1 alpha code for the country.
	// See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
	ISOCode string `json:"iso_code,omitzero"             maxminddb:"iso_code"`
	// GeoNameID for the country
	GeoNameID uint `json:"geoname_id,omitzero"           maxminddb:"geoname_id"`
	// Confidence is a value from 0-100 indicating MaxMind's confidence that
	// the country is correct
	Confidence uint8 `json:"confidence,omitzero"           maxminddb:"confidence"`
	// IsInEuropeanUnion is true if the country is a member state of the
	// European Union
	IsInEuropeanUnion bool `json:"is_in_european_union,omitzero" maxminddb:"is_in_european_union"`
}

EnterpriseCountryRecord contains country data for Enterprise database records.

func (EnterpriseCountryRecord) HasData

func (c EnterpriseCountryRecord) HasData() bool

HasData returns true if the EnterpriseCountryRecord has any data.

type EnterprisePostal

type EnterprisePostal struct {
	// Code is the postal code of the location. Postal codes are not
	// available for all countries.
	// In some countries, this will only contain part of the postal code.
	Code string `json:"code,omitzero"       maxminddb:"code"`
	// Confidence is a value from 0-100 indicating MaxMind's confidence that
	// the postal code is correct
	Confidence uint8 `json:"confidence,omitzero" maxminddb:"confidence"`
}

EnterprisePostal contains postal data for Enterprise database records.

func (EnterprisePostal) HasData

func (p EnterprisePostal) HasData() bool

HasData returns true if the EnterprisePostal has any data.

type EnterpriseSubdivision

type EnterpriseSubdivision struct {
	// Names contains localized names for the subdivision
	Names Names `json:"names,omitzero"      maxminddb:"names"`
	// ISOCode is a string up to three characters long containing the
	// subdivision portion of the ISO 3166-2 code.
	// See https://en.wikipedia.org/wiki/ISO_3166-2
	ISOCode string `json:"iso_code,omitzero"   maxminddb:"iso_code"`
	// GeoNameID for the subdivision
	GeoNameID uint `json:"geoname_id,omitzero" maxminddb:"geoname_id"`
	// Confidence is a value from 0-100 indicating MaxMind's confidence that
	// the subdivision is correct
	Confidence uint8 `json:"confidence,omitzero" maxminddb:"confidence"`
}

EnterpriseSubdivision contains subdivision data for Enterprise database records.

func (EnterpriseSubdivision) HasData

func (s EnterpriseSubdivision) HasData() bool

HasData returns true if the EnterpriseSubdivision has any data.

type EnterpriseTraits

type EnterpriseTraits struct {
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// AutonomousSystemOrganization for the registered ASN
	AutonomousSystemOrganization string `json:"autonomous_system_organization,omitzero" maxminddb:"autonomous_system_organization"` //nolint:lll
	// ConnectionType indicates the connection type. May be Dialup,
	// Cable/DSL, Corporate, Cellular, or Satellite
	ConnectionType string `json:"connection_type,omitzero"                maxminddb:"connection_type"`
	// Domain is the second level domain associated with the IP address
	// (e.g., "example.com")
	Domain string `json:"domain,omitzero"                         maxminddb:"domain"`
	// ISP is the name of the ISP associated with the IP address
	ISP string `json:"isp,omitzero"                            maxminddb:"isp"`
	// MobileCountryCode is the mobile country code (MCC) associated with
	// the IP address and ISP.
	// See https://en.wikipedia.org/wiki/Mobile_country_code
	MobileCountryCode string `json:"mobile_country_code,omitzero"            maxminddb:"mobile_country_code"`
	// MobileNetworkCode is the mobile network code (MNC) associated with
	// the IP address and ISP.
	// See https://en.wikipedia.org/wiki/Mobile_network_code
	MobileNetworkCode string `json:"mobile_network_code,omitzero"            maxminddb:"mobile_network_code"`
	// Organization is the name of the organization associated with the IP
	// address
	Organization string `json:"organization,omitzero"                   maxminddb:"organization"`
	// UserType indicates the user type associated with the IP address
	// (business, cafe, cellular, college, etc.)
	UserType string `json:"user_type,omitzero"                      maxminddb:"user_type"`
	// StaticIPScore is an indicator of how static or dynamic an IP address
	// is, ranging from 0 to 99.99
	StaticIPScore float64 `json:"static_ip_score,omitzero"                maxminddb:"static_ip_score"`
	// AutonomousSystemNumber for the IP address
	AutonomousSystemNumber uint `json:"autonomous_system_number,omitzero"       maxminddb:"autonomous_system_number"`
	// IsAnycast is true if the IP address belongs to an anycast network.
	// See https://en.wikipedia.org/wiki/Anycast
	IsAnycast bool `json:"is_anycast,omitzero"                     maxminddb:"is_anycast"`
	// IsLegitimateProxy is true if MaxMind believes this IP address to be a
	// legitimate proxy, such as an internal VPN used by a corporation
	IsLegitimateProxy bool `json:"is_legitimate_proxy,omitzero"            maxminddb:"is_legitimate_proxy"`
}

EnterpriseTraits contains traits data for Enterprise database records.

func (EnterpriseTraits) HasData

func (t EnterpriseTraits) HasData() bool

HasData returns true if the EnterpriseTraits has any data (excluding Network and IPAddress).

type ISP

type ISP struct {
	// Network is the largest network prefix where all fields besides
	// IPAddress have the same value.
	Network netip.Prefix `json:"network,omitzero"`
	// IPAddress is the IP address used during the lookup
	IPAddress netip.Addr `json:"ip_address,omitzero"`
	// AutonomousSystemOrganization for the registered ASN
	AutonomousSystemOrganization string `json:"autonomous_system_organization,omitzero" maxminddb:"autonomous_system_organization"` //nolint:lll
	// ISP is the name of the ISP associated with the IP address
	ISP string `json:"isp,omitzero"                            maxminddb:"isp"`
	// MobileCountryCode is the mobile country code (MCC) associated with the IP address and ISP.
	// See https://en.wikipedia.org/wiki/Mobile_country_code
	MobileCountryCode string `json:"mobile_country_code,omitzero"            maxminddb:"mobile_country_code"`
	// MobileNetworkCode is the mobile network code (MNC) associated with the IP address and ISP.
	// See https://en.wikipedia.org/wiki/Mobile_network_code
	MobileNetworkCode string `json:"mobile_network_code,omitzero"            maxminddb:"mobile_network_code"`
	// Organization is the name of the organization associated with the IP address
	Organization string `json:"organization,omitzero"                   maxminddb:"organization"`
	// AutonomousSystemNumber for the IP address
	AutonomousSystemNumber uint `json:"autonomous_system_number,omitzero"       maxminddb:"autonomous_system_number"`
}

The ISP struct corresponds to the data in the GeoIP2 ISP database.

func (ISP) HasData

func (i ISP) HasData() bool

HasData returns true if any data was found for the IP in the ISP database. This excludes the Network and IPAddress fields which are always populated for found IPs.

type InvalidMethodError

type InvalidMethodError struct {
	Method       string
	DatabaseType string
}

InvalidMethodError is returned when a lookup method is called on a database that it does not support. For instance, calling the ISP method on a City database.

func (InvalidMethodError) Error

func (e InvalidMethodError) Error() string

type Location

type Location struct {
	// Latitude is the approximate latitude of the location associated with
	// the IP address. This value is not precise and should not be used to
	// identify a particular address or household. Will be nil if not present
	// in the database.
	Latitude *float64 `json:"latitude,omitzero"        maxminddb:"latitude"`
	// Longitude is the approximate longitude of the location associated with
	// the IP address. This value is not precise and should not be used to
	// identify a particular address or household. Will be nil if not present
	// in the database.
	Longitude *float64 `json:"longitude,omitzero"       maxminddb:"longitude"`
	// TimeZone is the time zone associated with location, as specified by
	// the IANA Time Zone Database (e.g., "America/New_York")
	TimeZone string `json:"time_zone,omitzero"       maxminddb:"time_zone"`
	// MetroCode is a metro code for targeting advertisements.
	//
	// Deprecated: Metro codes are no longer maintained and should not be used.
	MetroCode uint `json:"metro_code,omitzero"      maxminddb:"metro_code"`
	// AccuracyRadius is the approximate accuracy radius in kilometers around
	// the latitude and longitude. This is the radius where we have a 67%
	// confidence that the device using the IP address resides within the
	// circle.
	AccuracyRadius uint16 `json:"accuracy_radius,omitzero" maxminddb:"accuracy_radius"`
}

Location contains data for the location record associated with an IP address.

func (Location) HasCoordinates

func (l Location) HasCoordinates() bool

HasCoordinates returns true if both latitude and longitude are present.

func (Location) HasData

func (l Location) HasData() bool

HasData returns true if the Location has any data.

type Names

type Names struct {
	// German localized name
	German string `json:"de,omitzero"    maxminddb:"de"`
	// English localized name
	English string `json:"en,omitzero"    maxminddb:"en"`
	// Spanish localized name
	Spanish string `json:"es,omitzero"    maxminddb:"es"`
	// French localized name
	French string `json:"fr,omitzero"    maxminddb:"fr"`
	// Japanese localized name
	Japanese string `json:"ja,omitzero"    maxminddb:"ja"`
	// BrazilianPortuguese localized name (pt-BR)
	BrazilianPortuguese string `json:"pt-BR,omitzero" maxminddb:"pt-BR"` //nolint:tagliatelle,lll // pt-BR matches MMDB format
	// Russian localized name
	Russian string `json:"ru,omitzero"    maxminddb:"ru"`
	// SimplifiedChinese localized name (zh-CN)
	SimplifiedChinese string `json:"zh-CN,omitzero" maxminddb:"zh-CN"` //nolint:tagliatelle // zh-CN matches MMDB format
}

Names contains localized names for geographic entities.

func (Names) HasData

func (n Names) HasData() bool

HasData returns true if the Names struct has any localized names.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader holds the maxminddb.Reader struct. It can be created using the Open and OpenBytes functions.

func FromBytes deprecated

func FromBytes(bytes []byte) (*Reader, error)

FromBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database file and returns a Reader struct or an error. Note that the byte slice is used directly; any modification of it after opening the database will result in errors while reading from the database.

Deprecated: Use OpenBytes instead. FromBytes will be removed in a future version.

func Open

func Open(file string) (*Reader, error)

Open takes a string path to a file and returns a Reader struct or an error. The database file is opened using a memory map. Use the Close method on the Reader object to return the resources to the system.

func OpenBytes

func OpenBytes(bytes []byte) (*Reader, error)

OpenBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database file and returns a Reader struct or an error. Note that the byte slice is used directly; any modification of it after opening the database will result in errors while reading from the database.

func (*Reader) ASN

func (r *Reader) ASN(ipAddress netip.Addr) (*ASN, error)

ASN takes an IP address as a netip.Addr and returns a ASN struct and/or an error.

Example

ExampleReader_ASN demonstrates how to use the ASN database.

db, err := Open("test-data/test-data/GeoLite2-ASN-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("1.128.0.0")
if err != nil {
	log.Panic(err)
}
record, err := db.ASN(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("ASN: %v\n", record.AutonomousSystemNumber)
fmt.Printf("Organization: %v\n", record.AutonomousSystemOrganization)
Output:

ASN: 1221
Organization: Telstra Pty Ltd

func (*Reader) AnonymousIP

func (r *Reader) AnonymousIP(ipAddress netip.Addr) (*AnonymousIP, error)

AnonymousIP takes an IP address as a netip.Addr and returns a AnonymousIP struct and/or an error.

Example

ExampleReader_AnonymousIP demonstrates how to use the Anonymous IP database.

db, err := Open("test-data/test-data/GeoIP2-Anonymous-IP-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("1.2.0.0")
if err != nil {
	log.Panic(err)
}
record, err := db.AnonymousIP(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("Is Anonymous: %v\n", record.IsAnonymous)
fmt.Printf("Is Anonymous VPN: %v\n", record.IsAnonymousVPN)
fmt.Printf("Is Public Proxy: %v\n", record.IsPublicProxy)
Output:

Is Anonymous: true
Is Anonymous VPN: true
Is Public Proxy: false

func (*Reader) City

func (r *Reader) City(ipAddress netip.Addr) (*City, error)

City takes an IP address as a netip.Addr and returns a City struct and/or an error. Although this can be used with other databases, this method generally should be used with the GeoIP2 or GeoLite2 City databases.

Example

ExampleReader_City demonstrates how to use the City database.

db, err := Open("test-data/test-data/GeoIP2-City-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("81.2.69.142")
if err != nil {
	log.Panic(err)
}
record, err := db.City(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("City: %v\n", record.City.Names.English)
fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
Output:

City: London
Country: United Kingdom (GB)
Time zone: Europe/London

func (*Reader) Close

func (r *Reader) Close() error

Close unmaps the database file from virtual memory and returns the resources to the system.

func (*Reader) ConnectionType

func (r *Reader) ConnectionType(ipAddress netip.Addr) (*ConnectionType, error)

ConnectionType takes an IP address as a netip.Addr and returns a ConnectionType struct and/or an error.

Example

ExampleReader_ConnectionType demonstrates how to use the Connection Type database.

db, err := Open("test-data/test-data/GeoIP2-Connection-Type-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("1.0.128.0")
if err != nil {
	log.Panic(err)
}
record, err := db.ConnectionType(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("Connection Type: %v\n", record.ConnectionType)
Output:

Connection Type: Cable/DSL

func (*Reader) Country

func (r *Reader) Country(ipAddress netip.Addr) (*Country, error)

Country takes an IP address as a netip.Addr and returns a Country struct and/or an error. Although this can be used with other databases, this method generally should be used with the GeoIP2 or GeoLite2 Country databases.

Example

ExampleReader_Country demonstrates how to use the Country database.

db, err := Open("test-data/test-data/GeoIP2-City-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("81.2.69.142")
if err != nil {
	log.Panic(err)
}
record, err := db.Country(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
fmt.Printf("Continent: %v (%v)\n", record.Continent.Names.English, record.Continent.Code)
Output:

Country: United Kingdom (GB)
Continent: Europe (EU)

func (*Reader) Domain

func (r *Reader) Domain(ipAddress netip.Addr) (*Domain, error)

Domain takes an IP address as a netip.Addr and returns a Domain struct and/or an error.

Example

ExampleReader_Domain demonstrates how to use the Domain database.

db, err := Open("test-data/test-data/GeoIP2-Domain-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("1.2.0.0")
if err != nil {
	log.Panic(err)
}
record, err := db.Domain(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("Domain: %v\n", record.Domain)
Output:

Domain: maxmind.com

func (*Reader) Enterprise

func (r *Reader) Enterprise(ipAddress netip.Addr) (*Enterprise, error)

Enterprise takes an IP address as a netip.Addr and returns an Enterprise struct and/or an error. This is intended to be used with the GeoIP2 Enterprise database.

Example

ExampleReader_Enterprise demonstrates how to use the Enterprise database.

db, err := Open("test-data/test-data/GeoIP2-Enterprise-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("74.209.24.0")
if err != nil {
	log.Panic(err)
}
record, err := db.Enterprise(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("City: %v\n", record.City.Names.English)
fmt.Printf("Country: %v (%v)\n", record.Country.Names.English, record.Country.ISOCode)
fmt.Printf("ISP: %v\n", record.Traits.ISP)
fmt.Printf("Organization: %v\n", record.Traits.Organization)
Output:

City: Chatham
Country: United States (US)
ISP: Fairpoint Communications
Organization: Fairpoint Communications

func (*Reader) ISP

func (r *Reader) ISP(ipAddress netip.Addr) (*ISP, error)

ISP takes an IP address as a netip.Addr and returns a ISP struct and/or an error.

Example

ExampleReader_ISP demonstrates how to use the ISP database.

db, err := Open("test-data/test-data/GeoIP2-ISP-Test.mmdb")
if err != nil {
	log.Panic(err)
}
defer db.Close()

ip, err := netip.ParseAddr("1.128.0.0")
if err != nil {
	log.Panic(err)
}
record, err := db.ISP(ip)
if err != nil {
	log.Panic(err)
}

if !record.HasData() {
	fmt.Println("No data found for this IP")
	return
}

fmt.Printf("ISP: %v\n", record.ISP)
fmt.Printf("Organization: %v\n", record.Organization)
fmt.Printf("ASN: %v\n", record.AutonomousSystemNumber)
Output:

ISP: Telstra Internet
Organization: Telstra Internet
ASN: 1221

func (*Reader) Metadata

func (r *Reader) Metadata() maxminddb.Metadata

Metadata takes no arguments and returns a struct containing metadata about the MaxMind database in use by the Reader.

type RepresentedCountry

type RepresentedCountry struct {
	// Names contains localized names for the represented country
	Names Names `json:"names,omitzero"                maxminddb:"names"`
	// ISOCode is the two-character ISO 3166-1 alpha code for the represented
	// country. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
	ISOCode string `json:"iso_code,omitzero"             maxminddb:"iso_code"`
	// Type is a string indicating the type of entity that is representing
	// the country. Currently this is only "military" but may expand in the future.
	Type string `json:"type,omitzero"                 maxminddb:"type"`
	// GeoNameID for the represented country
	GeoNameID uint `json:"geoname_id,omitzero"           maxminddb:"geoname_id"`
	// IsInEuropeanUnion is true if the represented country is a member
	// state of the European Union
	IsInEuropeanUnion bool `json:"is_in_european_union,omitzero" maxminddb:"is_in_european_union"`
}

RepresentedCountry contains data for the represented country associated with an IP address. The represented country is the country represented by something like a military base or embassy.

func (RepresentedCountry) HasData

func (r RepresentedCountry) HasData() bool

HasData returns true if the RepresentedCountry has any data.

type UnknownDatabaseTypeError

type UnknownDatabaseTypeError struct {
	DatabaseType string
}

UnknownDatabaseTypeError is returned when an unknown database type is opened.

func (UnknownDatabaseTypeError) Error

func (e UnknownDatabaseTypeError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL