Files
2025-05-12 12:50:54 +02:00

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())
}
}