1102644Snectar/* $NetBSD: geoip.c,v 1.7 2024/02/21 22:51:05 christos Exp $ */ 2102644Snectar 355682Smarkm/* 4102644Snectar * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 578527Sassar * 655682Smarkm * SPDX-License-Identifier: MPL-2.0 755682Smarkm * 855682Smarkm * This Source Code Form is subject to the terms of the Mozilla Public 955682Smarkm * License, v. 2.0. If a copy of the MPL was not distributed with this 1055682Smarkm * file, you can obtain one at https://mozilla.org/MPL/2.0/. 1155682Smarkm * 1255682Smarkm * See the COPYRIGHT file distributed with this work for additional 1355682Smarkm * information regarding copyright ownership. 1455682Smarkm */ 1590926Snectar 1690926Snectar/*! \file */ 1790926Snectar 1890926Snectar#if defined(HAVE_GEOIP2) 19102644Snectar#include <maxminddb.h> 2090926Snectar#endif /* if defined(HAVE_GEOIP2) */ 21102644Snectar 2255682Smarkm#include <isc/dir.h> 2355682Smarkm#include <isc/print.h> 2455682Smarkm#include <isc/string.h> 2555682Smarkm#include <isc/util.h> 2655682Smarkm 2755682Smarkm#include <dns/geoip.h> 2855682Smarkm 2955682Smarkm#include <named/geoip.h> 3055682Smarkm#include <named/log.h> 3155682Smarkm 3255682Smarkmstatic dns_geoip_databases_t geoip_table; 3355682Smarkm 3455682Smarkm#if defined(HAVE_GEOIP2) 3555682Smarkmstatic MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain; 3655682Smarkm 3755682Smarkmstatic MMDB_s * 3855682Smarkmopen_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) { 3955682Smarkm char pathbuf[PATH_MAX]; 4055682Smarkm unsigned int n; 4155682Smarkm int ret; 4255682Smarkm 4355682Smarkm n = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile); 4455682Smarkm if (n >= sizeof(pathbuf)) { 4555682Smarkm isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 4655682Smarkm NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 4755682Smarkm "GeoIP2 database '%s/%s': path too long", dir, 4855682Smarkm dbfile); 4955682Smarkm return (NULL); 5055682Smarkm } 5155682Smarkm 52102644Snectar ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb); 5355682Smarkm if (ret == MMDB_SUCCESS) { 5472445Sassar isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 5555682Smarkm NAMED_LOGMODULE_SERVER, ISC_LOG_INFO, 56102644Snectar "opened GeoIP2 database '%s'", pathbuf); 57102644Snectar return (mmdb); 58102644Snectar } 5955682Smarkm 6090926Snectar isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 6155682Smarkm NAMED_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), 6255682Smarkm "unable to open GeoIP2 database '%s' (status %d)", 6355682Smarkm pathbuf, ret); 6455682Smarkm 6555682Smarkm return (NULL); 6655682Smarkm} 6755682Smarkm#endif /* HAVE_GEOIP2 */ 6855682Smarkm 6955682Smarkmvoid 70102644Snectarnamed_geoip_init(void) { 71102644Snectar#if defined(HAVE_GEOIP2) 72102644Snectar if (named_g_geoip == NULL) { 73102644Snectar named_g_geoip = &geoip_table; 7455682Smarkm } 7572445Sassar#else /* if defined(HAVE_GEOIP2) */ 7672445Sassar return; 7755682Smarkm#endif /* if defined(HAVE_GEOIP2) */ 7855682Smarkm} 7955682Smarkm 8055682Smarkmvoid 8155682Smarkmnamed_geoip_load(char *dir) { 8290926Snectar#if defined(HAVE_GEOIP2) 8372445Sassar REQUIRE(dir != NULL); 8455682Smarkm 8572445Sassar isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 8690926Snectar NAMED_LOGMODULE_SERVER, ISC_LOG_INFO, 8772445Sassar "looking for GeoIP2 databases in '%s'", dir); 8872445Sassar 8972445Sassar named_g_geoip->country = open_geoip2(dir, "GeoIP2-Country.mmdb", 90102644Snectar &geoip_country); 9155682Smarkm if (named_g_geoip->country == NULL) { 9255682Smarkm named_g_geoip->country = open_geoip2( 9372445Sassar dir, "GeoLite2-Country.mmdb", &geoip_country); 9455682Smarkm } 9590926Snectar 9690926Snectar named_g_geoip->city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city); 9755682Smarkm if (named_g_geoip->city == NULL) { 98102644Snectar named_g_geoip->city = open_geoip2(dir, "GeoLite2-City.mmdb", 99102644Snectar &geoip_city); 100102644Snectar } 10155682Smarkm 10255682Smarkm named_g_geoip->as = open_geoip2(dir, "GeoIP2-ASN.mmdb", &geoip_as); 10355682Smarkm if (named_g_geoip->as == NULL) { 10490926Snectar named_g_geoip->as = open_geoip2(dir, "GeoLite2-ASN.mmdb", 10590926Snectar &geoip_as); 10690926Snectar } 10790926Snectar 10872445Sassar named_g_geoip->isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp); 10990926Snectar named_g_geoip->domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", 11072445Sassar &geoip_domain); 11190926Snectar#else /* if defined(HAVE_GEOIP2) */ 11255682Smarkm UNUSED(dir); 11355682Smarkm 11455682Smarkm return; 11555682Smarkm#endif /* if defined(HAVE_GEOIP2) */ 11655682Smarkm} 11755682Smarkm 11855682Smarkmvoid 11955682Smarkmnamed_geoip_unload(void) { 12055682Smarkm#ifdef HAVE_GEOIP2 12172445Sassar if (named_g_geoip->country != NULL) { 12255682Smarkm MMDB_close(named_g_geoip->country); 12355682Smarkm named_g_geoip->country = NULL; 124102644Snectar } 12555682Smarkm if (named_g_geoip->city != NULL) { 12655682Smarkm MMDB_close(named_g_geoip->city); 12755682Smarkm named_g_geoip->city = NULL; 12855682Smarkm } 12955682Smarkm if (named_g_geoip->as != NULL) { 13090926Snectar MMDB_close(named_g_geoip->as); 13190926Snectar named_g_geoip->as = NULL; 13290926Snectar } 13390926Snectar if (named_g_geoip->isp != NULL) { 13455682Smarkm MMDB_close(named_g_geoip->isp); 13590926Snectar named_g_geoip->isp = NULL; 13690926Snectar } 137102644Snectar if (named_g_geoip->domain != NULL) { 138102644Snectar MMDB_close(named_g_geoip->domain); 139102644Snectar named_g_geoip->domain = NULL; 14072445Sassar } 14155682Smarkm#endif /* ifdef HAVE_GEOIP2 */ 142102644Snectar} 14372445Sassar 144102644Snectarvoid 14555682Smarkmnamed_geoip_shutdown(void) { 14672445Sassar#ifdef HAVE_GEOIP2 14755682Smarkm named_geoip_unload(); 148102644Snectar#endif /* HAVE_GEOIP2 */ 149102644Snectar} 15090926Snectar