aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2018-02-08 17:20:26 -0800
committerGerald Combs <gerald@wireshark.org>2018-03-06 18:02:21 +0000
commita1da75c554881667dd92e11f098630f2d604872b (patch)
treeb1d6a60a663bf93f1eede809a0c383544508d6e2 /epan
parentb2d3680558d19998c55b48e9807a26e145756eba (diff)
Transition from GeoIP Legacy to MaxMindDB.
MaxMind is discontinuing its legacy databases in April in favor of GeoIP2, which use a newer database format (MaxMind DB). The reference C library (libmaxminddb) is available under the Apache 2.0 license which isn't quite compatible with ours. Add mmdbresolve, a utility that reads IPv4 and IPv6 addresses on stdin and prints resolved information on stdout. Place it under a liberal license (MIT) so that we can keep libmaxminddb at arm's length. Add epan/maxmind_db.[ch], which spawns mmdbresolve and communicates with it via stdio. Migrate the preferences and documentation to MaxMindDB. Change the IPv4 and IPv6 asnum fields to FT_UINT32s. Change the geographic coordinate fields to FT_DOUBLEs. Bug: 10658 Change-Id: I24aeed637bea1b41d173270bda413af230f4425f Reviewed-on: https://code.wireshark.org/review/26214 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'epan')
-rw-r--r--epan/CMakeLists.txt9
-rw-r--r--epan/Makefile.am9
-rw-r--r--epan/addr_resolv.c10
-rw-r--r--epan/addr_resolv.h6
-rw-r--r--epan/dissectors/Makefile.am2
-rw-r--r--epan/dissectors/packet-ip.c271
-rw-r--r--epan/dissectors/packet-ipv6.c285
-rw-r--r--epan/epan.c10
-rw-r--r--epan/geoip_db.c638
-rw-r--r--epan/geoip_db.h104
-rw-r--r--epan/maxmind_db.c513
-rw-r--r--epan/maxmind_db.h93
-rw-r--r--epan/prefs.c8
13 files changed, 876 insertions, 1082 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index 5bd3d40e4e..f0196fc57f 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -105,7 +105,7 @@ set(LIBWIRESHARK_PUBLIC_HEADERS
frame_data_sequence.h
funnel.h
garrayfix.h
- geoip_db.h
+ #geoip_db.h
golay.h
guid-utils.h
iana_charsets.h
@@ -117,6 +117,7 @@ set(LIBWIRESHARK_PUBLIC_HEADERS
ipv6.h
lapd_sapi.h
llcsaps.h
+ maxmind_db.h
media_params.h
next_tvb.h
nlpid.h
@@ -208,12 +209,13 @@ set(LIBWIRESHARK_NONGENERATED_FILES
frame_data.c
frame_data_sequence.c
funnel.c
- geoip_db.c
+ #geoip_db.c
golay.c
guid-utils.c
iana_charsets.c
in_cksum.c
ipproto.c
+ maxmind_db.c
media_params.c
next_tvb.c
oids.c
@@ -278,8 +280,9 @@ set(epan_LIBS
wsutil
${CARES_LIBRARIES}
${GCRYPT_LIBRARIES}
- ${GEOIP_LIBRARIES}
+ #${GEOIP_LIBRARIES}
${GLIB2_LIBRARIES}
+ ${GIO2_LIBRARIES}
${GTHREAD2_LIBRARIES}
${GNUTLS_LIBRARIES}
${KERBEROS_LIBRARIES}
diff --git a/epan/Makefile.am b/epan/Makefile.am
index d22d68e18b..c85fcd2d52 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -31,8 +31,8 @@ SUBDIRS = crypt ftypes dfilter dissectors wmem $(wslua_dir)
AM_CPPFLAGS = $(INCLUDEDIRS) $(WS_CPPFLAGS) \
$(GLIB_CFLAGS) $(PCAP_CFLAGS) $(LUA_CFLAGS) $(LIBGNUTLS_CFLAGS) \
- $(LIBGCRYPT_CFLAGS) $(LIBSMI_CFLAGS) $(LIBGEOIP_CFLAGS) \
- $(LZ4_CFLAGS) $(KRB5_CFLAGS) $(SNAPPY_CFLAGS) $(LIBXML2_CFLAGS)
+ $(LIBGCRYPT_CFLAGS) $(LIBSMI_CFLAGS) $(LZ4_CFLAGS) $(KRB5_CFLAGS) \
+ $(SNAPPY_CFLAGS) $(LIBXML2_CFLAGS)
lib_LTLIBRARIES = libwireshark.la
@@ -71,12 +71,12 @@ LIBWIRESHARK_NONGENERATED_SRC = \
frame_data.c \
frame_data_sequence.c \
funnel.c \
- geoip_db.c \
golay.c \
guid-utils.c \
iana_charsets.c \
in_cksum.c \
ipproto.c \
+ maxmind_db.c \
media_params.c \
next_tvb.c \
oids.c \
@@ -212,7 +212,6 @@ LIBWIRESHARK_INCLUDES_PUBLIC = \
frame_data_sequence.h \
funnel.h \
garrayfix.h \
- geoip_db.h \
golay.h \
guid-utils.h \
iana_charsets.h \
@@ -224,6 +223,7 @@ LIBWIRESHARK_INCLUDES_PUBLIC = \
ipv6.h \
lapd_sapi.h \
llcsaps.h \
+ maxmind_db.h \
media_params.h \
next_tvb.h \
nlpid.h \
@@ -321,7 +321,6 @@ libwireshark_la_LIBADD = \
${top_builddir}/wiretap/libwiretap.la \
${top_builddir}/wsutil/libwsutil.la \
@C_ARES_LIBS@ \
- @GEOIP_LIBS@ \
@KRB5_LIBS@ \
@LIBGCRYPT_LIBS@ \
@LIBGNUTLS_LIBS@ \
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index 1cae8a5733..56da73bf69 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -92,6 +92,7 @@
#include <epan/strutil.h>
#include <epan/to_str-int.h>
+#include <epan/maxmind_db.h>
#include <epan/prefs.h>
#define ENAME_HOSTS "hosts"
@@ -245,12 +246,12 @@ static void add_serv_port_cb(const guint32 port, gpointer ptr);
/* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing
* One-at-a-Time hash
*/
-static guint32
+guint
ipv6_oat_hash(gconstpointer key)
{
int len = 16;
const unsigned char *p = (const unsigned char *)key;
- guint32 h = 0;
+ guint h = 0;
int i;
for ( i = 0; i < len; i++ ) {
@@ -266,7 +267,7 @@ ipv6_oat_hash(gconstpointer key)
return h;
}
-static gboolean
+gboolean
ipv6_equal(gconstpointer v1, gconstpointer v2)
{
@@ -2519,6 +2520,7 @@ host_name_lookup_process(void) {
wmem_list_frame_t* head;
new_resolved_objects = FALSE;
+ nro |= maxmind_db_lookup_process();
if (!async_dns_initialized)
/* c-ares not initialized. Bail out and cancel timers. */
@@ -2579,6 +2581,8 @@ host_name_lookup_process(void) {
new_resolved_objects = FALSE;
+ nro |= maxmind_db_lookup_process();
+
return nro;
}
diff --git a/epan/addr_resolv.h b/epan/addr_resolv.h
index cfac1fc5c1..bc1d78d61a 100644
--- a/epan/addr_resolv.h
+++ b/epan/addr_resolv.h
@@ -381,6 +381,12 @@ gboolean str_to_ip(const char *str, void *dst);
WS_DLL_PUBLIC
gboolean str_to_ip6(const char *str, void *dst);
+WS_DLL_LOCAL
+guint ipv6_oat_hash(gconstpointer key);
+
+WS_DLL_LOCAL
+gboolean ipv6_equal(gconstpointer v1, gconstpointer v2);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/epan/dissectors/Makefile.am b/epan/dissectors/Makefile.am
index 423a5dda34..0367141e8e 100644
--- a/epan/dissectors/Makefile.am
+++ b/epan/dissectors/Makefile.am
@@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.am.inc
AM_CPPFLAGS = $(INCLUDEDIRS) -I$(top_srcdir)/epan $(WS_CPPFLAGS) \
$(GLIB_CFLAGS) $(LIBGNUTLS_CFLAGS) $(LIBGCRYPT_CFLAGS) \
- $(LIBGEOIP_CFLAGS) $(KRB5_CFLAGS) $(LIBXML2_CFLAGS)
+ $(KRB5_CFLAGS) $(LIBXML2_CFLAGS)
include Custom.common
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 1ab1b25812..02432764f1 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -18,6 +18,7 @@
#include <epan/packet.h>
#include <epan/capture_dissectors.h>
#include <epan/addr_resolv.h>
+#include <epan/maxmind_db.h>
#include <epan/ipproto.h>
#include <epan/expert.h>
#include <epan/ip_opts.h>
@@ -48,11 +49,6 @@
#include "packet-mpls.h"
#include "packet-nsh.h"
-#ifdef HAVE_GEOIP
-#include <GeoIP.h>
-#include <epan/geoip_db.h>
-#endif /* HAVE_GEOIP */
-
void proto_register_ip(void);
void proto_reg_handoff_ip(void);
@@ -76,10 +72,8 @@ static gboolean ip_tso_supported = TRUE;
/* Use heuristics to determine subdissector */
static gboolean try_heuristic_first = FALSE;
-#ifdef HAVE_GEOIP
-/* Look up addresses in GeoIP */
+/* Look up addresses via mmdbresolve */
static gboolean ip_use_geoip = TRUE;
-#endif /* HAVE_GEOIP */
/* Interpret the reserved flag as security flag (RFC 3514) */
static gboolean ip_security_flag = FALSE;
@@ -204,29 +198,26 @@ static int hf_ip_cipso_doi = -1;
static int hf_ip_opt_time_stamp = -1;
static int hf_ip_opt_time_stamp_addr = -1;
-#ifdef HAVE_GEOIP
static int hf_geoip_country = -1;
static int hf_geoip_city = -1;
-static int hf_geoip_org = -1;
-static int hf_geoip_isp = -1;
-static int hf_geoip_asnum = -1;
-static int hf_geoip_lat = -1;
-static int hf_geoip_lon = -1;
+static int hf_geoip_as_number = -1;
+static int hf_geoip_as_org = -1;
+static int hf_geoip_latitude = -1;
+static int hf_geoip_longitude = -1;
+static int hf_geoip_src_summary = -1;
static int hf_geoip_src_country = -1;
static int hf_geoip_src_city = -1;
-static int hf_geoip_src_org = -1;
-static int hf_geoip_src_isp = -1;
-static int hf_geoip_src_asnum = -1;
-static int hf_geoip_src_lat = -1;
-static int hf_geoip_src_lon = -1;
+static int hf_geoip_src_as_number = -1;
+static int hf_geoip_src_as_org = -1;
+static int hf_geoip_src_latitude = -1;
+static int hf_geoip_src_longitude = -1;
+static int hf_geoip_dst_summary = -1;
static int hf_geoip_dst_country = -1;
static int hf_geoip_dst_city = -1;
-static int hf_geoip_dst_org = -1;
-static int hf_geoip_dst_isp = -1;
-static int hf_geoip_dst_asnum = -1;
-static int hf_geoip_dst_lat = -1;
-static int hf_geoip_dst_lon = -1;
-#endif /* HAVE_GEOIP */
+static int hf_geoip_dst_as_number = -1;
+static int hf_geoip_dst_as_org = -1;
+static int hf_geoip_dst_latitude = -1;
+static int hf_geoip_dst_longitude = -1;
static gint ett_ip = -1;
static gint ett_ip_dsfield = -1;
@@ -271,9 +262,7 @@ static expert_field ei_ip_bogus_ip_version = EI_INIT;
static dissector_handle_t ip_handle;
static dissector_table_t ip_option_table;
-#ifdef HAVE_GEOIP
static gint ett_geoip_info = -1;
-#endif /* HAVE_GEOIP */
static const fragment_items ip_frag_items = {
&ett_ip_fragment,
@@ -576,110 +565,93 @@ capture_ip(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo,
return try_capture_dissector("ip.proto", pd[offset + 9], pd, offset+IPH_MIN_LEN, len, cpinfo, pseudo_header);
}
-#ifdef HAVE_GEOIP
static void
-add_geoip_info_entry(proto_tree *geoip_info_tree, proto_item *geoip_info_item, tvbuff_t *tvb, gint offset, guint32 ip, int isdst)
+add_geoip_info_entry(proto_tree *tree, tvbuff_t *tvb, gint offset, guint32 ip, int isdst)
{
- guint num_dbs = geoip_db_num_dbs();
- guint item_cnt = 0;
- guint dbnum;
+ const mmdb_lookup_t *lookup = maxmind_db_lookup_ipv4(ip);
+ if (!lookup->found) return;
- for (dbnum = 0; dbnum < num_dbs; dbnum++) {
- char *geoip_str = geoip_db_lookup_ipv4(dbnum, ip, NULL);
- int db_type = geoip_db_type(dbnum);
+ wmem_strbuf_t *summary = wmem_strbuf_new(wmem_packet_scope(), "");
+ if (lookup->city) {
+ wmem_strbuf_append(summary, lookup->city);
+ }
+ if (lookup->country) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append(summary, lookup->country);
+ }
+ if (lookup->as_number > 0) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append_printf(summary, "ASN %u", lookup->as_number);
+ }
+ if (lookup->as_org) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append(summary, lookup->as_org);
+ }
- int geoip_hf, geoip_local_hf;
+ int addr_offset = offset + isdst ? IPH_DST : IPH_SRC;
+ int dir_hf = isdst ? hf_geoip_dst_summary : hf_geoip_src_summary;
+ proto_item *geoip_info_item = proto_tree_add_string(tree, dir_hf, tvb, addr_offset, 4, wmem_strbuf_finalize(summary));
+ PROTO_ITEM_SET_GENERATED(geoip_info_item);
+ proto_tree *geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
- switch (db_type) {
- case GEOIP_COUNTRY_EDITION:
- geoip_hf = hf_geoip_country;
- geoip_local_hf = (isdst) ? hf_geoip_dst_country : hf_geoip_src_country;
- break;
- case GEOIP_CITY_EDITION_REV0:
- geoip_hf = hf_geoip_city;
- geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
- break;
- case GEOIP_CITY_EDITION_REV1:
- geoip_hf = hf_geoip_city;
- geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
- break;
- case GEOIP_ORG_EDITION:
- geoip_hf = hf_geoip_org;
- geoip_local_hf = (isdst) ? hf_geoip_dst_org : hf_geoip_src_org;
- break;
- case GEOIP_ISP_EDITION:
- geoip_hf = hf_geoip_isp;
- geoip_local_hf = (isdst) ? hf_geoip_dst_isp : hf_geoip_src_isp;
- break;
- case GEOIP_ASNUM_EDITION:
- geoip_hf = hf_geoip_asnum;
- geoip_local_hf = (isdst) ? hf_geoip_dst_asnum : hf_geoip_src_asnum;
- break;
- case WS_LAT_FAKE_EDITION:
- geoip_hf = hf_geoip_lat;
- geoip_local_hf = (isdst) ? hf_geoip_dst_lat : hf_geoip_src_lat;
- break;
- case WS_LON_FAKE_EDITION:
- geoip_hf = hf_geoip_lon;
- geoip_local_hf = (isdst) ? hf_geoip_dst_lon : hf_geoip_src_lon;
- break;
- default:
- continue;
- }
+ proto_item *item;
- if (geoip_str) {
- proto_item *item;
- if (db_type == WS_LAT_FAKE_EDITION || db_type == WS_LON_FAKE_EDITION) {
- /* Convert latitude, longitude to double. Fix bug #5077 */
- item = proto_tree_add_double_format_value(geoip_info_tree, geoip_local_hf,
- tvb, offset, 4, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- item = proto_tree_add_double_format_value(geoip_info_tree, geoip_hf,
- tvb, offset, 4, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- PROTO_ITEM_SET_HIDDEN(item);
- } else {
- item = proto_tree_add_string(geoip_info_tree, geoip_local_hf,
- tvb, offset, 4, geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- item = proto_tree_add_string(geoip_info_tree, geoip_hf,
- tvb, offset, 4, geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- PROTO_ITEM_SET_HIDDEN(item);
- }
+ if (lookup->city) {
+ dir_hf = isdst ? hf_geoip_dst_city : hf_geoip_src_city;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->city);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_city, tvb, addr_offset, 4, lookup->city);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
- item_cnt++;
- proto_item_append_text(geoip_info_item, "%s%s",
- plurality(item_cnt, "", ", "), geoip_str);
- wmem_free(NULL, geoip_str);
- }
+ if (lookup->country) {
+ dir_hf = isdst ? hf_geoip_dst_country : hf_geoip_src_country;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->country);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_country, tvb, addr_offset, 4, lookup->country);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->as_number > 0) {
+ dir_hf = isdst ? hf_geoip_dst_as_number : hf_geoip_src_as_number;
+ item = proto_tree_add_uint(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->as_number);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(geoip_info_tree, hf_geoip_as_number, tvb, addr_offset, 4, lookup->as_number);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->as_org) {
+ dir_hf = isdst ? hf_geoip_dst_as_org : hf_geoip_src_as_org;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->as_org);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_as_org, tvb, addr_offset, 4, lookup->as_org);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0) {
+ dir_hf = isdst ? hf_geoip_dst_latitude : hf_geoip_src_latitude;
+ item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->latitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_double(geoip_info_tree, hf_geoip_latitude, tvb, addr_offset, 4, lookup->latitude);
+ PROTO_ITEM_SET_GENERATED(item);
}
- if (item_cnt == 0)
- proto_item_append_text(geoip_info_item, "Unknown");
+ if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0) {
+ dir_hf = isdst ? hf_geoip_dst_longitude : hf_geoip_src_longitude;
+ item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 4, lookup->longitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_double(geoip_info_tree, hf_geoip_longitude, tvb, addr_offset, 4, lookup->longitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
}
static void
add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, guint32 src32,
guint32 dst32)
{
- guint num_dbs;
- proto_item *geoip_info_item;
- proto_tree *geoip_info_tree;
-
- num_dbs = geoip_db_num_dbs();
- if (num_dbs < 1)
- return;
-
- geoip_info_tree = proto_tree_add_subtree(tree, tvb, offset + IPH_SRC, 4, ett_geoip_info, &geoip_info_item, "Source GeoIP: ");
- PROTO_ITEM_SET_GENERATED(geoip_info_item);
- add_geoip_info_entry(geoip_info_tree, geoip_info_item, tvb, offset + IPH_SRC, src32, 0);
-
- geoip_info_tree = proto_tree_add_subtree(tree, tvb, offset + IPH_DST, 4, ett_geoip_info, &geoip_info_item, "Destination GeoIP: ");
- PROTO_ITEM_SET_GENERATED(geoip_info_item);
- add_geoip_info_entry(geoip_info_tree, geoip_info_item, tvb, offset + IPH_DST, dst32, 1);
+ add_geoip_info_entry(tree, tvb, offset, g_htonl(src32), FALSE);
+ add_geoip_info_entry(tree, tvb, offset, g_htonl(dst32), TRUE);
}
-#endif /* HAVE_GEOIP */
const value_string ipopt_type_class_vals[] = {
{(IPOPT_CONTROL & IPOPT_CLASS_MASK) >> 5, "Control"},
@@ -2206,13 +2178,11 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
PROTO_ITEM_SET_GENERATED(item);
PROTO_ITEM_SET_HIDDEN(item);
}
- }
-#ifdef HAVE_GEOIP
- if (tree && ip_use_geoip) {
- add_geoip_info(ip_tree, tvb, offset, src32, dst32);
+ if (ip_use_geoip) {
+ add_geoip_info(ip_tree, tvb, offset, src32, dst32);
+ }
}
-#endif
/* Decode IP options, if any. */
if (hlen > IPH_MIN_LEN) {
@@ -2522,71 +2492,66 @@ proto_register_ip(void)
{ "Source or Destination Host", "ip.host", FT_STRING, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
-#ifdef HAVE_GEOIP
{ &hf_geoip_country,
{ "Source or Destination GeoIP Country", "ip.geoip.country",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
{ &hf_geoip_city,
{ "Source or Destination GeoIP City", "ip.geoip.city",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_org,
- { "Source or Destination GeoIP Organization", "ip.geoip.org",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_isp,
- { "Source or Destination GeoIP ISP", "ip.geoip.isp",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_asnum,
+ { &hf_geoip_as_number,
{ "Source or Destination GeoIP AS Number", "ip.geoip.asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_geoip_as_org,
+ { "Source or Destination GeoIP AS Organization", "ip.geoip.org",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_lat,
+ { &hf_geoip_latitude,
{ "Source or Destination GeoIP Latitude", "ip.geoip.lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_lon,
+ { &hf_geoip_longitude,
{ "Source or Destination GeoIP Longitude", "ip.geoip.lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_geoip_src_summary,
+ { "Source GeoIP", "ip.geoip.src_summary",
+ FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
{ &hf_geoip_src_country,
{ "Source GeoIP Country", "ip.geoip.src_country",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
{ &hf_geoip_src_city,
{ "Source GeoIP City", "ip.geoip.src_city",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_src_org,
- { "Source GeoIP Organization", "ip.geoip.src_org",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_src_isp,
- { "Source GeoIP ISP", "ip.geoip.src_isp",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_src_asnum,
+ { &hf_geoip_src_as_number,
{ "Source GeoIP AS Number", "ip.geoip.src_asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_geoip_src_as_org,
+ { "Source GeoIP AS Organization", "ip.geoip.src_org",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_src_lat,
+ { &hf_geoip_src_latitude,
{ "Source GeoIP Latitude", "ip.geoip.src_lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_src_lon,
+ { &hf_geoip_src_longitude,
{ "Source GeoIP Longitude", "ip.geoip.src_lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_geoip_dst_summary,
+ { "Destination GeoIP", "ip.geoip.dst_summary",
+ FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
{ &hf_geoip_dst_country,
{ "Destination GeoIP Country", "ip.geoip.dst_country",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
{ &hf_geoip_dst_city,
{ "Destination GeoIP City", "ip.geoip.dst_city",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_dst_org,
- { "Destination GeoIP Organization", "ip.geoip.dst_org",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_dst_isp,
- { "Destination GeoIP ISP", "ip.geoip.dst_isp",
- FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_dst_asnum,
+ { &hf_geoip_dst_as_number,
{ "Destination GeoIP AS Number", "ip.geoip.dst_asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_geoip_dst_as_org,
+ { "Destination GeoIP AS Organization", "ip.geoip.dst_org",
FT_STRING, STR_UNICODE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_dst_lat,
+ { &hf_geoip_dst_latitude,
{ "Destination GeoIP Latitude", "ip.geoip.dst_lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_geoip_dst_lon,
+ { &hf_geoip_dst_longitude,
{ "Destination GeoIP Longitude", "ip.geoip.dst_lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
-#endif /* HAVE_GEOIP */
{ &hf_ip_flags,
{ "Flags", "ip.flags", FT_UINT16, BASE_HEX,
@@ -2906,9 +2871,7 @@ proto_register_ip(void)
&ett_ip_opt_type,
&ett_ip_opt_sec_prot_auth_flags,
&ett_ip_unknown_opt,
-#ifdef HAVE_GEOIP
&ett_geoip_info
-#endif
};
static ei_register_info ei[] = {
{ &ei_ip_opt_len_invalid, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
@@ -2970,12 +2933,10 @@ proto_register_ip(void)
"Support packet-capture from IP TSO-enabled hardware",
"Whether to correct for TSO-enabled (TCP segmentation offload) hardware "
"captures, such as spoofing the IP packet length", &ip_tso_supported);
-#ifdef HAVE_GEOIP
prefs_register_bool_preference(ip_module, "use_geoip",
- "Enable GeoIP lookups",
- "Whether to look up IP addresses in each GeoIP database we have loaded",
+ "Enable IPv4 geolocation",
+ "Whether to look up IP addresses in each MaxMind database we have loaded",
&ip_use_geoip);
-#endif /* HAVE_GEOIP */
prefs_register_bool_preference(ip_module, "security_flag" ,
"Interpret Reserved flag as Security flag (RFC 3514)",
"Whether to interpret the originally reserved flag as security flag",
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index 852cf192a6..40e11edd99 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -20,6 +20,7 @@
#include <epan/expert.h>
#include <epan/ip_opts.h>
#include <epan/addr_resolv.h>
+#include <epan/maxmind_db.h>
#include <epan/prefs.h>
#include <epan/conversation_table.h>
#include <epan/dissector_filters.h>
@@ -43,11 +44,6 @@
#include "packet-mpls.h"
#include "packet-nsh.h"
-#ifdef HAVE_GEOIP_V6
-#include <GeoIP.h>
-#include <epan/geoip_db.h>
-#endif /* HAVE_GEOIP_V6 */
-
void proto_register_ipv6(void);
void proto_reg_handoff_ipv6(void);
@@ -269,29 +265,26 @@ static int hf_ipv6_routing_srh_flag_unused2 = -1;
static int hf_ipv6_routing_srh_reserved = -1;
static int hf_ipv6_routing_srh_addr = -1;
-#ifdef HAVE_GEOIP_V6
static int hf_geoip_country = -1;
static int hf_geoip_city = -1;
-static int hf_geoip_org = -1;
-static int hf_geoip_isp = -1;
-static int hf_geoip_asnum = -1;
-static int hf_geoip_lat = -1;
-static int hf_geoip_lon = -1;
+static int hf_geoip_as_number = -1;
+static int hf_geoip_as_org = -1;
+static int hf_geoip_latitude = -1;
+static int hf_geoip_longitude = -1;
+static int hf_geoip_src_summary = -1;
static int hf_geoip_src_country = -1;
static int hf_geoip_src_city = -1;
-static int hf_geoip_src_org = -1;
-static int hf_geoip_src_isp = -1;
-static int hf_geoip_src_asnum = -1;
-static int hf_geoip_src_lat = -1;
-static int hf_geoip_src_lon = -1;
+static int hf_geoip_src_as_number = -1;
+static int hf_geoip_src_as_org = -1;
+static int hf_geoip_src_latitude = -1;
+static int hf_geoip_src_longitude = -1;
+static int hf_geoip_dst_summary = -1;
static int hf_geoip_dst_country = -1;
static int hf_geoip_dst_city = -1;
-static int hf_geoip_dst_org = -1;
-static int hf_geoip_dst_isp = -1;
-static int hf_geoip_dst_asnum = -1;
-static int hf_geoip_dst_lat = -1;
-static int hf_geoip_dst_lon = -1;
-#endif /* HAVE_GEOIP_V6 */
+static int hf_geoip_dst_as_number = -1;
+static int hf_geoip_dst_as_org = -1;
+static int hf_geoip_dst_latitude = -1;
+static int hf_geoip_dst_longitude = -1;
static gint ett_ipv6_proto = -1;
static gint ett_ipv6_traffic_class = -1;
@@ -309,9 +302,7 @@ static gint ett_ipv6_fragments = -1;
static gint ett_ipv6_fragment = -1;
static gint ett_ipv6_dstopts_proto = -1;
-#ifdef HAVE_GEOIP_V6
static gint ett_geoip_info = -1;
-#endif /* HAVE_GEOIP_V6 */
static expert_field ei_ipv6_routing_invalid_length = EI_INIT;
static expert_field ei_ipv6_routing_invalid_segleft = EI_INIT;
@@ -523,10 +514,8 @@ static gboolean ipv6_reassemble = TRUE;
/* Place IPv6 summary in proto tree */
static gboolean ipv6_summary_in_tree = TRUE;
-#ifdef HAVE_GEOIP_V6
-/* Look up addresses in GeoIP */
+/* Look up addresses via mmdbresolve */
static gboolean ipv6_use_geoip = TRUE;
-#endif /* HAVE_GEOIP_V6 */
/* Perform strict RFC adherence checking */
static gboolean g_ipv6_rpl_srh_strict_rfc_checking = FALSE;
@@ -713,107 +702,92 @@ capture_ipv6_exthdr(const guchar *pd, int offset, int len, capture_packet_info_t
return try_capture_dissector("ip.proto", nxt, pd, offset, len, cpinfo, pseudo_header);
}
-#ifdef HAVE_GEOIP_V6
static void
-add_geoip_info_entry(proto_tree *geoip_info_tree, proto_item *geoip_info_item, tvbuff_t *tvb, gint offset, const ws_in6_addr *ip, int isdst)
+add_geoip_info_entry(proto_tree *tree, tvbuff_t *tvb, gint offset, const ws_in6_addr *ip6, int isdst)
{
- guint num_dbs = geoip_db_num_dbs();
- guint item_cnt = 0;
- guint dbnum;
+ const mmdb_lookup_t *lookup = maxmind_db_lookup_ipv6(ip6);
+ if (!lookup->found) return;
- for (dbnum = 0; dbnum < num_dbs; dbnum++) {
- char *geoip_str = geoip_db_lookup_ipv6(dbnum, *ip, NULL);
- int db_type = geoip_db_type(dbnum);
+ wmem_strbuf_t *summary = wmem_strbuf_new(wmem_packet_scope(), "");
+ if (lookup->city) {
+ wmem_strbuf_append(summary, lookup->city);
+ }
+ if (lookup->country) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append(summary, lookup->country);
+ }
+ if (lookup->as_number > 0) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append_printf(summary, "ASN %u", lookup->as_number);
+ }
+ if (lookup->as_org) {
+ if (wmem_strbuf_get_len(summary) > 0) wmem_strbuf_append(summary, ", ");
+ wmem_strbuf_append(summary, lookup->as_org);
+ }
- int geoip_hf, geoip_local_hf;
+ int addr_offset = offset + isdst ? IP6H_DST : IP6H_SRC;
+ int dir_hf = isdst ? hf_geoip_dst_summary : hf_geoip_src_summary;
+ proto_item *geoip_info_item = proto_tree_add_string(tree, dir_hf, tvb, addr_offset, 16, wmem_strbuf_finalize(summary));
+ PROTO_ITEM_SET_GENERATED(geoip_info_item);
+ proto_tree *geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
- switch (db_type) {
- case GEOIP_COUNTRY_EDITION_V6:
- geoip_hf = hf_geoip_country;
- geoip_local_hf = (isdst) ? hf_geoip_dst_country : hf_geoip_src_country;
- break;
-#if NUM_DB_TYPES > 31
- case GEOIP_CITY_EDITION_REV0_V6:
- case GEOIP_CITY_EDITION_REV1_V6:
- geoip_hf = hf_geoip_city;
- geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
- break;
- case GEOIP_ORG_EDITION_V6:
- geoip_hf = hf_geoip_org;
- geoip_local_hf = (isdst) ? hf_geoip_dst_org : hf_geoip_src_org;
- break;
- case GEOIP_ISP_EDITION_V6:
- geoip_hf = hf_geoip_isp;
- geoip_local_hf = (isdst) ? hf_geoip_dst_isp : hf_geoip_src_isp;
- break;
- case GEOIP_ASNUM_EDITION_V6:
- geoip_hf = hf_geoip_asnum;
- geoip_local_hf = (isdst) ? hf_geoip_dst_asnum : hf_geoip_src_asnum;
- break;
-#endif /* DB_NUM_TYPES */
- case WS_LAT_FAKE_EDITION:
- geoip_hf = hf_geoip_lat;
- geoip_local_hf = (isdst) ? hf_geoip_dst_lat : hf_geoip_src_lat;
- break;
- case WS_LON_FAKE_EDITION:
- geoip_hf = hf_geoip_lon;
- geoip_local_hf = (isdst) ? hf_geoip_dst_lon : hf_geoip_src_lon;
- break;
- default:
- continue;
- }
+ proto_item *item;
- if (geoip_str) {
- proto_item *item;
- if (db_type == WS_LAT_FAKE_EDITION || db_type == WS_LON_FAKE_EDITION) {
- /* Convert latitude, longitude to double. Fix bug #5077 */
- item = proto_tree_add_double_format_value(geoip_info_tree, geoip_local_hf, tvb,
- offset, 16, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- item = proto_tree_add_double_format_value(geoip_info_tree, geoip_hf, tvb,
- offset, 16, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- PROTO_ITEM_SET_HIDDEN(item);
- } else {
- item = proto_tree_add_string(geoip_info_tree, geoip_local_hf, tvb,
- offset, 16, geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- item = proto_tree_add_string(geoip_info_tree, geoip_hf, tvb,
- offset, 16, geoip_str);
- PROTO_ITEM_SET_GENERATED(item);
- PROTO_ITEM_SET_HIDDEN(item);
- }
+ if (lookup->city) {
+ dir_hf = isdst ? hf_geoip_dst_city : hf_geoip_src_city;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->city);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_city, tvb, addr_offset, 16, lookup->city);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
- item_cnt++;
- proto_item_append_text(geoip_info_item, "%s%s", plurality(item_cnt, "", ", "), geoip_str);
- wmem_free(NULL, geoip_str);
- }
+ if (lookup->country) {
+ dir_hf = isdst ? hf_geoip_dst_country : hf_geoip_src_country;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->country);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_country, tvb, addr_offset, 16, lookup->country);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->as_number > 0) {
+ dir_hf = isdst ? hf_geoip_dst_as_number : hf_geoip_src_as_number;
+ item = proto_tree_add_uint(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->as_number);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(geoip_info_tree, hf_geoip_as_number, tvb, addr_offset, 16, lookup->as_number);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->as_org) {
+ dir_hf = isdst ? hf_geoip_dst_as_org : hf_geoip_src_as_org;
+ item = proto_tree_add_string(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->as_org);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_string(geoip_info_tree, hf_geoip_as_org, tvb, addr_offset, 16, lookup->as_org);
+ PROTO_ITEM_SET_GENERATED(item);
}
- if (item_cnt == 0)
- proto_item_append_text(geoip_info_item, "Unknown");
+ if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0) {
+ dir_hf = isdst ? hf_geoip_dst_latitude : hf_geoip_src_latitude;
+ item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->latitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_double(geoip_info_tree, hf_geoip_latitude, tvb, addr_offset, 16, lookup->latitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0) {
+ dir_hf = isdst ? hf_geoip_dst_longitude : hf_geoip_src_longitude;
+ item = proto_tree_add_double(geoip_info_tree, dir_hf, tvb, addr_offset, 16, lookup->longitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_double(geoip_info_tree, hf_geoip_longitude, tvb, addr_offset, 16, lookup->longitude);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
}
static void
add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, const ws_in6_addr *src, const ws_in6_addr *dst)
{
- guint num_dbs;
- proto_item *geoip_info_item;
- proto_tree *geoip_info_tree;
-
- num_dbs = geoip_db_num_dbs();
- if (num_dbs < 1)
- return;
-
- geoip_info_tree = proto_tree_add_subtree(tree, tvb, offset + IP6H_SRC, 16, ett_geoip_info, &geoip_info_item, "Source GeoIP: ");
- PROTO_ITEM_SET_GENERATED(geoip_info_item);
- add_geoip_info_entry(geoip_info_tree, geoip_info_item, tvb, offset + IP6H_SRC, src, 0);
-
- geoip_info_tree = proto_tree_add_subtree(tree, tvb, offset + IP6H_DST, 16, ett_geoip_info, &geoip_info_item, "Destination GeoIP: ");
- PROTO_ITEM_SET_GENERATED(geoip_info_item);
- add_geoip_info_entry(geoip_info_tree, geoip_info_item, tvb, offset + IP6H_DST, dst, 1);
+ add_geoip_info_entry(tree, tvb, offset, src, FALSE);
+ add_geoip_info_entry(tree, tvb, offset, dst, TRUE);
}
-#endif /* HAVE_GEOIP_V6 */
/* Returns TRUE if reassembled */
static gboolean
@@ -2365,13 +2339,11 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
add_ipv6_address_embed_ipv4(ipv6_tree, tvb, offset + IP6H_SRC, hf_ipv6_src_embed_ipv4);
add_ipv6_address_embed_ipv4(ipv6_tree, tvb, offset + IP6H_DST, hf_ipv6_dst_embed_ipv4);
- }
-#ifdef HAVE_GEOIP_V6
- if (tree && ipv6_use_geoip) {
- add_geoip_info(ipv6_tree, tvb, offset, ip6_src, ip6_dst);
+ if (ipv6_use_geoip) {
+ add_geoip_info(ipv6_tree, tvb, offset, ip6_src, ip6_dst);
+ }
}
-#endif
/* Increment offset to point to next header (may be an extension header) */
offset += IPv6_HDR_SIZE;
@@ -2675,7 +2647,6 @@ proto_register_ipv6(void)
"IPv4-Embedded IPv6 Address with Well-Known Prefix", HFILL }
},
-#ifdef HAVE_GEOIP_V6
{ &hf_geoip_country,
{ "Source or Destination GeoIP Country", "ipv6.geoip.country",
FT_STRING, STR_UNICODE, NULL, 0x0,
@@ -2686,31 +2657,31 @@ proto_register_ipv6(void)
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_org,
- { "Source or Destination GeoIP Organization", "ipv6.geoip.org",
- FT_STRING, STR_UNICODE, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_geoip_isp,
- { "Source or Destination GeoIP ISP", "ipv6.geoip.isp",
- FT_STRING, STR_UNICODE, NULL, 0x0,
+ { &hf_geoip_as_number,
+ { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_asnum,
- { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum",
+ { &hf_geoip_as_org,
+ { "Source or Destination GeoIP AS Organization", "ipv6.geoip.org",
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_lat,
+ { &hf_geoip_latitude,
{ "Source or Destination GeoIP Latitude", "ipv6.geoip.lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_lon,
+ { &hf_geoip_longitude,
{ "Source or Destination GeoIP Longitude", "ipv6.geoip.lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_geoip_src_summary,
+ { "Source GeoIP", "ipv6.geoip.src_summary",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_geoip_src_country,
{ "Source GeoIP Country", "ipv6.geoip.src_country",
FT_STRING, STR_UNICODE, NULL, 0x0,
@@ -2721,31 +2692,31 @@ proto_register_ipv6(void)
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_src_org,
- { "Source GeoIP Organization", "ipv6.geoip.src_org",
- FT_STRING, STR_UNICODE, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_geoip_src_isp,
- { "Source GeoIP ISP", "ipv6.geoip.src_isp",
- FT_STRING, STR_UNICODE, NULL, 0x0,
+ { &hf_geoip_src_as_number,
+ { "Source GeoIP AS Number", "ipv6.geoip.src_asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_src_asnum,
- { "Source GeoIP AS Number", "ipv6.geoip.src_asnum",
+ { &hf_geoip_src_as_org,
+ { "Source GeoIP AS Organization", "ipv6.geoip.src_org",
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_src_lat,
+ { &hf_geoip_src_latitude,
{ "Source GeoIP Latitude", "ipv6.geoip.src_lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_src_lon,
+ { &hf_geoip_src_longitude,
{ "Source GeoIP Longitude", "ipv6.geoip.src_lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_geoip_dst_summary,
+ { "Destination GeoIP", "ipv6.geoip.dst_summary",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_geoip_dst_country,
{ "Destination GeoIP Country", "ipv6.geoip.dst_country",
FT_STRING, STR_UNICODE, NULL, 0x0,
@@ -2756,32 +2727,26 @@ proto_register_ipv6(void)
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_dst_org,
- { "Destination GeoIP Organization", "ipv6.geoip.dst_org",
- FT_STRING, STR_UNICODE, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_geoip_dst_isp,
- { "Destination GeoIP ISP", "ipv6.geoip.dst_isp",
- FT_STRING, STR_UNICODE, NULL, 0x0,
+ { &hf_geoip_dst_as_number,
+ { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_dst_asnum,
- { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum",
+ { &hf_geoip_dst_as_org,
+ { "Destination GeoIP AS Organization", "ipv6.geoip.dst_org",
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_dst_lat,
+ { &hf_geoip_dst_latitude,
{ "Destination GeoIP Latitude", "ipv6.geoip.dst_lat",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_geoip_dst_lon,
+ { &hf_geoip_dst_longitude,
{ "Destination GeoIP Longitude", "ipv6.geoip.dst_lon",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
-#endif /* HAVE_GEOIP_V6 */
{ &hf_ipv6_opt,
{ "IPv6 Option", "ipv6.opt",
@@ -3369,9 +3334,7 @@ proto_register_ipv6(void)
static gint *ett_ipv6[] = {
&ett_ipv6_proto,
&ett_ipv6_traffic_class,
-#ifdef HAVE_GEOIP_V6
&ett_geoip_info,
-#endif /* HAVE_GEOIP_V6 */
&ett_ipv6_opt,
&ett_ipv6_opt_type,
&ett_ipv6_opt_rpl,
@@ -3576,12 +3539,10 @@ proto_register_ipv6(void)
"Show IPv6 summary in protocol tree",
"Whether the IPv6 summary line should be shown in the protocol tree",
&ipv6_summary_in_tree);
-#ifdef HAVE_GEOIP_V6
prefs_register_bool_preference(ipv6_module, "use_geoip" ,
- "Enable GeoIP lookups",
- "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
+ "Enable IPv6 geolocation",
+ "Whether to look up IPv6 addresses in each MaxMind database we have loaded",
&ipv6_use_geoip);
-#endif /* HAVE_GEOIP_V6 */
/* RPL Strict Header Checking */
prefs_register_bool_preference(ipv6_module, "perform_strict_rpl_srh_rfc_checking",
diff --git a/epan/epan.c b/epan/epan.c
index 076b557b5a..a1a9240a81 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -727,13 +727,13 @@ epan_get_compiled_version_info(GString *str)
g_string_append(str, "without Kerberos");
#endif /* HAVE_KERBEROS */
- /* GeoIP */
+ /* MaxMindDB */
g_string_append(str, ", ");
-#ifdef HAVE_GEOIP
- g_string_append(str, "with GeoIP");
+#ifdef HAVE_MAXMINDDB
+ g_string_append(str, "with MaxMind DB resolver");
#else
- g_string_append(str, "without GeoIP");
-#endif /* HAVE_GEOIP */
+ g_string_append(str, "without MaxMind DB resolver");
+#endif /* HAVE_MAXMINDDB */
/* nghttp2 */
g_string_append(str, ", ");
diff --git a/epan/geoip_db.c b/epan/geoip_db.c
deleted file mode 100644
index f79b0f677b..0000000000
--- a/epan/geoip_db.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/* geoip_db.c
- * GeoIP database support
- *
- * Copyright 2008, Gerald Combs <gerald@wireshark.org>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-/* To do:
- * We currently return a single string for each database. Some databases,
- * e.g. GeoIPCity, can return other info such as area codes.
- */
-
-#include "config.h"
-
-#include <glib.h>
-
-#include <epan/wmem/wmem.h>
-
-#ifdef HAVE_GEOIP
-#include <GeoIP.h>
-#include <GeoIPCity.h>
-
-#include <epan/geoip_db.h>
-#include <epan/uat.h>
-#include <epan/prefs.h>
-#include <epan/value_string.h>
-
-#include <wsutil/report_message.h>
-#include <wsutil/file_util.h>
-
-/* This needs to match NUM_GEOIP_COLS in hostlist_table.h */
-#define MAX_GEOIP_DBS 13
-
-/*
- * GeoIP_free is patched into our GeoIP distribution on Windows.
- * See bug 13598.
- */
-#ifndef HAVE_GEOIP_FREE
-#define GeoIP_free free
-#endif
-
-/* Column names for each database type */
-value_string geoip_type_name_vals[] = {
- { GEOIP_COUNTRY_EDITION, "Country" },
- { GEOIP_REGION_EDITION_REV0, "Region" },
- { GEOIP_CITY_EDITION_REV0, "City"},
- { GEOIP_ORG_EDITION, "Organization" },
- { GEOIP_ISP_EDITION, "ISP" },
- { GEOIP_CITY_EDITION_REV1, "City" },
- { GEOIP_REGION_EDITION_REV1, "Region" },
- { GEOIP_PROXY_EDITION, "Proxy" },
- { GEOIP_ASNUM_EDITION, "AS Number" },
- { GEOIP_NETSPEED_EDITION, "Speed" },
- { GEOIP_DOMAIN_EDITION, "Domain" },
-#ifdef HAVE_GEOIP_V6
- { GEOIP_COUNTRY_EDITION_V6, "Country" },
-/* This is the closest thing to a version that GeoIP.h seems to provide. */
-#if NUM_DB_TYPES > 31 /* 1.4.7 */
- { GEOIP_CITY_EDITION_REV0_V6, "City"},
- { GEOIP_CITY_EDITION_REV1_V6, "City"},
- { GEOIP_ASNUM_EDITION_V6, "AS Number" },
- { GEOIP_ISP_EDITION_V6, "ISP" },
- { GEOIP_ORG_EDITION_V6, "Organization" },
- { GEOIP_DOMAIN_EDITION_V6, "Domain" },
-#endif /* NUM_DB_TYPES > 31 */
-#if NUM_DB_TYPES > 32 /* 1.4.8 */
- { GEOIP_NETSPEED_EDITION_REV1_V6, "Speed" },
-#endif /* NUM_DB_TYPES > 32 */
-#endif /* HAVE_GEOIP_V6 */
- { WS_LAT_FAKE_EDITION, "Latitude" }, /* fake database */
- { WS_LON_FAKE_EDITION, "Longitude" }, /* fake database */
- { 0, NULL }
-};
-
-static GArray *geoip_dat_arr = NULL;
-
-/* UAT definitions. Copied from oids.c */
-typedef struct _geoip_db_path_t {
- char* path;
-} geoip_db_path_t;
-
-static geoip_db_path_t *geoip_db_paths = NULL;
-static guint num_geoip_db_paths = 0;
-static const geoip_db_path_t geoip_db_system_paths[] = {
-#ifdef G_OS_UNIX
- { "/usr/share/GeoIP" },
-#endif
- { NULL }
-};
-static uat_t *geoip_db_paths_uat = NULL;
-UAT_DIRECTORYNAME_CB_DEF(geoip_mod, path, geoip_db_path_t)
-
-
-/**
- * Scan a directory for GeoIP databases and load them
- */
-static void
-geoip_dat_scan_dir(const char *dirname) {
- WS_DIR *dir;
- WS_DIRENT *file;
- const char *name;
- char *datname;
- GeoIP *gi;
-
- if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) {
- while ((file = ws_dir_read_name(dir)) != NULL) {
- name = ws_dir_get_name(file);
- if (g_str_has_prefix(file, "Geo") && g_str_has_suffix(file, ".dat")) {
- datname = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dirname, name);
- gi = GeoIP_open(datname, GEOIP_MEMORY_CACHE);
- if (gi) {
- g_array_append_val(geoip_dat_arr, gi);
- }
- g_free(datname);
- }
- }
- ws_dir_close (dir);
- }
-}
-
-/* UAT callbacks */
-static void* geoip_db_path_copy_cb(void* dest, const void* orig, size_t len _U_) {
- const geoip_db_path_t *m = (const geoip_db_path_t *)orig;
- geoip_db_path_t *d = (geoip_db_path_t *)dest;
-
- d->path = g_strdup(m->path);
-
- return d;
-}
-
-static void geoip_db_path_free_cb(void* p) {
- geoip_db_path_t *m = (geoip_db_path_t *)p;
- g_free(m->path);
-}
-
-static void geoip_dat_cleanup(void) {
- GeoIP *gi;
- guint i;
-
- /* If we have old data, clear out the whole thing
- * and start again. TODO: Just update the ones that
- * have changed for efficiency's sake. */
- if (geoip_dat_arr) {
- /* skip the last two, as they are fake */
- for (i = 0; i < geoip_db_num_dbs() - 2; i++) {
- gi = g_array_index(geoip_dat_arr, GeoIP *, i);
- if (gi) {
- GeoIP_delete(gi);
- }
- }
- /* don't use GeoIP_delete() on the two fake
- * databases as they weren't created by GeoIP_new()
- * or GeoIP_open() */
- gi = g_array_index(geoip_dat_arr, GeoIP *, i);
- g_free(gi);
- gi = g_array_index(geoip_dat_arr, GeoIP *, i+1);
- g_free(gi);
- /* finally, free the array itself */
- g_array_free(geoip_dat_arr, TRUE);
- geoip_dat_arr = NULL;
- }
-}
-
-/* called every time the user presses "Apply" or "OK in the list of
- * GeoIP directories, and also once on startup */
-static void geoip_db_post_update_cb(void) {
- guint i;
- GeoIP* gi;
-
- geoip_dat_cleanup();
-
- /* allocate the array */
- geoip_dat_arr = g_array_new(FALSE, FALSE, sizeof(GeoIP *));
-
- /* First try the system paths */
- for (i = 0; geoip_db_system_paths[i].path != NULL; i++) {
- geoip_dat_scan_dir(geoip_db_system_paths[i].path);
- }
-
- /* Walk all the directories */
- for (i = 0; i < num_geoip_db_paths; i++) {
- if (geoip_db_paths[i].path) {
- geoip_dat_scan_dir(geoip_db_paths[i].path);
- }
- }
-
- /* add fake databases for latitude and longitude
- * (using "City" in reality) */
-
- /* latitude */
- gi = (GeoIP *)g_malloc(sizeof (GeoIP));
- gi->databaseType = WS_LAT_FAKE_EDITION;
- g_array_append_val(geoip_dat_arr, gi);
-
- /* longitude */
- gi = (GeoIP *)g_malloc(sizeof (GeoIP));
- gi->databaseType = WS_LON_FAKE_EDITION;
- g_array_append_val(geoip_dat_arr, gi);
-}
-
-static void geoip_db_cleanup(void)
-{
- geoip_dat_cleanup();
-}
-
-/**
- * Initialize GeoIP lookups
- */
-void
-geoip_db_pref_init(module_t *nameres)
-{
- static uat_field_t geoip_db_paths_fields[] = {
- UAT_FLD_DIRECTORYNAME(geoip_mod, path, "GeoIP Database Directory", "The GeoIP database directory path"),
- UAT_END_FIELDS
- };
-
- geoip_db_paths_uat = uat_new("GeoIP Database Paths",
- sizeof(geoip_db_path_t),
- "geoip_db_paths",
- FALSE,
- (void**)&geoip_db_paths,
- &num_geoip_db_paths,
- /* affects dissection of packets (as the GeoIP database is
- used when dissecting), but not set of named fields */
- UAT_AFFECTS_DISSECTION,
- "ChGeoIPDbPaths",
- geoip_db_path_copy_cb,
- NULL,
- geoip_db_path_free_cb,
- geoip_db_post_update_cb,
- geoip_db_cleanup,
- geoip_db_paths_fields);
-
- prefs_register_uat_preference(nameres,
- "geoip_db_paths",
- "GeoIP database directories",
- "Search paths for GeoIP address mapping databases."
- " Wireshark will look in each directory for files beginning"
- " with \"Geo\" and ending with \".dat\".",
- geoip_db_paths_uat);
-}
-
-guint
-geoip_db_num_dbs(void) {
- return (geoip_dat_arr == NULL) ? 0 : geoip_dat_arr->len;
-}
-
-const gchar *
-geoip_db_name(guint dbnum) {
- GeoIP *gi;
-
- gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
- if (gi) {
- return (val_to_str_const(gi->databaseType, geoip_type_name_vals, "Unknown database"));
- }
- return "Invalid database";
-}
-
-int
-geoip_db_type(guint dbnum) {
- GeoIP *gi;
-
- gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
- if (gi) {
- return (gi->databaseType);
- }
- return -1;
-}
-
-static int
-geoip_db_lookup_latlon4(guint32 addr, float *lat, float *lon) {
- GeoIP *gi;
- GeoIPRecord *gir;
- guint i;
-
- for (i = 0; i < geoip_db_num_dbs(); i++) {
- gi = g_array_index(geoip_dat_arr, GeoIP *, i);
- if (gi) {
- switch (gi->databaseType) {
- case GEOIP_CITY_EDITION_REV0:
- case GEOIP_CITY_EDITION_REV1:
- gir = GeoIP_record_by_ipnum(gi, addr);
- if (gir) {
- *lat = gir->latitude;
- *lon = gir->longitude;
- GeoIPRecord_delete(gir);
- return 0;
- }
- return -1;
- /*break;*/
-
- default:
- break;
- }
- }
- }
- return -1;
-}
-
-/*
- * GeoIP 1.4.3 and later provide GeoIP_set_charset(), but in versions
- * 1.4.3 to 1.4.6 that only applies to the City databases. I.e., it's
- * possible to produce invalid UTF-8 sequences even if GeoIP_set_charset()
- * is used.
- */
-
-/* Ensure that a given db value is UTF-8 */
-static char *
-db_val_to_utf_8(const char *val, GeoIP *gi) {
-
- if (GeoIP_charset(gi) == GEOIP_CHARSET_ISO_8859_1) {
- char *utf8_val;
- utf8_val = g_convert(val, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
- if (utf8_val) {
- char *ret_val = wmem_strdup(NULL, utf8_val);
- g_free(utf8_val);
- return ret_val;
- }
- }
- return wmem_strdup(NULL, val);
-}
-
-char *
-geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found) {
- GeoIP *gi;
- GeoIPRecord *gir;
- char *name;
- const char *country;
- char *val, *ret = NULL;
-
- if (dbnum > geoip_db_num_dbs()) {
- if (not_found == NULL)
- return NULL;
-
- return wmem_strdup(NULL, not_found);
- }
- gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
- if (gi) {
- switch (gi->databaseType) {
- case GEOIP_COUNTRY_EDITION:
- country = GeoIP_country_name_by_ipnum(gi, addr);
- if (country) {
- ret = db_val_to_utf_8(country, gi);
- }
- break;
-
- case GEOIP_CITY_EDITION_REV0:
- case GEOIP_CITY_EDITION_REV1:
- gir = GeoIP_record_by_ipnum(gi, addr);
- if (gir && gir->city && gir->region) {
- val = wmem_strdup_printf(NULL, "%s, %s", gir->city, gir->region);
- ret = db_val_to_utf_8(val, gi);
- wmem_free(NULL, val);
- } else if (gir && gir->city) {
- ret = db_val_to_utf_8(gir->city, gi);
- }
- if (gir)
- GeoIPRecord_delete(gir);
- break;
-
- case GEOIP_ORG_EDITION:
- case GEOIP_ISP_EDITION:
- case GEOIP_ASNUM_EDITION:
- name = GeoIP_name_by_ipnum(gi, addr);
- if (name) {
- ret = db_val_to_utf_8(name, gi);
- GeoIP_free(name);
- }
- break;
-
- case WS_LAT_FAKE_EDITION:
- {
- float lat;
- float lon;
- char *c;
- if(geoip_db_lookup_latlon4(addr, &lat, &lon) == 0) {
- val = wmem_strdup_printf(NULL, "%f", lat);
- c = strchr(val, ',');
- if (c != NULL) *c = '.';
- ret = val;
- }
- }
- break;
-
- case WS_LON_FAKE_EDITION:
- {
- float lat;
- float lon;
- char *c;
- if(geoip_db_lookup_latlon4(addr, &lat, &lon) == 0) {
- val = wmem_strdup_printf(NULL, "%f", lon);
- c = strchr(val, ',');
- if (c != NULL) *c = '.';
- ret = val;
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- if (ret == NULL) {
- if (not_found == NULL)
- return NULL;
-
- return wmem_strdup(NULL, not_found);
- }
-
- return ret;
-}
-
-#ifdef HAVE_GEOIP_V6
-
-static int
-#if NUM_DB_TYPES > 31 /* 1.4.7 */
-geoip_db_lookup_latlon6(geoipv6_t addr, float *lat, float *lon) {
- GeoIP *gi;
- GeoIPRecord *gir;
- guint i;
-
- for (i = 0; i < geoip_db_num_dbs(); i++) {
- gi = g_array_index(geoip_dat_arr, GeoIP *, i);
- if (gi) {
- switch (gi->databaseType) {
- case GEOIP_CITY_EDITION_REV0_V6:
- case GEOIP_CITY_EDITION_REV1_V6:
- gir = GeoIP_record_by_ipnum_v6(gi, addr);
- if(gir) {
- *lat = gir->latitude;
- *lon = gir->longitude;
- return 0;
- }
- return -1;
- /*break;*/
-
- default:
- break;
- }
- }
- }
- return -1;
-}
-#else /* NUM_DB_TYPES */
-geoip_db_lookup_latlon6(geoipv6_t addr _U_, float *lat _U_, float *lon _U_) {
- return -1;
-}
-#endif /* NUM_DB_TYPES */
-
-char *
-geoip_db_lookup_ipv6(guint dbnum, ws_in6_addr addr, const char *not_found) {
- GeoIP *gi;
- geoipv6_t gaddr;
- char *name;
- const char *country;
- char *val, *ret = NULL;
-#if NUM_DB_TYPES > 31
- GeoIPRecord *gir;
-#endif
- if (dbnum > geoip_db_num_dbs()) {
- if (not_found == NULL)
- return NULL;
-
- return wmem_strdup(NULL, not_found);
- }
-
- memcpy(&gaddr, &addr, sizeof(addr));
-
- gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
- if (gi) {
- switch (gi->databaseType) {
- case GEOIP_COUNTRY_EDITION_V6:
- country = GeoIP_country_name_by_ipnum_v6(gi, gaddr);
- if (country) {
- ret = db_val_to_utf_8(country, gi);
- }
- break;
-
-#if NUM_DB_TYPES > 31
- case GEOIP_CITY_EDITION_REV0_V6:
- case GEOIP_CITY_EDITION_REV1_V6:
- gir = GeoIP_record_by_ipnum_v6(gi, gaddr);
- if (gir && gir->city && gir->region) {
- val = wmem_strdup_printf(NULL, "%s, %s", gir->city, gir->region);
- ret = db_val_to_utf_8(val, gi);
- wmem_free(NULL, val);
- } else if (gir && gir->city) {
- ret = db_val_to_utf_8(gir->city, gi);
- }
- break;
-
- case GEOIP_ORG_EDITION_V6:
- case GEOIP_ISP_EDITION_V6:
- case GEOIP_ASNUM_EDITION_V6:
- name = GeoIP_name_by_ipnum_v6(gi, gaddr);
- if (name) {
- ret = db_val_to_utf_8(name, gi);
- GeoIP_free(name);
- }
- break;
-#endif /* NUM_DB_TYPES */
-
- case WS_LAT_FAKE_EDITION:
- {
- float lat;
- float lon;
- char *c;
- if(geoip_db_lookup_latlon6(gaddr, &lat, &lon) == 0) {
- val = wmem_strdup_printf(NULL, "%f", lat);
- c = strchr(val, ',');
- if (c != NULL) *c = '.';
- ret = val;
- }
- }
- break;
-
- case WS_LON_FAKE_EDITION:
- {
- float lat;
- float lon;
- char *c;
- if(geoip_db_lookup_latlon6(gaddr, &lat, &lon) == 0) {
- val = wmem_strdup_printf(NULL, "%f", lon);
- c = strchr(val, ',');
- if (c != NULL) *c = '.';
- ret = val;
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- if (ret == NULL) {
- if (not_found == NULL)
- return NULL;
-
- return wmem_strdup(NULL, not_found);
- }
-
- return ret;
-}
-
-#else /* HAVE_GEOIP_V6 */
-
-char *
-geoip_db_lookup_ipv6(guint dbnum _U_, ws_in6_addr addr _U_, const char *not_found) {
- if (not_found == NULL)
- return NULL;
-
- return wmem_strdup(NULL, not_found);
-}
-
-#endif /* HAVE_GEOIP_V6 */
-
-gchar *
-geoip_db_get_paths(void) {
- GString* path_str = NULL;
- guint i;
-
- path_str = g_string_new("");
-
- for (i = 0; geoip_db_system_paths[i].path != NULL; i++) {
- g_string_append_printf(path_str,
- "%s" G_SEARCHPATH_SEPARATOR_S, geoip_db_system_paths[i].path);
- }
-
- for (i = 0; i < num_geoip_db_paths; i++) {
- if (geoip_db_paths[i].path) {
- g_string_append_printf(path_str,
- "%s" G_SEARCHPATH_SEPARATOR_S, geoip_db_paths[i].path);
- }
- }
-
- g_string_truncate(path_str, path_str->len-1);
-
- return g_string_free(path_str, FALSE);
-}
-
-#else /* HAVE_GEOIP */
-guint
-geoip_db_num_dbs(void) {
- return 0;
-}
-
-const gchar *
-geoip_db_name(guint dbnum _U_) {
- return "Unsupported";
-}
-
-int
-geoip_db_type(guint dbnum _U_) {
- return -1;
-}
-
-char *
-geoip_db_lookup_ipv4(guint dbnum _U_, guint32 addr _U_, const char *not_found) {
- if (not_found == NULL)
- return NULL;
-
- return (char *)wmem_strdup(NULL, not_found);
-}
-
-char *
-geoip_db_lookup_ipv6(guint dbnum _U_, guint32 addr _U_, const char *not_found) {
- if (not_found == NULL)
- return NULL;
-
- return (char *)wmem_strdup(NULL, not_found);
-}
-
-gchar *
-geoip_db_get_paths(void) {
- return g_strdup("");
-}
-
-#endif /* HAVE_GEOIP */
-
-/*
- * Editor modelines
- *
- * Local Variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * ex: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */
diff --git a/epan/geoip_db.h b/epan/geoip_db.h
deleted file mode 100644
index 20aa46a8c6..0000000000
--- a/epan/geoip_db.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* geoip_db.h
- * GeoIP database support
- *
- * Copyright 2008, Gerald Combs <gerald@wireshark.org>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef __GEOIP_DB_H__
-#define __GEOIP_DB_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include <epan/ipv6.h>
-#include <epan/prefs.h>
-#include "ws_symbol_export.h"
-
-/* Fake databases to make lat/lon values available */
-/* XXX - find a better way to interface */
-#define WS_LAT_FAKE_EDITION (NUM_DB_TYPES+1)
-#define WS_LON_FAKE_EDITION (NUM_DB_TYPES+2)
-
-
-/**
- * Init function called from epan.h
- */
-extern void geoip_db_pref_init(module_t *nameres);
-
-/**
- * Number of databases we have loaded
- *
- * @return The number GeoIP databases successfully loaded
- */
-WS_DLL_PUBLIC guint geoip_db_num_dbs(void);
-
-/**
- * Fetch the name of a database
- *
- * @param dbnum Database index
- * @return The database name or "Invalid database"
- */
-WS_DLL_PUBLIC const gchar *geoip_db_name(guint dbnum);
-
-/**
- * Fetch the database type. Types are enumerated in GeoIPDBTypes in GeoIP.h.
- *
- * @param dbnum Database index
- * @return The database type or -1
- */
-WS_DLL_PUBLIC int geoip_db_type(guint dbnum);
-
-/**
- * Look up an IPv4 address in a database
- *
- * @param dbnum Database index
- * @param addr IPv4 address to look up
- * @param not_found The string to return if the lookup fails. May be NULL.
- *
- * @return The database entry if found, else not_found. Return value must be freed with wmem_free.
- */
-WS_DLL_PUBLIC char *geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found);
-
-/**
- * Look up an IPv6 address in a database
- *
- * @param dbnum Database index
- * @param addr IPv6 address to look up
- * @param not_found The string to return if the lookup fails. May be NULL.
- *
- * @return The database entry if found, else not_found. Return value must be freed with wmem_free.
- */
-WS_DLL_PUBLIC char *geoip_db_lookup_ipv6(guint dbnum, ws_in6_addr addr, const char *not_found);
-
-/**
- * Get all configured paths
- *
- * @return String with all paths separated by a path separator
- */
-WS_DLL_PUBLIC gchar *geoip_db_get_paths(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __GEOIP_DB_H__ */
-
-/*
- * Editor modelines
- *
- * Local Variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * ex: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */
diff --git a/epan/maxmind_db.c b/epan/maxmind_db.c
new file mode 100644
index 0000000000..03e705660d
--- /dev/null
+++ b/epan/maxmind_db.c
@@ -0,0 +1,513 @@
+/* maxmind_db.c
+ * GeoIP database support
+ *
+ * Copyright 2018, Gerald Combs <gerald@wireshark.org>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <epan/maxmind_db.h>
+
+static mmdb_lookup_t mmdb_not_found;
+
+#ifdef HAVE_MAXMINDDB
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <epan/wmem/wmem.h>
+
+#include <epan/addr_resolv.h>
+#include <epan/uat.h>
+#include <epan/prefs.h>
+
+#include <wsutil/report_message.h>
+#include <wsutil/file_util.h>
+#include <wsutil/filesystem.h>
+#include <wsutil/ws_pipe.h>
+
+// To do:
+// - If we can't reliably do non-blocking reads, move process_mmdbr_stdout to a worker thread.
+// - Add RBL lookups? Along with the "is this a spammer" information that most RBL databases
+// provide, you can also fetch AS information: http://www.team-cymru.org/IP-ASN-mapping.html
+// - Switch to a different format? I was going to use g_key_file_* to parse
+// the mmdbresolve output, but it was easier to just parse it directly.
+
+// Hashes of mmdb_lookup_t
+static wmem_map_t *mmdb_ipv4_map;
+static wmem_map_t *mmdb_ipv6_map;
+
+// Interned strings
+static wmem_map_t *mmdb_str_chunk;
+
+/* Child mmdbresolve process */
+static char cur_addr[WS_INET6_ADDRSTRLEN];
+static mmdb_lookup_t cur_lookup;
+static ws_pipe_t mmdbr_pipe;
+
+/* UAT definitions. Copied from oids.c */
+typedef struct _maxmind_db_path_t {
+ char* path;
+} maxmind_db_path_t;
+
+static maxmind_db_path_t *maxmind_db_paths;
+static guint num_maxmind_db_paths;
+static const maxmind_db_path_t maxmind_db_system_paths[] = {
+#ifdef _WIN32
+ // XXX Properly expand "%ProgramData%\GeoIP".
+ { "C:\\ProgramData\\GeoIP" },
+ { "C:\\GeoIP" },
+#else
+ { "/usr/share/GeoIP" },
+ { "/var/lib/GeoIP" },
+#endif
+ { NULL }
+};
+static uat_t *maxmind_db_paths_uat;
+UAT_DIRECTORYNAME_CB_DEF(maxmind_mod, path, maxmind_db_path_t)
+
+static GPtrArray *mmdb_file_arr; // .mmdb files
+
+#if 0
+#define MMDB_DEBUG(...) { \
+ char *MMDB_DEBUG_MSG = g_strdup_printf(__VA_ARGS__); \
+ g_warning("mmdb: %s:%d %s", G_STRFUNC, __LINE__, MMDB_DEBUG_MSG); \
+ g_free(MMDB_DEBUG_MSG); \
+}
+#else
+#define MMDB_DEBUG(...)
+#endif
+
+static void mmdb_resolve_stop(void);
+
+// Hopefully scanning a few lines asynchronously has less overhead than
+// reading in a child thread.
+#define RES_STATUS_ERROR "mmdbresolve.status: false"
+#define RES_COUNTRY_ISO_CODE "country.iso_code" // Unused.
+#define RES_COUNTRY_NAMES_EN "country.names.en"
+#define RES_CITY_NAMES_EN "city.names.en"
+#define RES_ASN_ORG "autonomous_system_organization"
+#define RES_ASN_NUMBER "autonomous_system_number"
+#define RES_LOCATION_LATITUDE "location.latitude"
+#define RES_LOCATION_LONGITUDE "location.longitude"
+#define RES_END "# End "
+
+// Interned strings, similar to GLib's string chunks.
+static const char *chunkify_string(char *key) {
+ g_strstrip(key);
+ char *chunk_string = (char *) wmem_map_lookup(mmdb_str_chunk, key);
+
+ if (!chunk_string) {
+ chunk_string = wmem_strdup(wmem_epan_scope(), key);
+ wmem_map_insert(mmdb_str_chunk, key, chunk_string);
+ }
+
+ return chunk_string;
+}
+
+static gboolean
+process_mmdbr_stdout(int fd) {
+
+ size_t read_buf_size = 65536;
+ char *read_buf = (char *) g_malloc((gsize) read_buf_size);
+ gboolean new_entries = FALSE;
+
+ MMDB_DEBUG("start %d", ws_pipe_data_available(fd));
+
+ while (ws_pipe_data_available(fd)) {
+ read_buf[0] = '\0';
+ ssize_t read_status = ws_read(fd, read_buf, read_buf_size);
+ if (read_status < 1) {
+ MMDB_DEBUG("read error %s", g_strerror(errno));
+ mmdb_resolve_stop();
+ break;
+ }
+
+ size_t read_len = strlen(read_buf);
+ MMDB_DEBUG("read %zd bytes", read_len);
+ if (read_len < 1) {
+ break;
+ }
+
+ char **lines = g_strsplit(read_buf, "\n", -1);
+ for (size_t idx = 0; lines[idx]; idx++) {
+ char *line = lines[idx];
+ size_t line_len = strlen(line);
+ char *val_start = strchr(line, ':');
+
+ if (val_start) val_start++;
+
+ if (line_len < 1) continue;
+ MMDB_DEBUG("line %s", line);
+
+ if (line[0] == '[') {
+ // [init] or resolved address in square brackets.
+ line[line_len - 1] = '\0';
+ g_strlcpy(cur_addr, line + 1, WS_INET6_ADDRSTRLEN);
+ memset(&cur_lookup, 0, sizeof(cur_lookup));
+ } else if (strcmp(line, RES_STATUS_ERROR) == 0) {
+ // Error during init.
+ cur_addr[0] = '\0';
+ memset(&cur_lookup, 0, sizeof(cur_lookup));
+ mmdb_resolve_stop();
+ } else if (val_start && g_str_has_prefix(line, RES_COUNTRY_NAMES_EN)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.country = chunkify_string(val_start);
+ } else if (g_str_has_prefix(line, RES_CITY_NAMES_EN)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.city = chunkify_string(val_start);
+ } else if (g_str_has_prefix(line, RES_ASN_ORG)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.as_org = chunkify_string(val_start);
+ } else if (g_str_has_prefix(line, RES_ASN_NUMBER)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.as_number = (unsigned int) strtoul(val_start, NULL, 10);
+ } else if (g_str_has_prefix(line, RES_LOCATION_LATITUDE)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.latitude = strtod(val_start, NULL);
+ } else if (g_str_has_prefix(line, RES_LOCATION_LONGITUDE)) {
+ cur_lookup.found = TRUE;
+ cur_lookup.longitude = strtod(val_start, NULL);
+ } else if (g_str_has_prefix(line, RES_END)) {
+ if (cur_lookup.found) {
+ mmdb_lookup_t *mmdb_val = (mmdb_lookup_t *) wmem_memdup(wmem_epan_scope(), &cur_lookup, sizeof(cur_lookup));
+ if (strstr(cur_addr, ".")) {
+ MMDB_DEBUG("inserting v4 %p %s: city %s country %s", (void *) mmdb_val, cur_addr, mmdb_val->city, mmdb_val->country);
+ guint32 addr;
+ ws_inet_pton4(cur_addr, &addr);
+ wmem_map_insert(mmdb_ipv4_map, GUINT_TO_POINTER(addr), mmdb_val);
+ new_entries = TRUE;
+ } else if (strstr(cur_addr, ":")) {
+ MMDB_DEBUG("inserting v6 %p %s: city %s country %s", (void *) mmdb_val, cur_addr, mmdb_val->city, mmdb_val->country);
+ ws_in6_addr addr;
+ ws_inet_pton6(cur_addr, &addr);
+ wmem_map_insert(mmdb_ipv6_map, addr.bytes, mmdb_val);
+ new_entries = TRUE;
+ }
+ }
+ cur_addr[0] = '\0';
+ memset(&cur_lookup, 0, sizeof(cur_lookup));
+ }
+ }
+ g_strfreev(lines);
+ }
+ return new_entries;
+}
+
+/**
+ * Stop our mmdbresolve process.
+ */
+static void mmdb_resolve_stop(void) {
+ if (!mmdbr_pipe.pid) return;
+
+ ws_close(mmdbr_pipe.stdin_fd);
+ MMDB_DEBUG("closing pid %d", mmdbr_pipe.pid);
+ g_spawn_close_pid(mmdbr_pipe.pid);
+ mmdbr_pipe.pid = WS_INVALID_PID;
+}
+
+/**
+ * Start an mmdbresolve process.
+ */
+static void mmdb_resolve_start(void) {
+ if (!mmdb_ipv4_map) {
+ mmdb_ipv4_map = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
+ }
+ if (!mmdb_ipv6_map) {
+ mmdb_ipv6_map = wmem_map_new(wmem_epan_scope(), ipv6_oat_hash, ipv6_equal);
+ }
+
+ if (!mmdb_str_chunk) {
+ mmdb_str_chunk = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
+ }
+
+ if (!mmdb_file_arr) return;
+
+ mmdb_resolve_stop();
+
+ GPtrArray *args = g_ptr_array_new();
+ char *mmdbresolve = g_strdup_printf("%s%c%s", get_progfile_dir(), G_DIR_SEPARATOR, "mmdbresolve");
+ g_ptr_array_add(args, mmdbresolve);
+ for (guint i = 0; i < mmdb_file_arr->len; i++) {
+ g_ptr_array_add(args, g_strdup("-f"));
+ g_ptr_array_add(args, g_strdup(g_ptr_array_index(mmdb_file_arr, i)));
+ }
+ g_ptr_array_add(args, NULL);
+
+ ws_pipe_init(&mmdbr_pipe);
+ GPid pipe_pid = ws_pipe_spawn_async(&mmdbr_pipe, args);
+ MMDB_DEBUG("spawned %s pid %d", mmdbresolve, pipe_pid);
+
+ for (guint i = 0; i < args->len; i++) {
+ g_free(g_ptr_array_index(args, i));
+ }
+ g_ptr_array_free(args, TRUE);
+
+ if (pipe_pid == WS_INVALID_PID) {
+ ws_pipe_init(&mmdbr_pipe);
+ return;
+ }
+
+ // [init]
+ process_mmdbr_stdout(mmdbr_pipe.stdout_fd);
+}
+
+/**
+ * Scan a directory for GeoIP databases and load them
+ */
+static void
+maxmind_db_scan_dir(const char *dirname) {
+ WS_DIR *dir;
+ WS_DIRENT *file;
+
+ if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) {
+ while ((file = ws_dir_read_name(dir)) != NULL) {
+ const char *name = ws_dir_get_name(file);
+ if (g_str_has_suffix(file, ".mmdb")) {
+ char *datname = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dirname, name);
+ FILE *mmdb_f = ws_fopen(datname, "r");
+ if (mmdb_f) {
+ g_ptr_array_add(mmdb_file_arr, datname);
+ fclose(mmdb_f);
+ } else {
+ g_free(datname);
+ }
+ }
+ }
+ ws_dir_close (dir);
+ }
+}
+
+/* UAT callbacks */
+static void* maxmind_db_path_copy_cb(void* dest, const void* orig, size_t len _U_) {
+ const maxmind_db_path_t *m = (const maxmind_db_path_t *)orig;
+ maxmind_db_path_t *d = (maxmind_db_path_t *)dest;
+
+ d->path = g_strdup(m->path);
+
+ return d;
+}
+
+static void maxmind_db_path_free_cb(void* p) {
+ maxmind_db_path_t *m = (maxmind_db_path_t *)p;
+ g_free(m->path);
+}
+
+static void maxmind_db_cleanup(void) {
+ guint i;
+
+ mmdb_resolve_stop();
+
+ /* If we have old data, clear out the whole thing
+ * and start again. TODO: Just update the ones that
+ * have changed for efficiency's sake. */
+ if (mmdb_file_arr) {
+ for (i = 0; i < mmdb_file_arr->len; i++) {
+ g_free(g_ptr_array_index(mmdb_file_arr, i));
+ }
+ /* finally, free the array itself */
+ g_ptr_array_free(mmdb_file_arr, TRUE);
+ mmdb_file_arr = NULL;
+ }
+}
+
+/* called every time the user presses "Apply" or "OK in the list of
+ * GeoIP directories, and also once on startup */
+static void maxmind_db_post_update_cb(void) {
+ guint i;
+
+ maxmind_db_cleanup();
+
+ /* allocate the array */
+ mmdb_file_arr = g_ptr_array_new();
+
+ /* First try the system paths */
+ for (i = 0; maxmind_db_system_paths[i].path != NULL; i++) {
+ maxmind_db_scan_dir(maxmind_db_system_paths[i].path);
+ }
+
+ /* Walk all the directories */
+ for (i = 0; i < num_maxmind_db_paths; i++) {
+ if (maxmind_db_paths[i].path) {
+ maxmind_db_scan_dir(maxmind_db_paths[i].path);
+ }
+ }
+
+ mmdb_resolve_start();
+}
+
+/**
+ * Initialize GeoIP lookups
+ */
+void
+maxmind_db_pref_init(module_t *nameres)
+{
+ static uat_field_t maxmind_db_paths_fields[] = {
+ UAT_FLD_DIRECTORYNAME(maxmind_mod, path, "MaxMind Database Directory", "The MaxMind database directory path"),
+ UAT_END_FIELDS
+ };
+
+ maxmind_db_paths_uat = uat_new("MaxMind Database Paths",
+ sizeof(maxmind_db_path_t),
+ "maxmind_db_paths",
+ FALSE, // Global, not per-profile
+ (void**)&maxmind_db_paths,
+ &num_maxmind_db_paths,
+ UAT_AFFECTS_DISSECTION, // Affects IP4 and IPv6 packets.
+ "ChMaxMindDbPaths",
+ maxmind_db_path_copy_cb,
+ NULL, // update_cb
+ maxmind_db_path_free_cb,
+ maxmind_db_post_update_cb,
+ maxmind_db_cleanup,
+ maxmind_db_paths_fields);
+
+ prefs_register_uat_preference(nameres,
+ "maxmind_db_paths",
+ "MaxMind database directories",
+ "Search paths for MaxMind address mapping databases."
+ " Wireshark will look in each directory for files ending"
+ " with \".mmdb\".",
+ maxmind_db_paths_uat);
+}
+
+void maxmind_db_pref_cleanup(void)
+{
+ mmdb_resolve_stop();
+}
+
+/**
+ * Public API
+ */
+
+gboolean maxmind_db_lookup_process(void)
+{
+ if (mmdbr_pipe.pid == WS_INVALID_PID) return FALSE;
+
+ return process_mmdbr_stdout(mmdbr_pipe.stdout_fd);
+}
+
+const mmdb_lookup_t *
+maxmind_db_lookup_ipv4(guint32 addr) {
+ mmdb_lookup_t *result = (mmdb_lookup_t *) wmem_map_lookup(mmdb_ipv4_map, GUINT_TO_POINTER(addr));
+
+ if (!result) {
+ if (mmdbr_pipe.stdin_fd) {
+ char addr_str[WS_INET_ADDRSTRLEN + 1];
+ ws_inet_ntop4(&addr, addr_str, WS_INET_ADDRSTRLEN);
+ MMDB_DEBUG("looking up %s", addr_str);
+ g_strlcat(addr_str, "\n", (gsize) sizeof(addr_str));
+ ssize_t write_status = ws_write(mmdbr_pipe.stdin_fd, addr_str, strlen(addr_str));
+ if (write_status < 0) {
+ MMDB_DEBUG("write error %s", g_strerror(errno));
+ mmdb_resolve_stop();
+ }
+ }
+
+ result = &mmdb_not_found;
+ wmem_map_insert(mmdb_ipv4_map, GUINT_TO_POINTER(addr), result);
+ }
+
+ return result;
+}
+
+const mmdb_lookup_t *
+maxmind_db_lookup_ipv6(const ws_in6_addr *addr) {
+ mmdb_lookup_t * result = (mmdb_lookup_t *) wmem_map_lookup(mmdb_ipv6_map, addr->bytes);
+
+ if (!result) {
+ if (mmdbr_pipe.stdin_fd) {
+ char addr_str[WS_INET6_ADDRSTRLEN + 1];
+ ws_inet_ntop6(addr, addr_str, WS_INET6_ADDRSTRLEN);
+ MMDB_DEBUG("looking up %s", addr_str);
+ g_strlcat(addr_str, "\n", (gsize) sizeof(addr_str));
+ ssize_t write_status = ws_write(mmdbr_pipe.stdin_fd, addr_str, strlen(addr_str));
+ if (write_status < 0) {
+ MMDB_DEBUG("write error %s", g_strerror(errno));
+ mmdb_resolve_stop();
+ }
+ }
+
+ result = &mmdb_not_found;
+ wmem_map_insert(mmdb_ipv6_map, addr->bytes, result);
+ }
+
+ return result;
+}
+
+gchar *
+maxmind_db_get_paths(void) {
+ GString* path_str = NULL;
+ guint i;
+
+ path_str = g_string_new("");
+
+ for (i = 0; maxmind_db_system_paths[i].path != NULL; i++) {
+ g_string_append_printf(path_str,
+ "%s" G_SEARCHPATH_SEPARATOR_S, maxmind_db_system_paths[i].path);
+ }
+
+ for (i = 0; i < num_maxmind_db_paths; i++) {
+ if (maxmind_db_paths[i].path) {
+ g_string_append_printf(path_str,
+ "%s" G_SEARCHPATH_SEPARATOR_S, maxmind_db_paths[i].path);
+ }
+ }
+
+ g_string_truncate(path_str, path_str->len-1);
+
+ return g_string_free(path_str, FALSE);
+}
+
+#else // HAVE_MAXMINDDB
+
+void
+maxmind_db_pref_init(module_t *nameres _U_) {}
+
+void
+maxmind_db_pref_cleanup(void) {}
+
+
+gboolean
+maxmind_db_lookup_process(void)
+{
+ return FALSE;
+}
+
+const mmdb_lookup_t *
+maxmind_db_lookup_ipv4(guint32 addr _U_) {
+ return &mmdb_not_found;
+}
+
+const mmdb_lookup_t *
+maxmind_db_lookup_ipv6(const ws_in6_addr *addr _U_) {
+ return &mmdb_not_found;
+}
+
+gchar *
+maxmind_db_get_paths(void) {
+ return g_strdup("");
+}
+#endif // HAVE_MAXMINDDB
+
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/maxmind_db.h b/epan/maxmind_db.h
new file mode 100644
index 0000000000..1b8e5fed0a
--- /dev/null
+++ b/epan/maxmind_db.h
@@ -0,0 +1,93 @@
+/* maxmind_db.h
+ * Maxmind database support
+ *
+ * Copyright 2018, Gerald Combs <gerald@wireshark.org>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef __MAXMIND_DB_H__
+#define __MAXMIND_DB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <epan/ipv6.h>
+#include <epan/prefs.h>
+#include "ws_symbol_export.h"
+
+typedef struct _mmdb_lookup_t {
+ gboolean found;
+ const char *country;
+ const char *city;
+ unsigned int as_number;
+ const char *as_org;
+ double latitude;
+ double longitude;
+} mmdb_lookup_t;
+
+/**
+ * Init function called from epan.h
+ */
+WS_DLL_LOCAL void maxmind_db_pref_init(module_t *nameres);
+
+/**
+ * Cleanup function called from epan.h
+ */
+WS_DLL_LOCAL void maxmind_db_pref_cleanup(void);
+
+/**
+ * Look up an IPv4 address in a database
+ *
+ * @param addr IPv4 address to look up
+ *
+ * @return The database entry if found, else NULL.
+ */
+WS_DLL_PUBLIC WS_RETNONNULL const mmdb_lookup_t *maxmind_db_lookup_ipv4(guint32 addr);
+
+/**
+ * Look up an IPv6 address in a database
+ *
+ * @param addr IPv6 address to look up
+ *
+ * @return The database entry if found, else NULL.
+ */
+WS_DLL_PUBLIC WS_RETNONNULL const mmdb_lookup_t *maxmind_db_lookup_ipv6(const ws_in6_addr *addr);
+
+/**
+ * Get all configured paths
+ *
+ * @return String with all paths separated by a path separator
+ */
+WS_DLL_PUBLIC gchar *maxmind_db_get_paths(void);
+
+/**
+ * Process outstanding requests.
+ *
+ * @return True if any new addresses were resolved.
+ */
+WS_DLL_LOCAL gboolean maxmind_db_lookup_process(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MAXMIND_DB_H__ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/prefs.c b/epan/prefs.c
index 1ccf5ac185..eb30c1628a 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -21,9 +21,7 @@
#include <epan/address.h>
#include <epan/addr_resolv.h>
#include <epan/oids.h>
-#ifdef HAVE_GEOIP
-#include <epan/geoip_db.h>
-#endif
+#include <epan/maxmind_db.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/proto.h>
@@ -3506,9 +3504,7 @@ prefs_register_modules(void)
"Name Resolution", NULL, TRUE);
addr_resolve_pref_init(nameres_module);
oid_pref_init(nameres_module);
-#ifdef HAVE_GEOIP
- geoip_db_pref_init(nameres_module);
-#endif
+ maxmind_db_pref_init(nameres_module);
/* Printing */
printing = prefs_register_module(NULL, "print", "Printing",