107 lines
2.2 KiB
Go
107 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"slices"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/oschwald/maxminddb-golang/v2"
|
|
)
|
|
|
|
var (
|
|
ccf = flag.String("c", "", "2-letters country codes separated by commas")
|
|
asnf = flag.String("a", "", "ASN numbers separated by commas")
|
|
cdbf = flag.String("cdb", "/var/lib/GeoIP/GeoLite2-City.mmdb", "City DB")
|
|
adbf = flag.String("adb", "/var/lib/GeoIP/GeoLite2-ASN.mmdb", "ASN DB")
|
|
v4f = flag.Bool("4", false, "IPv4 only")
|
|
v6f = flag.Bool("6", false, "IPv6 only")
|
|
outf = flag.String("o", "", "Output text file")
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if *ccf == "" && *asnf == "" {
|
|
log.Fatal("must specify at least -c or -a")
|
|
}
|
|
|
|
err := error(nil)
|
|
|
|
var cityDB *maxminddb.Reader
|
|
if *ccf != "" {
|
|
cityDB, err = maxminddb.Open(*cdbf)
|
|
if err != nil {
|
|
log.Fatalf("opening City DB: %v", err)
|
|
}
|
|
defer cityDB.Close()
|
|
}
|
|
|
|
var asnDB *maxminddb.Reader
|
|
if *asnf != "" {
|
|
asnDB, err = maxminddb.Open(*adbf)
|
|
if err != nil {
|
|
log.Fatalf("opening ASN DB: %v", err)
|
|
}
|
|
defer asnDB.Close()
|
|
}
|
|
|
|
f := os.Stdout
|
|
if *outf != "" {
|
|
f, err = os.Create(*outf)
|
|
if err != nil {
|
|
log.Fatalf("failed to create output file %q: %v", *outf, err)
|
|
}
|
|
}
|
|
defer f.Close()
|
|
|
|
if *ccf != "" {
|
|
cclst := strings.Split(*ccf, ",")
|
|
var rec struct {
|
|
Country struct {
|
|
IsoCode string `maxminddb:"iso_code"`
|
|
} `maxminddb:"country"`
|
|
}
|
|
for result := range cityDB.Networks() {
|
|
if err := result.Decode(&rec); err != nil {
|
|
log.Fatalf("decode city record: %v", err)
|
|
}
|
|
if slices.Contains(cclst, rec.Country.IsoCode) {
|
|
output(f, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
if *asnf != "" {
|
|
aslst := strings.Split(*asnf, ",")
|
|
var rec struct {
|
|
AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
|
|
}
|
|
for result := range asnDB.Networks() {
|
|
if err := result.Decode(&rec); err != nil {
|
|
log.Fatalf("decode ASN record: %v", err)
|
|
}
|
|
if slices.Contains(aslst, strconv.Itoa(int(rec.AutonomousSystemNumber))) {
|
|
output(f, result)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func output(f *os.File, result maxminddb.Result) {
|
|
if !*v4f && !*v6f {
|
|
fmt.Fprintln(f, result.Prefix())
|
|
}
|
|
|
|
if *v4f && result.Prefix().Addr().Is4() {
|
|
fmt.Fprintln(f, result.Prefix())
|
|
}
|
|
|
|
if *v6f && result.Prefix().Addr().Is6() {
|
|
fmt.Fprintln(f, result.Prefix())
|
|
}
|
|
}
|