Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
GEOIP continent lookup
package main
import (
"flag"
"fmt"
"log"
"math/rand"
"net"
"net/url"
"os"
"time"
"github.com/fiorix/freegeoip"
)
var maxmindFile = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"
func main() {
ipdb := flag.String("db", maxmindFile, "IP database file or URL")
flag.Usage = func() {
fmt.Printf("usage: %s [-db file_or_url] hostname_or_ip\n", os.Args[0])
os.Exit(1)
}
flag.Parse()
args := flag.Args()
if len(args) != 1 {
flag.Usage()
}
addr, err := net.LookupHost(args[0])
if err != nil {
log.Fatal(err)
}
ip := net.ParseIP(addr[rand.Intn(len(addr))])
if ip == nil {
flag.Usage()
}
db, err := openDB(*ipdb, time.Hour, time.Minute)
if err != nil {
log.Fatal(err)
}
select {
case <-db.NotifyOpen(): // Wait for db to be ready.
case err = <-db.NotifyError():
log.Fatal(err)
}
var resp maxmindQuery
err = db.Lookup(ip, &resp)
if err != nil {
log.Fatal(err)
}
continent := resp.Continent.Names["en"]
if len(continent) == 0 {
fmt.Println(ip, "not found")
} else {
fmt.Println(ip, "is in", continent)
}
}
// openDB opens and returns the IP database.
func openDB(dsn string, updateIntvl, maxRetryIntvl time.Duration) (db *freegeoip.DB, err error) {
u, err := url.Parse(dsn)
if err != nil || len(u.Scheme) == 0 {
db, err = freegeoip.Open(dsn)
} else {
db, err = freegeoip.OpenURL(dsn, updateIntvl, maxRetryIntvl)
}
return
}
type maxmindQuery struct {
Continent struct {
Names map[string]string `maxminddb:"names"`
} `maxminddb:"continent"`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment