aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt34
-rw-r--r--CMakeOptions.txt2
-rw-r--r--Makefile.am9
-rw-r--r--README.macos7
-rw-r--r--acinclude.m432
-rw-r--r--cmake/modules/FindGEOIP.cmake74
-rw-r--r--cmake/modules/FindMaxMindDB.cmake74
-rw-r--r--cmakeconfig.h.in10
-rw-r--r--configure.ac42
-rw-r--r--debian/control4
-rw-r--r--debian/libwireshark-data.install2
-rw-r--r--debian/libwireshark0.symbols9
-rw-r--r--debian/maxmind_db_paths (renamed from debian/geoip_db_paths)0
-rw-r--r--doc/CMakeLists.txt29
-rw-r--r--doc/Makefile.am13
-rw-r--r--doc/mmdbresolve.pod69
-rw-r--r--docbook/release-notes.asciidoc2
-rw-r--r--docbook/wsdg_src/WSDG_chapter_libraries.asciidoc23
-rw-r--r--docbook/wsug_src/WSUG_chapter_customize.asciidoc41
-rw-r--r--docbook/wsug_src/WSUG_chapter_statistics.asciidoc11
-rw-r--r--docbook/wsug_src/WSUG_chapter_use.asciidoc7
-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
-rw-r--r--mmdbresolve.c169
-rwxr-xr-xpackaging/macosx/Scripts/cli-postinstall.sh1
-rw-r--r--packaging/nsis/CMakeLists.txt7
-rw-r--r--packaging/nsis/uninstall.nsi18
-rw-r--r--packaging/nsis/wireshark.nsi8
-rw-r--r--packaging/rpm/SPECS/wireshark.spec.in4
-rw-r--r--packaging/wix/CMakeLists.txt13
-rw-r--r--packaging/wix/ComponentGroups.wxi18
-rw-r--r--packaging/wix/Features.wxi3
-rw-r--r--tools/Get-HardenFlags.ps12
-rwxr-xr-xtools/debian-setup.sh6
-rwxr-xr-xtools/install_rpms_for_devel.sh6
-rwxr-xr-xtools/macos-setup.sh88
-rw-r--r--tools/pre-commit-ignore.conf1
-rwxr-xr-xtools/rpm_setup.sh4
-rw-r--r--tools/win-setup.ps14
-rw-r--r--tshark.c12
-rw-r--r--ui/qt/endpoint_dialog.cpp176
-rw-r--r--ui/qt/endpoint_dialog.h18
-rw-r--r--ui/traffic_table_ui.c8
-rw-r--r--ui/traffic_table_ui.h9
55 files changed, 1524 insertions, 1503 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 747223adf6..96b013892a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -923,6 +923,11 @@ if(BUILD_wireshark)
endif()
endif()
+# MaxMind DB address resolution
+if(BUILD_mmdbresolve)
+ set(PACKAGELIST ${PACKAGELIST} MaxMindDB)
+endif()
+
# SMI SNMP
if(ENABLE_SMI)
set(PACKAGELIST ${PACKAGELIST} SMI)
@@ -991,11 +996,6 @@ if(ENABLE_LUA)
set(PACKAGELIST ${PACKAGELIST} LUA)
endif()
-# GeoIP address resolving
-if(ENABLE_GEOIP)
- set(PACKAGELIST ${PACKAGELIST} GEOIP)
-endif()
-
if(ENABLE_NETLINK)
set(PACKAGELIST ${PACKAGELIST} NL)
endif()
@@ -1117,8 +1117,8 @@ endif()
if(HAVE_LIBKERBEROS)
set(HAVE_KERBEROS 1)
endif()
-if(HAVE_LIBGEOIP)
- set(HAVE_GEOIP 1)
+if(MAXMINDDB_FOUND)
+ set(HAVE_MAXMINDDB 1)
endif()
if(LIBSSH_FOUND)
set(HAVE_LIBSSH 1)
@@ -1648,6 +1648,10 @@ set(INSTALL_FILES
${CMAKE_BINARY_DIR}/doc/wireshark-filter.html
)
+if(MAXMINDDB_FOUND)
+ list(APPEND INSTALL_FILES ${CMAKE_BINARY_DIR}/doc/mmdbresolve.html)
+endif()
+
if (BUILD_corbaidl2wrs)
list(APPEND INSTALL_FILES ${CMAKE_BINARY_DIR}/doc/idl2wrs.html)
endif()
@@ -2919,6 +2923,20 @@ if(BUILD_randpktdump)
add_dependencies(extcaps randpktdump)
endif()
+if (MAXMINDDB_FOUND)
+ set(mmdbresolve_LIBS
+ # Note: libmaxminddb is not GPL-2 compatible.
+ ${MAXMINDDB_LIBRARY}
+ )
+ set(mmdbresolve_FILES
+ mmdbresolve.c
+ )
+ add_executable(mmdbresolve ${mmdbresolve_FILES})
+ set_extra_executable_properties(mmdbresolve "Executables")
+ target_link_libraries(mmdbresolve ${mmdbresolve_LIBS})
+ install(TARGETS mmdbresolve RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
+
if(ENABLE_APPLICATION_BUNDLE)
add_custom_target(app_bundle)
set_target_properties(app_bundle PROPERTIES FOLDER "Copy Tasks")
@@ -2990,7 +3008,7 @@ set(CLEAN_C_FILES
${androiddump_FILES}
${sshdump_FILES}
${ciscodump_FILES}
- ${udpdump_FILES}
+ ${mmdbresolve_FILES}
)
# Make sure we don't pass /WX to rc.exe. Rc doesn't have a /WX flag,
diff --git a/CMakeOptions.txt b/CMakeOptions.txt
index c011f3e65b..e7903f5b0f 100644
--- a/CMakeOptions.txt
+++ b/CMakeOptions.txt
@@ -24,6 +24,7 @@ option(BUILD_randpktdump "Build randpktdump" ON)
option(BUILD_udpdump "Build udpdump" ON)
option(BUILD_sharkd "Build sharkd" ON)
option(BUILD_fuzzshark "Build fuzzshark" ON)
+option(BUILD_mmdbresolve "Build MaxMind DB resolver" ON)
option(DISABLE_WERROR "Do not treat warnings as errors" OFF)
option(DISABLE_FRAME_LARGER_THAN_WARNING "Disable warning if the size of a function frame is large" OFF)
@@ -67,7 +68,6 @@ option(ENABLE_NGHTTP2 "Build with HTTP/2 header decompression support" ON)
option(ENABLE_LUA "Build with Lua dissector support" ON)
option(ENABLE_SMI "Build with libsmi snmp support" ON)
option(ENABLE_GNUTLS "Build with GNU TLS support" ON)
-option(ENABLE_GEOIP "Build with GeoIP support" ON)
if(WIN32)
option(ENABLE_WINSPARKLE "Enable WinSparkle support" ON)
endif()
diff --git a/Makefile.am b/Makefile.am
index 3f381f8a0e..f90fda4c32 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,7 +43,7 @@ bin_PROGRAMS = \
@randpkt_bin@ \
@dumpcap_bin@ \
@reordercap_bin@ \
- @rawshark_bin@ \
+ @mmdbresolve_bin@ \
@sharkd_bin@
noinst_PROGRAMS = \
@@ -52,7 +52,7 @@ noinst_PROGRAMS = \
EXTRA_PROGRAMS = wireshark-gtk wireshark tshark tfshark capinfos captype \
editcap mergecap dftest randpkt text2pcap dumpcap reordercap \
- rawshark sharkd fuzzshark
+ mmdbresolve rawshark sharkd fuzzshark
#
# Wireshark configuration files are put in $(pkgdatadir).
@@ -531,6 +531,11 @@ rawshark_LDADD = \
@PCAP_LIBS@ \
${EPAN_EXTRA_LIBS}
+mmdbresolve_SOURCES = mmdbresolve.c
+mmdbresolve_CPPFLAGS = $(AM_CPPFLAGS)
+mmdbresolve_LDFLAGS = $(AM_LDFLAGS)
+mmdbresolve_LDADD = @MAXMINDDB_LIBS@
+
sharkd_SOURCES = \
$(SHARK_COMMON_SRC) \
sharkd.c \
diff --git a/README.macos b/README.macos
index 7e533ca3f7..e53e946d2f 100644
--- a/README.macos
+++ b/README.macos
@@ -149,13 +149,6 @@ Newer versions don't have this problem, but still fail to build on Lion
if a universal build is attempted. The tools/macos-setup.sh script
downloads a newer version, and also suppresses the universal build.
-GeoIP - Their man pages "helpfully" have an ISO 8859-1 copyright symbol
-in the copyright notice, but macOS's default character encoding is
-UTF-8. sed on Mountain Lion barfs at the "illegal character sequence"
-represented by an ISO 8859-1 copyright symbol, as it's not a valid UTF-8
-sequence. The tools/macos-setup.sh script uses iconv to convert the man
-page files from ISO 8859-1 to UTF-8.
-
If you want to build Wireshark installer packages on a system that
doesn't include Xcode 3.x or earlier, you will need to install some
additional tools. From the Xcode menu, select the Open Developer Tool
diff --git a/acinclude.m4 b/acinclude.m4
index c53ac7c46a..bfc715c3f1 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1162,36 +1162,24 @@ AC_DEFUN([AC_WIRESHARK_KRB5_CHECK],
])
#
-# AC_WIRESHARK_GEOIP_CHECK
+# AC_WIRESHARK_MAXMINDDB_CHECK
#
-AC_DEFUN([AC_WIRESHARK_GEOIP_CHECK],
+AC_DEFUN([AC_WIRESHARK_MAXMINDDB_CHECK],
[
- want_geoip=defaultyes
+ want_maxminddb=defaultyes
- if test "x$want_geoip" = "xdefaultyes"; then
- want_geoip=yes
+ if test "x$want_maxminddb" = "xdefaultyes"; then
+ want_maxminddb=yes
fi
- if test "x$want_geoip" = "xyes"; then
- AC_CHECK_LIB(GeoIP, GeoIP_new,
+ if test "x$want_maxminddb" = "xyes"; then
+ AC_CHECK_LIB(maxminddb, MMDB_open,
[
- GEOIP_LIBS=-lGeoIP
- AC_DEFINE(HAVE_GEOIP, 1, [Define to use GeoIP library])
- have_good_geoip=yes
+ MAXMINDDB_LIBS=-lmaxminddb
+ AC_DEFINE(HAVE_MAXMINDDB, 1, [Define to use MaxMind DB library])
+ have_good_maxminddb=yes
],,
)
- if test "x$have_good_geoip" = "xyes"; then
- AC_CHECK_LIB(GeoIP, GeoIP_country_name_by_ipnum_v6,
- [
- AC_DEFINE(HAVE_GEOIP_V6, 1, [Define if GeoIP supports IPv6 (GeoIP 1.4.5 and later)])
- ],,
- )
- AC_CHECK_LIB(GeoIP, GeoIP_free,
- [
- AC_DEFINE(HAVE_GEOIP_FREE, 1, [Define if GeoIP has GeoIP_free])
- ],,
- )
- fi
else
AC_MSG_RESULT(not required)
fi
diff --git a/cmake/modules/FindGEOIP.cmake b/cmake/modules/FindGEOIP.cmake
deleted file mode 100644
index 518837be4b..0000000000
--- a/cmake/modules/FindGEOIP.cmake
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# - Find GeoIP
-# Find the native GEOIP includes and library
-#
-# GEOIP_INCLUDE_DIRS - where to find GeoIP.h, etc.
-# GEOIP_LIBRARIES - List of libraries when using GeoIP.
-# GEOIP_FOUND - True if GeoIP found.
-# GEOIP_DLL_DIR - (Windows) Path to the GeoIP DLL.
-# GEOIP_DLL - (Windows) Name of the GeoIP DLL.
-
-
-IF (GEOIP_INCLUDE_DIRS)
- # Already in cache, be silent
- SET(GEOIP_FIND_QUIETLY TRUE)
-ENDIF (GEOIP_INCLUDE_DIRS)
-
-INCLUDE(FindWSWinLibs)
-FindWSWinLibs("GeoIP-.*" "GEOIP_HINTS")
-
-IF (NOT WIN32)
- find_package(PkgConfig)
- pkg_search_module(GEOIP geoip)
-endif()
-
-FIND_PATH(GEOIP_INCLUDE_DIR GeoIP.h
- HINTS
- "${GEOIP_INCLUDEDIR}"
- "${GEOIP_HINTS}/include"
-)
-
-SET(GEOIP_NAMES GeoIP libGeoIP-1)
-FIND_LIBRARY(GEOIP_LIBRARY NAMES ${GEOIP_NAMES}
- HINTS
- "${GEOIP_LIBDIR}"
- "${GEOIP_HINTS}/lib"
- )
-
-# handle the QUIETLY and REQUIRED arguments and set GEOIP_FOUND to TRUE if
-# all listed variables are TRUE
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(GEOIP DEFAULT_MSG GEOIP_LIBRARY GEOIP_INCLUDE_DIR)
-
-IF(GEOIP_FOUND)
- INCLUDE(CMakePushCheckState)
- CMAKE_PUSH_CHECK_STATE()
- SET(GEOIP_LIBRARIES ${GEOIP_LIBRARY} )
- SET(GEOIP_INCLUDE_DIRS ${GEOIP_INCLUDE_DIR} )
- INCLUDE(CheckFunctionExists)
- SET(CMAKE_REQUIRED_INCLUDES ${GEOIP_INCLUDE_DIRS})
- SET(CMAKE_REQUIRED_LIBRARIES ${GEOIP_LIBRARIES})
- CHECK_FUNCTION_EXISTS("GeoIP_country_name_by_ipnum_v6" HAVE_GEOIP_V6)
- CHECK_FUNCTION_EXISTS("GeoIP_free" HAVE_GEOIP_FREE)
- CMAKE_POP_CHECK_STATE()
- if (WIN32)
- set ( GEOIP_DLL_DIR "${GEOIP_HINTS}/bin"
- CACHE PATH "Path to the GeoIP DLL"
- )
- file( GLOB _geoip_dll RELATIVE "${GEOIP_DLL_DIR}"
- "${GEOIP_DLL_DIR}/libGeoIP-*.dll"
- )
- set ( GEOIP_DLL ${_geoip_dll}
- # We're storing filenames only. Should we use STRING instead?
- CACHE FILEPATH "GeoIP DLL file name"
- )
- mark_as_advanced( GEOIP_DLL_DIR GEOIP_DLL )
- endif()
-ELSE(GEOIP_FOUND)
- SET(GEOIP_LIBRARIES )
- SET(GEOIP_INCLUDE_DIRS )
- SET(GEOIP_DLL_DIR )
- SET(GEOIP_DLL )
-ENDIF(GEOIP_FOUND)
-
-MARK_AS_ADVANCED( GEOIP_LIBRARIES GEOIP_INCLUDE_DIRS )
diff --git a/cmake/modules/FindMaxMindDB.cmake b/cmake/modules/FindMaxMindDB.cmake
new file mode 100644
index 0000000000..cad4499e5b
--- /dev/null
+++ b/cmake/modules/FindMaxMindDB.cmake
@@ -0,0 +1,74 @@
+#
+# - Try to find libmaxminddb.
+# Once done this will define
+# MAXMINDDB_FOUND - System has libmaxminddb
+# MAXMINDDB_INCLUDE_DIRS - The libmaxminddb include directories
+# MAXMINDDB_LIBRARIES - The libraries needed to use libmaxminddb
+# MAXMINDDB_DEFINITIONS - Compiler switches required for using libmaxminddb
+# MAXMINDDB_DLL_DIR - (Windows) Path to the MaxMindDB DLL.
+# MAXMINDDB_DLL - (Windows) Name of the MaxMindDB DLL.
+
+IF (MAXMINDDB_INCLUDE_DIRS)
+ # Already in cache, be silent
+ SET(MAXMINDDB_FIND_QUIETLY TRUE)
+ENDIF (MAXMINDDB_INCLUDE_DIRS)
+
+INCLUDE(FindWSWinLibs)
+FindWSWinLibs("MaxMindDB-.*" "MAXMINDDB_HINTS")
+
+IF (NOT WIN32)
+ find_package(PkgConfig)
+ pkg_check_modules(PC_LIBMAXMINDDB QUIET libmaxminddb)
+ set(MAXMINDDB_DEFINITIONS ${PC_LIBMAXMINDDB_CFLAGS_OTHER})
+endif()
+
+FIND_PATH(MAXMINDDB_INCLUDE_DIR maxminddb.h
+ HINTS
+ ${PC_LIBMAXMINDDB_INCLUDEDIR} ${PC_LIBMAXMINDDB_INCLUDE_DIRS}
+ PATH_SUFFIXES maxminddb
+)
+
+find_library(MAXMINDDB_LIBRARY
+ NAMES
+ maxminddb libmaxminddb
+ HINTS
+ ${PC_LIBMAXMINDDB_LIBDIR} ${PC_LIBMAXMINDDB_LIBRARY_DIRS}
+ "${MAXMINDDB_HINTS}/lib"
+)
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set MAXMINDDB_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(MaxMindDB DEFAULT_MSG
+ MAXMINDDB_LIBRARY MAXMINDDB_INCLUDE_DIR)
+
+IF(MAXMINDDB_FOUND)
+ INCLUDE(CMakePushCheckState)
+ CMAKE_PUSH_CHECK_STATE()
+ SET(MAXMINDDB_LIBRARIES ${MAXMINDDB_LIBRARY} )
+ SET(MAXMINDDB_INCLUDE_DIRS ${MAXMINDDB_INCLUDE_DIR} )
+ INCLUDE(CheckFunctionExists)
+ SET(CMAKE_REQUIRED_INCLUDES ${MAXMINDDB_INCLUDE_DIRS})
+ SET(CMAKE_REQUIRED_LIBRARIES ${MAXMINDDB_LIBRARIES})
+ CMAKE_POP_CHECK_STATE()
+ if (WIN32)
+ set ( MAXMINDDB_DLL_DIR "${MAXMINDDB_HINTS}/bin"
+ CACHE PATH "Path to the MaxMindDB DLL"
+ )
+ file( GLOB _MAXMINDDB_dll RELATIVE "${MAXMINDDB_DLL_DIR}"
+ "${MAXMINDDB_DLL_DIR}/libmaxminddb*.dll"
+ )
+ set ( MAXMINDDB_DLL ${_MAXMINDDB_dll}
+ # We're storing filenames only. Should we use STRING instead?
+ CACHE FILEPATH "MaxMindDB DLL file name"
+ )
+ mark_as_advanced( MAXMINDDB_DLL_DIR MAXMINDDB_DLL )
+ endif()
+ELSE(MAXMINDDB_FOUND)
+ SET(MAXMINDDB_LIBRARIES )
+ SET(MAXMINDDB_INCLUDE_DIRS )
+ SET(MAXMINDDB_DLL_DIR )
+ SET(MAXMINDDB_DLL )
+ENDIF(MAXMINDDB_FOUND)
+
+MARK_AS_ADVANCED( MAXMINDDB_LIBRARIES MAXMINDDB_INCLUDE_DIRS )
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index 30660c259a..c78328ae08 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -62,14 +62,8 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
-/* Define to use GeoIP library */
-#cmakedefine HAVE_GEOIP 1
-
-/* Define if GeoIP supports IPv6 (GeoIP 1.4.5 and later) */
-#cmakedefine HAVE_GEOIP_V6 1
-
-/* Define if GeoIP has GeoIP_free */
-#cmakedefine HAVE_GEOIP_FREE 1
+/* Define to use the MaxMind DB library */
+#cmakedefine HAVE_MAXMINDDB 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#cmakedefine HAVE_IFADDRS_H 1
diff --git a/configure.ac b/configure.ac
index 11ef8825e6..ebb8ba0364 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2183,30 +2183,40 @@ else
fi
AC_SUBST(C_ARES_LIBS)
-dnl GEOIP Check
-GEOIP_LIBS=''
-AC_MSG_CHECKING(whether to use the GeoIP IP address mapping library if available)
+dnl MaxMind DB Check
+MAXMINDDB_LIBS=''
+AC_MSG_CHECKING(whether to use the MaxMind DB IP address mapping library if available)
-AC_ARG_WITH(geoip,
- AC_HELP_STRING( [--with-geoip@<:@=DIR@:>@],
- [use GeoIP (located in directory DIR, if supplied) @<:@default=yes, if present@:>@]),
+AC_ARG_WITH(maxminddb,
+ AC_HELP_STRING( [--with-maxminddb@<:@=DIR@:>@],
+ [use MaxMind DB (located in directory DIR, if supplied) @<:@default=yes, if present@:>@]),
[
if test "x$withval" = "xno"; then
- want_geoip=no
+ want_maxminddb=no
elif test "x$withval" = "xyes"; then
- want_geoip=yes
+ want_maxminddb=yes
elif test -d "$withval"; then
- want_geoip=yes
+ want_maxminddb=yes
AC_WIRESHARK_ADD_DASH_L(WS_LDFLAGS, ${withval}/lib)
fi
])
-if test "x$want_geoip" = "xno"; then
+if test "x$want_maxminddb" = "xno"; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(yes)
- AC_WIRESHARK_GEOIP_CHECK
+ AC_WIRESHARK_MAXMINDDB_CHECK
fi
-AC_SUBST(GEOIP_LIBS)
+AC_SUBST(MAXMINDDB_LIBS)
+
+if test "x$have_good_maxminddb" = "xyes" ; then
+ mmdbresolve_bin="mmdbresolve\$(EXEEXT)"
+ mmdbresolve_man="mmdbresolve.1"
+else
+ mmdbresolve_bin=""
+ mmdbresolve_man=""
+fi
+AC_SUBST(mmdbresolve_bin)
+AC_SUBST(mmdbresolve_man)
dnl LIBSSH Check
LIBSSH=''
@@ -2901,10 +2911,10 @@ else
libcap_message="no"
fi
-if test "x$have_good_geoip" = "xyes" ; then
- geoip_message="yes"
+if test "x$have_good_maxminddb" = "xyes" ; then
+ maxminddb_message="yes"
else
- geoip_message="no"
+ maxminddb_message="no"
fi
if test "x$have_good_libssh" = "xyes" ; then
@@ -2969,6 +2979,7 @@ echo " Build sshdump : $enable_sshdump"
echo " Build ciscodump : $enable_ciscodump"
echo " Build randpktdump : $enable_randpktdump"
echo " Build udpdump : $enable_udpdump"
+echo " Build MaxMind DB resolver : $maxminddb_message"
echo " Build User's Guide : $wsug_message"
echo ""
echo " Save files as pcapng by default : $enable_pcap_ng_default"
@@ -2987,7 +2998,6 @@ echo " Use SMI MIB library : $have_libsmi"
echo " Use GNU gcrypt library : yes"
echo " Use GnuTLS library : $tls_message"
echo " Use POSIX capabilities library : $libcap_message"
-echo " Use GeoIP library : $geoip_message"
echo " Use libssh library : ${libssh_message}${ssh_userauth_agent_message}"
echo " Use nl library : $libnl_message"
echo " Use SBC codec library : $have_sbc"
diff --git a/debian/control b/debian/control
index 2f1c62fd29..e1b1511cdd 100644
--- a/debian/control
+++ b/debian/control
@@ -19,7 +19,7 @@ Build-Depends: libgtk-3-dev, lsb-release,
# enable backports-compatible libgnutls-dev
libgnutls-dev,
libgcrypt-dev, portaudio19-dev, libkrb5-dev, liblua5.2-dev, libsmi2-dev,
- libgeoip-dev, dpkg-dev (>= 1.16.1~),
+ libmaxminddb-dev, dpkg-dev (>= 1.16.1~),
libnl-genl-3-dev [linux-any], libnl-route-3-dev [linux-any], asciidoctor,
cmake (>= 2.8.12), libsbc-dev, libnghttp2-dev, libssh-gcrypt-dev,
liblz4-dev, libsnappy-dev, libspandsp-dev, libxml2-dev
@@ -198,7 +198,7 @@ Multi-Arch: foreign
Depends: ${misc:Depends}
Conflicts: wireshark-common (<< 1.4.0~rc2-1)
Replaces: wireshark-common (<< 1.4.0~rc2-1)
-Recommends: geoip-database, geoip-database-extra
+#Recommends: geoip-database-contrib # Only includes legacy?
Suggests: snmp-mibs-downloader
Description: network packet dissection library -- data files
The libwireshark library provides the network packet dissection services
diff --git a/debian/libwireshark-data.install b/debian/libwireshark-data.install
index 568526fc2e..b717c62e2a 100644
--- a/debian/libwireshark-data.install
+++ b/debian/libwireshark-data.install
@@ -1,3 +1,3 @@
usr/share/wireshark/*
etc/wireshark/init.lua
-debian/geoip_db_paths /usr/share/wireshark
+debian/maxmind_db_paths /usr/share/wireshark
diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols
index a1bdc2116f..ea313849ce 100644
--- a/debian/libwireshark0.symbols
+++ b/debian/libwireshark0.symbols
@@ -699,12 +699,6 @@ libwireshark.so.0 libwireshark0 #MINVER#
gcamel_StatSRT@Base 1.9.1
gcp_cmd_type@Base 1.9.1
gcp_term_types@Base 1.9.1
- geoip_db_get_paths@Base 1.9.1
- geoip_db_lookup_ipv4@Base 1.9.1
- geoip_db_lookup_ipv6@Base 1.9.1
- geoip_db_name@Base 1.9.1
- geoip_db_num_dbs@Base 1.9.1
- geoip_db_type@Base 1.9.1
get_8859_1_string@Base 1.12.0~rc1
get_CDR_any@Base 1.9.1
get_CDR_boolean@Base 1.9.1
@@ -902,6 +896,9 @@ libwireshark.so.0 libwireshark0 #MINVER#
make_printable_string@Base 1.9.1
manually_resolve_cleanup@Base 1.12.0~rc1
mark_frame_as_depended_upon@Base 1.9.1
+ maxmind_db_get_paths@Base 2.5.0
+ maxmind_db_lookup_ipv4@Base 2.5.0
+ maxmind_db_lookup_ipv6@Base 2.5.0
mbim_register_uuid_ext@Base 1.12.0~rc1
memory_usage_component_register@Base 1.12.0~rc1
memory_usage_gc@Base 1.12.0~rc1
diff --git a/debian/geoip_db_paths b/debian/maxmind_db_paths
index 0ca498c9b8..0ca498c9b8 100644
--- a/debian/geoip_db_paths
+++ b/debian/maxmind_db_paths
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index c0cf6c11fc..798c49ee20 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -57,10 +57,12 @@ else()
)
endif()
+pod2manhtml(${CMAKE_CURRENT_BINARY_DIR}/wireshark 1)
+
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/androiddump 1)
-pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/udpdump 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/capinfos 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/captype 1)
+pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/ciscodump 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/dftest 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/dumpcap 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/editcap 1)
@@ -70,14 +72,17 @@ pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/randpktdump 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/rawshark 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/reordercap 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/sshdump 1)
-pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/ciscodump 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/text2pcap 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/tshark 1)
-pod2manhtml(${CMAKE_CURRENT_BINARY_DIR}/wireshark 1)
+pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/udpdump 1)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/extcap 4)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/wireshark-filter 4)
+if(MAXMINDDB_FOUND)
+ pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/mmdbresolve 1)
+endif()
+
if (BUILD_corbaidl2wrs)
pod2manhtml(${CMAKE_CURRENT_SOURCE_DIR}/idl2wrs 1)
endif()
@@ -88,10 +93,10 @@ endif()
set(MAN1_INSTALL_FILES
${CMAKE_CURRENT_BINARY_DIR}/androiddump.1
- ${CMAKE_CURRENT_BINARY_DIR}/udpdump.1
${CMAKE_CURRENT_BINARY_DIR}/capinfos.1
${CMAKE_CURRENT_BINARY_DIR}/captype.1
${CMAKE_CURRENT_BINARY_DIR}/ciscodump.1
+ ${CMAKE_CURRENT_BINARY_DIR}/ciscodump.1
${CMAKE_CURRENT_BINARY_DIR}/dftest.1
${CMAKE_CURRENT_BINARY_DIR}/dumpcap.1
${CMAKE_CURRENT_BINARY_DIR}/editcap.1
@@ -101,12 +106,16 @@ set(MAN1_INSTALL_FILES
${CMAKE_CURRENT_BINARY_DIR}/rawshark.1
${CMAKE_CURRENT_BINARY_DIR}/reordercap.1
${CMAKE_CURRENT_BINARY_DIR}/sshdump.1
- ${CMAKE_CURRENT_BINARY_DIR}/ciscodump.1
${CMAKE_CURRENT_BINARY_DIR}/text2pcap.1
${CMAKE_CURRENT_BINARY_DIR}/tshark.1
+ ${CMAKE_CURRENT_BINARY_DIR}/udpdump.1
${CMAKE_CURRENT_BINARY_DIR}/wireshark.1
)
+if(MAXMINDDB_FOUND)
+ list(APPEND MAN1_INSTALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/mmdbresolve.1)
+endif()
+
if (BUILD_corbaidl2wrs)
list(APPEND MAN1_INSTALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/idl2wrs.1)
endif()
@@ -132,10 +141,10 @@ add_custom_target(manpages DEPENDS
set(HTML_INSTALL_FILES
${CMAKE_CURRENT_BINARY_DIR}/androiddump.html
- ${CMAKE_CURRENT_BINARY_DIR}/udpdump.html
${CMAKE_CURRENT_BINARY_DIR}/capinfos.html
${CMAKE_CURRENT_BINARY_DIR}/captype.html
${CMAKE_CURRENT_BINARY_DIR}/ciscodump.html
+ ${CMAKE_CURRENT_BINARY_DIR}/ciscodump.html
${CMAKE_CURRENT_BINARY_DIR}/dftest.html
${CMAKE_CURRENT_BINARY_DIR}/dumpcap.html
${CMAKE_CURRENT_BINARY_DIR}/editcap.html
@@ -146,13 +155,17 @@ set(HTML_INSTALL_FILES
${CMAKE_CURRENT_BINARY_DIR}/rawshark.html
${CMAKE_CURRENT_BINARY_DIR}/reordercap.html
${CMAKE_CURRENT_BINARY_DIR}/sshdump.html
- ${CMAKE_CURRENT_BINARY_DIR}/ciscodump.html
${CMAKE_CURRENT_BINARY_DIR}/text2pcap.html
${CMAKE_CURRENT_BINARY_DIR}/tshark.html
- ${CMAKE_CURRENT_BINARY_DIR}/wireshark.html
+ ${CMAKE_CURRENT_BINARY_DIR}/udpdump.html
${CMAKE_CURRENT_BINARY_DIR}/wireshark-filter.html
+ ${CMAKE_CURRENT_BINARY_DIR}/wireshark.html
)
+if(MAXMINDDB_FOUND)
+ list(APPEND HTML_INSTALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/mmdbresolve.html)
+endif()
+
if (BUILD_corbaidl2wrs)
list(APPEND HTML_INSTALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/idl2wrs.html)
endif()
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7c5b31ca15..c88ebc7bc4 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -65,7 +65,8 @@ man1_MANS = \
@ciscodump_man@ \
@sshdump_man@ \
@randpktdump_man@ \
- @udpdump_man@
+ @udpdump_man@ \
+ @mmdbresolve_man@
man4_MANS = \
@extcap_man@ \
@@ -81,7 +82,7 @@ pkgdata_DATA = AUTHORS-SHORT $(top_srcdir)/docbook/ws.css wireshark.html \
tshark.html wireshark-filter.html capinfos.html captype.html ciscodump.html \
editcap.html mergecap.html reordercap.html text2pcap.html dumpcap.html \
androiddump.html sshdump.html randpktdump.html rawshark.html dftest.html \
- randpkt.html extcap.html udpdump.html
+ randpkt.html extcap.html udpdump.html mmdbresolve.html
#
# Build the short version of the authors file for the about dialog
@@ -278,6 +279,13 @@ udpdump.html: udpdump.pod ../config.h $(top_srcdir)/docbook/ws.css
--noindex \
$(srcdir)/udpdump.pod > udpdump.html
+mmdbresolve.html: mmdbresolve.pod ../config.h $(top_srcdir)/docbook/ws.css
+ $(AM_V_POD2HTML)$(POD2HTML) \
+ --title="mmdbresolve - The Wireshark Network Analyzer $(VERSION)" \
+ --css=$(POD_CSS_URL) \
+ --noindex \
+ $(srcdir)/mmdbresolve.pod > mmdbresolve.html
+
CLEANFILES = \
wireshark.pod \
*.1 \
@@ -340,6 +348,7 @@ EXTRA_DIST = \
text2pcap.pod \
tshark.pod \
udpdump.pod \
+ mmdbresolve.pod \
wireshark-filter.pod \
wireshark.pod.template \
CMakeLists.txt
diff --git a/doc/mmdbresolve.pod b/doc/mmdbresolve.pod
new file mode 100644
index 0000000000..43a827e448
--- /dev/null
+++ b/doc/mmdbresolve.pod
@@ -0,0 +1,69 @@
+
+=head1 NAME
+
+mmdbresolve - Read IPv4 and IPv6 addresses and print their IP geolocation information.
+
+=head1 SYNOPSIS
+
+B<mmdbresolve>
+S<B<-f E<lt>dbfileE<gt>>>
+S<[ B<-f E<lt>dbfileE<gt>> ]>
+I<...>
+
+=head1 DESCRIPTION
+
+B<mmdbresolve> reads IPv4 and IPv6 addresses on stdin and prints their IP geolocation information
+on stdout. Each input line must contain exactly one address. Output is in INI format, with a section
+delimiter named after the query address followed by a set of "key: value" pairs. A comment
+beginning with "# End" is appended to each section.
+
+At startup an "[init]" section is printed that shows the status of each datbase and of mmdbresolve
+itself.
+
+=head1 OPTIONS
+
+=over 4
+
+=item -f
+
+Path to a MaxMind Database file. Multiple databases may be specified.
+
+=back
+
+=head1 EXAMPLES
+
+To resolve a single address:
+
+ echo 4.4.4.4 | mmdbresolve -f /usr/share/GeoIP/GeoLite2-City.mmdb
+
+ Example output:
+[init]
+db.0.path: /usr/share/GeoIP/GeoLite2-City.mmdb
+db.0.status: OK
+mmdbresolve.status: true
+# End init
+[4.4.4.4]
+# GeoLite2-City
+country.iso_code: US
+country.names.en: United States
+location.latitude: 37.751000
+location.longitude: -97.822000
+# End 4.4.4.4
+
+=head1 SEE ALSO
+
+wireshark(1), tshark(1)
+
+=head1 NOTES
+
+B<mmdbresolve> is part of the B<Wireshark> distribution. The latest version
+of B<Wireshark> can be found at L<https://www.wireshark.org>.
+
+HTML versions of the Wireshark project man pages are available at:
+L<https://www.wireshark.org/docs/man-pages>.
+
+=head1 AUTHORS
+
+ Original Author
+ ---------------
+ Gerald Combs <gerald[AT]wireshark.org>
diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc
index b2db89ff99..073d634a1d 100644
--- a/docbook/release-notes.asciidoc
+++ b/docbook/release-notes.asciidoc
@@ -40,6 +40,8 @@ The following features are new (or have been significantly updated)
since version 2.5.0:
* HTTP Referer statistics are now supported.
+* Wireshark now supports MaxMind DB files. Support for GeoIP and GeoLite
+ Legacy databases has been removed.
* The Windows packages are now built using Microsoft Visual Studio 2017.
* The IP map feature (the “Map” button in the “Endpoints” dialog) has been removed.
diff --git a/docbook/wsdg_src/WSDG_chapter_libraries.asciidoc b/docbook/wsdg_src/WSDG_chapter_libraries.asciidoc
index 247649d5a7..c184f867cf 100644
--- a/docbook/wsdg_src/WSDG_chapter_libraries.asciidoc
+++ b/docbook/wsdg_src/WSDG_chapter_libraries.asciidoc
@@ -353,26 +353,19 @@ The PortAudio sources are downloaded from
https://anonsvn.wireshark.org/wireshark-win32-libs/trunk/packages/[] and compiled
locally.
-[[ChLibsGeoIP]]
+[[ChLibsMaxMindDB]]
-=== GeoIP (optional)
+=== MaxMindDB (optional)
-MaxMind Inc. publishes a GeoIP database for use in open source software.
-It can be used to map IP addresses to geographical locations.
+MaxMind Inc. publishes a set of IP geolocation databases and related
+open source libraries. They can be used to map IP addresses to
+geographical locations and other information.
-[[ChLibsUnixGeoIP]]
-
-==== Unix
-
-If this library isn't already installed or available as a
+If libmaxminddb library isn't already installed or available as a
package for your platform, you can get it at
-http://www.maxmind.com/app/c[].
+https://github.com/maxmind/libmaxminddb[].
-[[ChLibsWin32GeoIP]]
-
-==== Win32 MSVC
-
-We provide a package cross-compiled using MinGW32 at
+We provide a package for Windows at
https://anonsvn.wireshark.org/wireshark-win32-libs/trunk/packages/[].
[[ChLibsWinSparkle]]
diff --git a/docbook/wsug_src/WSUG_chapter_customize.asciidoc b/docbook/wsug_src/WSUG_chapter_customize.asciidoc
index 96e443468e..66ea7288da 100644
--- a/docbook/wsug_src/WSUG_chapter_customize.asciidoc
+++ b/docbook/wsug_src/WSUG_chapter_customize.asciidoc
@@ -746,7 +746,7 @@ Configuration files stored in the Profiles:
* ESS Category Attributes (ess_category_attributes)
(<<ChEssCategoryAttributes>>)
-* GeoIP Database Paths (geoip_db_paths) (<<ChGeoIPDbPaths>>)
+* MaxMind Database Paths (maxmind_db_paths) (<<ChMaxMindDbPaths>>)
* K12 Protocols (k12_protos) (<<ChK12ProtocolsSection>>)
@@ -876,28 +876,35 @@ The value (Label And Cert Value) representing the Category.
Name::
The textual representation for the value.
-[[ChGeoIPDbPaths]]
+[[ChMaxMindDbPaths]]
-=== GeoIP Database Paths
+=== MaxMind Database Paths
-If your copy of Wireshark supports link:http://www.maxmind.com/[MaxMind’s]
-GeoIP library, you can use their databases to match IP addresses to countries,
-cites, autonomous system numbers, ISPs, and other bits of information. Some
-databases are link:http://www.maxmind.com/download/geoip/database/[available
-at no cost], while others require a licensing fee. See
-link:http://www.maxmind.com/app/ip-location[the MaxMind web site] for more
-information.
+If your copy of Wireshark supports
+link:http://www.maxmind.com/[MaxMind’s] MaxMindDB library, you can use
+their databases to match IP addresses to countries, cites, autonomous
+system numbers, and other bits of information. Some databases are
+link:https://dev.maxmind.com/geoip/geoip2/downloadable/[available at no
+cost], while others require a licensing fee. See
+link:http://www.maxmind.com/[the MaxMind web site] for more information.
This table is handled by an <<ChUserTable>> with the following fields.
Database pathname::
-This specifies a directory containing GeoIP data files. Any files beginning with
-_Geo_ and ending with _.dat_ will be automatically loaded. A total of 8 files
-can be loaded.
-+
-The locations for your data files are up to you, but `/usr/share/GeoIP` (Linux),
-`C:\GeoIP` (Windows), `C:\Program Files\Wireshark\GeoIP` (Windows) might be good
-choices.
+This specifies a directory containing MaxMind data files. Any files
+ending with _.mmdb_ will be automatically loaded.
+
+The locations for your data files are up to you, but `/usr/share/GeoIP`
+and `/var/lib/GeoIP` are common on Linux and `C:\ProgramData\GeoIP`,
+`C:\Program Files\Wireshark\GeoIP` might be good choices on Windows.
+
+[[ChGeoIPDbPaths]]
+
+Previous versions of Wireshark supported MaxMind's original GeoIP Legacy
+database format. They were configured similar to MaxMindDB files above,
+except GeoIP files must begin with _Geo_ and end with _.dat_. They are
+no longer supported and MaxMind stopped distributing GeoLite Legacy
+databases in April 2018.
[[ChIKEv2DecryptionSection]]
diff --git a/docbook/wsug_src/WSUG_chapter_statistics.asciidoc b/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
index 6580c5c090..607ccfc9d7 100644
--- a/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
+++ b/docbook/wsug_src/WSUG_chapter_statistics.asciidoc
@@ -255,11 +255,12 @@ related page can still be selected).
Each row in the list shows the statistical values for exactly one endpoint.
-_Name resolution_ will be done if selected in the window and if it is active for
-the specific protocol layer (MAC layer for the selected Ethernet endpoints
-page). _Limit to display filter_ will only show conversations matching the
-current display filter. Note that in this example we have GeoIP configured which
-gives us extra geographic columns. See <<ChGeoIPDbPaths>> for more information.
+_Name resolution_ will be done if selected in the window and if it is
+active for the specific protocol layer (MAC layer for the selected
+Ethernet endpoints page). _Limit to display filter_ will only show
+conversations matching the current display filter. Note that in this
+example we have MaxMind DB configured which gives us extra geographic
+columns. See <<ChMaxMindDbPaths>> for more information.
The btn:[Copy] button will copy the list values to the clipboard in CSV
(Comma Separated Values) or YAML format.
diff --git a/docbook/wsug_src/WSUG_chapter_use.asciidoc b/docbook/wsug_src/WSUG_chapter_use.asciidoc
index fd21e7afa2..1ea8d65038 100644
--- a/docbook/wsug_src/WSUG_chapter_use.asciidoc
+++ b/docbook/wsug_src/WSUG_chapter_use.asciidoc
@@ -893,9 +893,10 @@ There is a context menu (right mouse click) available. See details in
Some protocol fields have special meanings.
* *Generated fields.* Wireshark itself will generate additional protocol
- information which isn’t present in the captured data. This information is
- enclosed in square brackets (“[” and “]”). Generated information includes
- response times, TCP analysis, GeoIP information, and checksum validation.
+ information which isn’t present in the captured data. This information
+ is enclosed in square brackets (“[” and “]”). Generated information
+ includes response times, TCP analysis, IP geolocation information, and
+ checksum validation.
* *Links.* If Wireshark detects a relationship to another packet in the capture
file it will generate a link to that packet. Links are underlined and
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",
diff --git a/mmdbresolve.c b/mmdbresolve.c
new file mode 100644
index 0000000000..3568a0b4b9
--- /dev/null
+++ b/mmdbresolve.c
@@ -0,0 +1,169 @@
+/* Read IPv4 and IPv6 addresses on stdin and print their MMDB entries on stdout.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This progam uses the MaxMind DB library (libmaxminddb) and MUST be
+ * compatible with its license (Apache 2.0).
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#include <maxminddb.h>
+
+#define MAX_ADDR_LEN 46
+#define MMDBR_STRINGIFY(x) MMDBR_STRINGIFY_S(x)
+#define MMDBR_STRINGIFY_S(s) #s
+#define OUT_BUF_SIZE 65536
+
+static const char *co_iso_key[] = {"country", "iso_code", NULL};
+static const char *co_name_key[] = {"country", "names", "en", NULL};
+static const char *ci_name_key[] = {"city", "names", "en", NULL};
+static const char *asn_o_key[] = {"autonomous_system_organization", NULL};
+static const char *asn_key[] = {"autonomous_system_number", NULL};
+static const char *l_lat_key[] = {"location", "latitude", NULL};
+static const char *l_lon_key[] = {"location", "longitude", NULL};
+static const char *empty_key[] = {NULL};
+
+static const char **lookup_keys[] = {
+ co_iso_key,
+ co_name_key,
+ ci_name_key,
+ asn_o_key,
+ asn_key,
+ l_lat_key,
+ l_lon_key,
+ empty_key
+};
+
+static void print_usage(void) {
+ fprintf(stderr, "Usage: mmdbresolve -f db_file [-f db_file ...]\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ char addr_str[MAX_ADDR_LEN+1];
+ size_t mmdb_count = 0;
+ MMDB_s *mmdbs = NULL;
+ int mmdb_err;
+ int opt;
+ const char *optstring = "f:";
+
+ char *out_buf = (char *) malloc(OUT_BUF_SIZE);
+ setvbuf(stdout, out_buf, _IOFBF, OUT_BUF_SIZE);
+
+ fprintf(stdout, "[init]\n");
+
+ while ((opt = getopt(argc, argv, optstring)) != -1) {
+ if (opt == 'f') {
+ MMDB_s try_mmdb;
+ mmdb_err = MMDB_open(optarg, 0, &try_mmdb);
+ fprintf(stdout, "db.%zd.path: %s\n", mmdb_count, optarg);
+ fprintf(stdout, "db.%zd.status: ", mmdb_count);
+ if (mmdb_err == MMDB_SUCCESS) {
+ mmdb_count++;
+ mmdbs = (MMDB_s *) realloc(mmdbs, mmdb_count * sizeof(MMDB_s));
+ mmdbs[mmdb_count - 1] = try_mmdb;
+ fprintf(stdout, "OK\n");
+ fprintf(stdout, "db.%zd.type: %s\n", mmdb_count, mmdbs[mmdb_count - 1].metadata.database_type);
+ } else {
+ fprintf(stdout, "ERROR %s\n", MMDB_strerror(mmdb_err));
+ }
+ };
+ }
+
+ fprintf(stdout, "mmdbresolve.status: %s\n", mmdb_count > 0 ? "true": "false");
+ fprintf(stdout, "# End init\n");
+ fflush(stdout);
+
+ if (mmdb_count < 1) {
+ print_usage();
+ exit(1);
+ }
+
+ while (!feof(stdin)) {
+ int gai_err;
+
+ if (fscanf(stdin, "%" MMDBR_STRINGIFY(MAX_ADDR_LEN) "s", addr_str) < 1) {
+ continue;
+ }
+ fprintf(stdout, "[%s]\n", addr_str);
+
+ for (size_t mmdb_idx = 0; mmdb_idx < mmdb_count; mmdb_idx++) {
+ fprintf(stdout, "# %s\n", mmdbs[mmdb_idx].metadata.database_type);
+ MMDB_lookup_result_s result = MMDB_lookup_string(&mmdbs[mmdb_idx], addr_str, &gai_err, &mmdb_err);
+
+ if (result.found_entry && gai_err == 0 && mmdb_err == MMDB_SUCCESS) {
+ for (size_t key_idx = 0; lookup_keys[key_idx][0]; key_idx++) {
+ MMDB_entry_data_s entry_data;
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_keys[key_idx]);
+ if (status == MMDB_SUCCESS && entry_data.has_data) {
+ char *sep = "";
+ for (int idx = 0; lookup_keys[key_idx][idx] != 0; idx++) {
+ fprintf(stdout, "%s%s", sep, lookup_keys[key_idx][idx]);
+ sep = ".";
+ }
+ switch (entry_data.type) {
+ case MMDB_DATA_TYPE_UTF8_STRING:
+ {
+ char len_fmt[12]; // : %.xxxxxs\n\0
+ snprintf(len_fmt, 11, ": %%.%us\n", entry_data.data_size);
+ fprintf(stdout, len_fmt, entry_data.utf8_string);
+ }
+ break;
+ case MMDB_DATA_TYPE_UINT16:
+ fprintf(stdout, ": %u\n", entry_data.uint16);
+ break;
+ case MMDB_DATA_TYPE_UINT32:
+ fprintf(stdout, ": %u\n", entry_data.uint32);
+ break;
+ case MMDB_DATA_TYPE_INT32:
+ fprintf(stdout, ": %d\n", entry_data.int32);
+ break;
+ case MMDB_DATA_TYPE_BOOLEAN:
+ fprintf(stdout, ": %s\n", entry_data.boolean ? "True" : "False");
+ break;
+ case MMDB_DATA_TYPE_DOUBLE:
+ fprintf(stdout, ": %f\n", entry_data.double_value);
+ break;
+ case MMDB_DATA_TYPE_FLOAT:
+ fprintf(stdout, ": %f\n", entry_data.float_value);
+ break;
+ default:
+ fprintf(stdout, ": UNKNOWN (%d)\n", entry_data.type);
+ }
+ }
+ }
+ } else {
+ // dump error info.
+ }
+ }
+ fprintf(stdout, "# End %s\n", addr_str);
+ fflush(stdout);
+ }
+
+ return 0;
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/packaging/macosx/Scripts/cli-postinstall.sh b/packaging/macosx/Scripts/cli-postinstall.sh
index f83cf4faac..4c74a42847 100755
--- a/packaging/macosx/Scripts/cli-postinstall.sh
+++ b/packaging/macosx/Scripts/cli-postinstall.sh
@@ -7,6 +7,7 @@ BINARIES="
dumpcap
editcap
mergecap
+ mmdbresolve
randpkt
rawshark
text2pcap
diff --git a/packaging/nsis/CMakeLists.txt b/packaging/nsis/CMakeLists.txt
index 6237f5b382..ce6024ad7b 100644
--- a/packaging/nsis/CMakeLists.txt
+++ b/packaging/nsis/CMakeLists.txt
@@ -139,10 +139,13 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/config.nsh" "${_config_nsh_contents}")
# all-manifest.nsh. Can be created at configure time.
set(_all_manifest "${CMAKE_CURRENT_BINARY_DIR}/all-manifest.nsh")
set(_all_manifest_contents "# Files required for all sections. Generated by CMake.\n")
-foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
+foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
- ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
+ ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL}
+ ${ZLIB_DLL}
+ # Needed for mmdbresolve
+ ${MAXMINDDB_DLL}
)
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
endforeach()
diff --git a/packaging/nsis/uninstall.nsi b/packaging/nsis/uninstall.nsi
index f552ffed74..74d2e28eae 100644
--- a/packaging/nsis/uninstall.nsi
+++ b/packaging/nsis/uninstall.nsi
@@ -125,22 +125,22 @@ SetShellVarContext all
!insertmacro IsWiresharkRunning
Push "${EXECUTABLE_MARKER}"
+Push "${PROGRAM_NAME}"
Push "androiddump"
+Push "capinfos"
Push "ciscodump"
-Push "sshdump"
-Push "udpdump"
+Push "dftest"
Push "dumpcap"
-Push "${PROGRAM_NAME}"
-Push "tshark"
-Push "qtshark"
Push "editcap"
-Push "text2pcap"
Push "mergecap"
+Push "mmdbresolve"
Push "randpktdump"
-Push "reordercap"
-Push "capinfos"
Push "rawshark"
-Push "dftest"
+Push "reordercap"
+Push "sshdump"
+Push "text2pcap"
+Push "tshark"
+Push "udpdump"
Pop $EXECUTABLE
${DoUntil} $EXECUTABLE == ${EXECUTABLE_MARKER}
diff --git a/packaging/nsis/wireshark.nsi b/packaging/nsis/wireshark.nsi
index 21c67e31a5..404c6a326d 100644
--- a/packaging/nsis/wireshark.nsi
+++ b/packaging/nsis/wireshark.nsi
@@ -1117,6 +1117,14 @@ File "${STAGING_DIR}\rawshark.exe"
File "${STAGING_DIR}\rawshark.html"
SectionEnd
+Section /o "MMDBResolve" SecMMDBResolve
+;-------------------------------------------
+SetOutPath $INSTDIR
+File "${STAGING_DIR}\mmdbresolve.html"
+SetOutPath $INSTDIR
+File "${STAGING_DIR}\mmdbresolve.exe"
+SectionEnd
+
Section /o "Androiddump" SecAndroiddumpinfos
;-------------------------------------------
SetOutPath $INSTDIR
diff --git a/packaging/rpm/SPECS/wireshark.spec.in b/packaging/rpm/SPECS/wireshark.spec.in
index 024e9fd4b2..3ddd8a00e8 100644
--- a/packaging/rpm/SPECS/wireshark.spec.in
+++ b/packaging/rpm/SPECS/wireshark.spec.in
@@ -252,8 +252,8 @@ Requires: libxml2
%endif
# Uncomment these if you want to be sure you get them...
-#BuildRequires: GeoIP-devel
-#Requires: GeoIP
+#BuildRequires: libmaxminddb-devel
+#Requires: libmaxminddb
# Add this for more readable fonts on some distributions/versions
#Requires: dejavu-sans-mono-fonts
diff --git a/packaging/wix/CMakeLists.txt b/packaging/wix/CMakeLists.txt
index ec07991dc7..352e53f854 100644
--- a/packaging/wix/CMakeLists.txt
+++ b/packaging/wix/CMakeLists.txt
@@ -136,10 +136,13 @@ file(APPEND "${_all_manifest_wix}" "<?include InputPaths.wxi ?>\n")
file(APPEND "${_all_manifest_wix}" " <Fragment>\n")
file(APPEND "${_all_manifest_wix}" " <DirectoryRef Id=\"INSTALLFOLDER\">\n")
SET(unique_component "")
-foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
+foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
- ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
+ ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL}
+ ${ZLIB_DLL}
+ # Required for mmdbresolve
+ ${MAXMINDDB_DLL}
)
#ensure uniqueness of files
IF(NOT "${unique_component}" MATCHES "(^|;)${_dll}(;|$)")
@@ -161,10 +164,12 @@ file(APPEND "${_all_manifest_wix}" " </Fragment>\n")
file(APPEND "${_all_manifest_wix}" " <Fragment>\n")
file(APPEND "${_all_manifest_wix}" " <ComponentGroup Id=\"CG.RequiredDependencies\">\n")
SET(unique_file "")
-foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
+foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${ZLIB_DLL}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
- ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
+ ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLL} ${WINSPARKLE_DLL}
+ # mmdbresolve
+ ${MAXMINDDB_DLL}
)
#ensure uniqueness of files
IF(NOT "${unique_file}" MATCHES "(^|;)${_dll}(;|$)")
diff --git a/packaging/wix/ComponentGroups.wxi b/packaging/wix/ComponentGroups.wxi
index 92fc09b157..8631c805d2 100644
--- a/packaging/wix/ComponentGroups.wxi
+++ b/packaging/wix/ComponentGroups.wxi
@@ -433,6 +433,24 @@
</ComponentGroup>
</Fragment>
+ <!-- MMDBResolve -->
+ <Fragment>
+ <DirectoryRef Id="INSTALLFOLDER">
+ <Component Id="cmpMmdbresolve_exe" Guid="*">
+ <File Id="filMmdbresolve_exe" KeyPath="yes" Source="$(var.Staging.Dir)\mmdbresolve.exe" />
+ </Component>
+ <Component Id="cmpMmdbresolve_html" Guid="*">
+ <File Id="filMmdbresolve_html" KeyPath="yes" Source="$(var.Staging.Dir)\rawshark.html" />
+ </Component>
+ </DirectoryRef>
+ </Fragment>
+ <Fragment>
+ <ComponentGroup Id="CG.Tools.MMDBResolve">
+ <ComponentRef Id="cmpMmdbresolve_exe" />
+ <ComponentRef Id="cmpMmdbresolve_html" />
+ </ComponentGroup>
+ </Fragment>
+
<!-- Androiddump -->
<Fragment>
<DirectoryRef Id="dirExtcap">
diff --git a/packaging/wix/Features.wxi b/packaging/wix/Features.wxi
index 891d689b5e..277a713a14 100644
--- a/packaging/wix/Features.wxi
+++ b/packaging/wix/Features.wxi
@@ -81,6 +81,9 @@
<Feature Id="Fe.Tools.Rawshark" Title="Rawshark" Level="1" AllowAdvertise="yes" Display="expand" Description="Raw packet filter.">
<ComponentGroupRef Id="CG.Tools.Rawshark" />
</Feature>
+ <Feature Id="Fe.Tools.MMDBResolve" Title="MMDBResolve" Level="1" AllowAdvertise="yes" Display="expand" Description="IP geolocation database resolution.">
+ <ComponentGroupRef Id="CG.Tools.MMDBResolve" />
+ </Feature>
<Feature Id="Fe.Tools.Androiddump" Title="Androiddump" Level="2" AllowAdvertise="yes" Display="expand" Description="Provide capture interfaces from Android devices.">
<ComponentGroupRef Id="CG.Tools.Androiddump" />
</Feature>
diff --git a/tools/Get-HardenFlags.ps1 b/tools/Get-HardenFlags.ps1
index 7503f13826..5f45cab3e8 100644
--- a/tools/Get-HardenFlags.ps1
+++ b/tools/Get-HardenFlags.ps1
@@ -88,7 +88,6 @@ $SoftBins = (
"libgcrypt-20.dll",
"libgdk-win32-2.0-0.dll",
"libgdk_pixbuf-2.0-0.dll",
- "libGeoIP-1.dll",
"libgio-2.0-0.dll",
"libglib-2.0-0.dll",
"libgmodule-2.0-0.dll",
@@ -103,6 +102,7 @@ $SoftBins = (
"libjasper-1.dll",
"libjpeg-8.dll",
"liblzma-5.dll",
+ "libmaxminddb.dll",
"libnettle-4-6.dll",
"libp11-kit-0.dll",
"libpango-1.0-0.dll",
diff --git a/tools/debian-setup.sh b/tools/debian-setup.sh
index 2b7c672aac..44abcf76c1 100755
--- a/tools/debian-setup.sh
+++ b/tools/debian-setup.sh
@@ -55,7 +55,7 @@ BASIC_LIST="libgtk2.0-dev libpcap-dev bison flex make automake \
ADDITIONAL_LIST="libnl-3-dev qttools5-dev qttools5-dev-tools libgtk-3-dev \
libc-ares-dev libkrb5-dev libqt5svg5-dev libsmi2-dev \
- portaudio19-dev asciidoctor libsbc-dev libgeoip-dev \
+ portaudio19-dev asciidoctor libsbc-dev \
qtmultimedia5-dev liblua5.2-dev libnl-cli-3-dev \
libparse-yapp-perl qt5-default cmake libcap-dev \
liblz4-dev libsnappy-dev libspandsp-dev libxml2-dev \
@@ -92,6 +92,10 @@ add_package ADDITIONAL_LIST libgnutls28-dev ||
add_package ADDITIONAL_LIST libgnutls-dev ||
echo "libgnutls28-dev and libgnutls-dev are unavailable" >&2
+# mmdbresolve
+add_package ADDITIONAL_LIST libmaxminddb-dev ||
+echo "libmaxminddb-dev is unavailable" >&2
+
ACTUAL_LIST=$BASIC_LIST
# Now arrange for optional support libraries
diff --git a/tools/install_rpms_for_devel.sh b/tools/install_rpms_for_devel.sh
index f6ac3f077c..c2362e70ff 100755
--- a/tools/install_rpms_for_devel.sh
+++ b/tools/install_rpms_for_devel.sh
@@ -45,7 +45,6 @@ then
NGHTTP2="nghttp2"
# SUSE doesn't split the pod2* commands into a separate package like RH
PERLPODS=""
- GEOIP="libGeoIP-devel"
GNUTLS="libgnutls-devel"
GETTEXT="gettext-tools"
QT5="libqt5-linguist-devel libqt5-qtsvg-devel libqt5-qtmultimedia-devel
@@ -76,10 +75,11 @@ else
CARES="c-ares-devel c-ares"
NGHTTP2="libnghttp2"
PERLPODS="perl-podlators"
- GEOIP="GeoIP-devel"
GNUTLS="gnutls-devel"
GETTEXT="gettext-devel"
QT5="qt5-linguist qt5-qtsvg-devel"
+ # mmdbresolve
+ MAXMINDDB="libmaxminddb-devel"
fi
PKGS="autoconf automake libtool gcc flex bison python perl $GLIB2
@@ -87,7 +87,7 @@ $PCAP $ZLIB lua-devel lua $CARES $GTK3 $GTK2 desktop-file-utils $QT fop
asciidoc git git-review $PERLPODS"
PKGS_OPT="libnl3-devel libnghttp2-devel $NGHTTP2 $SNAPPY $LZ4 libcap $CAP_PROGS
-libcap-devel $GEOIP libgcrypt-devel $GNUTLS $GETTEXT libssh-devel
+libcap-devel $MAXMINDDB libgcrypt-devel $GNUTLS $GETTEXT libssh-devel
krb5-devel perl-Parse-Yapp sbc-devel libsmi-devel $POD2HTML $QT5 asciidoctor"
echo "Run this command (as root):"
diff --git a/tools/macos-setup.sh b/tools/macos-setup.sh
index a76ff3271e..30eb3d8928 100755
--- a/tools/macos-setup.sh
+++ b/tools/macos-setup.sh
@@ -155,12 +155,13 @@ SNAPPY_VERSION=1.1.4
LIBXML2_VERSION=2.9.4
LZ4_VERSION=1.7.5
SBC_VERSION=1.3
-GEOIP_VERSION=1.6.10
CARES_VERSION=1.12.0
# Redmine used by libssh.org numbers the files available for download,
# so using version only isn't enough
LIBSSH_VERSION=0.7.4
LIBSSH_FILENUM=210
+# mmdbresolve
+MAXMINDDB_VERSION=1.3.2
NGHTTP2_VERSION=1.21.0
SPANDSP_VERSION=0.0.6
@@ -1687,67 +1688,42 @@ uninstall_sbc() {
fi
}
-install_geoip() {
- if [ "$GEOIP_VERSION" -a ! -f geoip-$GEOIP_VERSION-done ] ; then
- echo "Downloading, building, and installing GeoIP API:"
- GEOIP_MAJOR_VERSION="`expr $GEOIP_VERSION : '\([0-9][0-9]*\).*'`"
- GEOIP_MINOR_VERSION="`expr $GEOIP_VERSION : '[0-9][0-9]*\.\([0-9][0-9]*\).*'`"
- GEOIP_DOTDOT_VERSION="`expr $GEOIP_VERSION : '[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*'`"
- if [[ $GEOIP_MAJOR_VERSION -gt 1 ||
- ($GEOIP_MAJOR_VERSION -eq 1 && $GEOIP_MINOR_VERSION -gt 6) ||
- ($GEOIP_MAJOR_VERSION -eq 1 && $GEOIP_MINOR_VERSION -eq 6 && $GEOIP_DOTDOT_VERSION -ge 1) ]]
- then
- #
- # Starting with GeoIP 1.6.1, the tarballs are on GitHub.
- #
- [ -f GeoIP-$GEOIP_VERSION.tar.gz ] || curl -L -O https://github.com/maxmind/geoip-api-c/releases/download/v$GEOIP_VERSION/GeoIP-$GEOIP_VERSION.tar.gz || exit 1
- else
- [ -f GeoIP-$GEOIP_VERSION.tar.gz ] || curl -L -O http://geolite.maxmind.com/download/geoip/api/c/GeoIP-$GEOIP_VERSION.tar.gz || exit 1
- fi
+install_maxminddb() {
+ if [ "$MAXMINDDB_VERSION" -a ! -f maxminddb-$MAXMINDDB_VERSION-done ] ; then
+ echo "Downloading, building, and installing MaxMindDB API:"
+ MAXMINDDB_MAJOR_VERSION="`expr $MAXMINDDB_VERSION : '\([0-9][0-9]*\).*'`"
+ MAXMINDDB_MINOR_VERSION="`expr $MAXMINDDB_VERSION : '[0-9][0-9]*\.\([0-9][0-9]*\).*'`"
+ MAXMINDDB_DOTDOT_VERSION="`expr $MAXMINDDB_VERSION : '[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*'`"
+ [ -f libmaxminddb-$MAXMINDDB_VERSION.tar.gz ] || curl -L -O https://github.com/maxmind/libmaxminddb/releases/download/$MAXMINDDB_VERSION/libmaxminddb-$MAXMINDDB_VERSION.tar.gz || exit 1
$no_build && echo "Skipping installation" && return
- gzcat GeoIP-$GEOIP_VERSION.tar.gz | tar xf - || exit 1
- cd GeoIP-$GEOIP_VERSION
+ gzcat libmaxminddb-$MAXMINDDB_VERSION.tar.gz | tar xf - || exit 1
+ cd libmaxminddb-$MAXMINDDB_VERSION
CFLAGS="$CFLAGS $VERSION_MIN_FLAGS $SDKFLAGS" CXXFLAGS="$CXXFLAGS $VERSION_MIN_FLAGS $SDKFLAGS" LDFLAGS="$LDFLAGS $VERSION_MIN_FLAGS $SDKFLAGS" ./configure || exit 1
- #
- # Grr. Their man pages "helpfully" have an ISO 8859-1
- # copyright symbol in the copyright notice, but macOS's
- # default character encoding is UTF-8. sed on Mountain
- # Lion barfs at the "illegal character sequence" represented
- # by an ISO 8859-1 copyright symbol, as it's not a valid
- # UTF-8 sequence.
- #
- # iconv the relevant man pages into UTF-8.
- #
- for i in geoipupdate.1.in geoiplookup6.1.in geoiplookup.1.in
- do
- iconv -f iso8859-1 -t utf-8 man/"$i" >man/"$i".tmp &&
- mv man/"$i".tmp man/"$i"
- done
make $MAKE_BUILD_OPTS || exit 1
$DO_MAKE_INSTALL || exit 1
cd ..
- touch geoip-$GEOIP_VERSION-done
+ touch maxminddb-$MAXMINDDB_VERSION-done
fi
}
-uninstall_geoip() {
- if [ ! -z "$installed_geoip_version" ] ; then
- echo "Uninstalling GeoIP API:"
- cd GeoIP-$installed_geoip_version
+uninstall_maxminddb() {
+ if [ ! -z "$installed_maxminddb_version" ] ; then
+ echo "Uninstalling MaxMindDB API:"
+ cd libmaxminddb-$installed_maxminddb_version
$DO_MAKE_UNINSTALL || exit 1
make distclean || exit 1
cd ..
- rm geoip-$installed_geoip_version-done
+ rm maxminddb-$installed_maxminddb_version-done
if [ "$#" -eq 1 -a "$1" = "-r" ] ; then
#
# Get rid of the previously downloaded and unpacked version.
#
- rm -rf GeoIP-$installed_geoip_version
- rm -rf GeoIP-$installed_geoip_version.tar.gz
+ rm -rf libmaxminddb-$installed_maxminddb_version
+ rm -rf libmaxminddb-$installed_maxminddb_version.tar.gz
fi
- installed_geoip_version=""
+ installed_maxminddb_version=""
fi
}
@@ -2056,15 +2032,15 @@ install_all() {
uninstall_c_ares -r
fi
- if [ ! -z "$installed_geoip_version" -a \
- "$installed_geoip_version" != "$GEOIP_VERSION" ] ; then
- echo "Installed GeoIP API version is $installed_geoip_version"
- if [ -z "$GEOIP_VERSION" ] ; then
- echo "GeoIP is not requested"
+ if [ ! -z "$installed_maxminddb_version" -a \
+ "$installed_maxminddb_version" != "$MAXMINDDB_VERSION" ] ; then
+ echo "Installed MaxMindDB API version is $installed_maxminddb_version"
+ if [ -z "$MAXMINDDB_VERSION" ] ; then
+ echo "MaxMindDB is not requested"
else
- echo "Requested GeoIP version is $GEOIP_VERSION"
+ echo "Requested MaxMindDB version is $MAXMINDDB_VERSION"
fi
- uninstall_geoip -r
+ uninstall_maxminddb -r
fi
if [ ! -z "$installed_sbc_version" -a \
@@ -2490,7 +2466,7 @@ install_all() {
# Now we have reached a point where we can build everything including
# the GUI (Wireshark), but not with any optional features such as
# SNMP OID resolution, some forms of decryption, Lua scripting, playback
- # of audio, or GeoIP mapping of IP addresses.
+ # of audio, or MaxMindDB mapping of IP addresses.
#
# We now conditionally download optional libraries to support them;
# the default is to download them all.
@@ -2520,7 +2496,7 @@ install_all() {
install_sbc
- install_geoip
+ install_maxminddb
install_c_ares
@@ -2561,7 +2537,7 @@ uninstall_all() {
uninstall_c_ares
- uninstall_geoip
+ uninstall_maxminddb
uninstall_portaudio
@@ -2658,7 +2634,7 @@ fi
dir=`dirname $0`
cd $dir/..
-#
+#
#
# If we have SDKs available, the default target OS is the major version
# of the one we're running; get that and strip off the third component
@@ -2747,7 +2723,7 @@ then
installed_libxml2_version=`ls libxml2-*-done 2>/dev/null | sed 's/libxml2-\(.*\)-done/\1/'`
installed_lz4_version=`ls lz4-*-done 2>/dev/null | sed 's/lz4-\(.*\)-done/\1/'`
installed_sbc_version=`ls sbc-*-done 2>/dev/null | sed 's/sbc-\(.*\)-done/\1/'`
- installed_geoip_version=`ls geoip-*-done 2>/dev/null | sed 's/geoip-\(.*\)-done/\1/'`
+ installed_maxminddb_version=`ls maxminddb-*-done 2>/dev/null | sed 's/maxminddb-\(.*\)-done/\1/'`
installed_cares_version=`ls c-ares-*-done 2>/dev/null | sed 's/c-ares-\(.*\)-done/\1/'`
installed_libssh_version=`ls libssh-*-done 2>/dev/null | sed 's/libssh-\(.*\)-done/\1/'`
installed_nghttp2_version=`ls nghttp2-*-done 2>/dev/null | sed 's/nghttp2-\(.*\)-done/\1/'`
diff --git a/tools/pre-commit-ignore.conf b/tools/pre-commit-ignore.conf
index 27a860f63d..e10030d87f 100644
--- a/tools/pre-commit-ignore.conf
+++ b/tools/pre-commit-ignore.conf
@@ -18,6 +18,7 @@ epan/wmem/wmem_strbuf.c
epan/wmem/wmem_strutil.c
extcap/*
image/stock_icons/*
+mmdbresolve.c
tools/lemon/*
wsutil/file_util.h
wsutil/strptime.c
diff --git a/tools/rpm_setup.sh b/tools/rpm_setup.sh
index 4e6bf7fd54..c52afbfde8 100755
--- a/tools/rpm_setup.sh
+++ b/tools/rpm_setup.sh
@@ -121,8 +121,8 @@ echo "lz4 devel is unavailable" >&2
add_package ADDITIONAL_LIST libcap-progs || echo "cap progs are unavailable" >&2
-add_package ADDITIONAL_LIST GeoIP-devel || add_package ADDITIONAL_LIST libGeoIP-devel ||
-echo "GeoIP devel is unavailable" >&2
+add_package ADDITIONAL_LIST libmaxminddb-devel ||
+echo "MaxMind DB devel is unavailable" >&2
add_package ADDITIONAL_LIST gnutls-devel || add_package ADDITIONAL_LIST libgnutls-devel ||
echo "gnutls devel is unavailable" >&2
diff --git a/tools/win-setup.ps1 b/tools/win-setup.ps1
index ccfffd13c6..6403aa42de 100644
--- a/tools/win-setup.ps1
+++ b/tools/win-setup.ps1
@@ -107,7 +107,7 @@ $Win64Archives = @{
"AirPcap_Devpack_4_1_0_1622.zip" = "AirPcap_Devpack_4_1_0_1622";
"bcg729-1.0.4-win64ws.zip" = "";
"c-ares-1.13.0-win64ws.zip" = "";
- "GeoIP-1.6.10-win64ws.zip" = "";
+ #"GeoIP-1.6.10-win64ws.zip" = "";
"gnutls-3.4.11-1.35-win64ws.zip" = "";
"gtk+-bundle_2.24.23-3.39-2_win64ws.zip" = "gtk2";
"kfw-3-2-2-x64-ws.zip" = "";
@@ -131,7 +131,7 @@ $Win32Archives = @{
"AirPcap_Devpack_4_1_0_1622.zip" = "AirPcap_Devpack_4_1_0_1622";
"bcg729-1.0.4-win32ws.zip" = "";
"c-ares-1.13.0-win32ws.zip" = "";
- "GeoIP-1.6.10-win32ws.zip" = "";
+ #"GeoIP-1.6.10-win32ws.zip" = "";
"gnutls-3.4.11-1.36-win32ws.zip" = "";
"gtk+-bundle_2.24.23-1.1-1_win32ws.zip" = "gtk2";
"kfw-3-2-2-i386-ws-vc6.zip" = "";
diff --git a/tshark.c b/tshark.c
index 289ea98239..9061fa3444 100644
--- a/tshark.c
+++ b/tshark.c
@@ -85,9 +85,7 @@
#if defined(HAVE_LIBSMI)
#include "epan/oids.h"
#endif
-#if defined(HAVE_GEOIP)
-#include "epan/geoip_db.h"
-#endif
+#include "epan/maxmind_db.h"
#include "epan/register.h"
#include <epan/epan_dissect.h>
#include <epan/tap.h>
@@ -618,18 +616,16 @@ about_folders(void)
g_strfreev(resultArray);
-#ifdef HAVE_GEOIP
- /* GeoIP */
- path = geoip_db_get_paths();
+ /* MaxMindDB */
+ path = maxmind_db_get_paths();
resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
for(i = 0; resultArray[i]; i++)
- printf("%-21s\t%s\n", "GeoIP path:", g_strstrip(resultArray[i]));
+ printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
g_strfreev(resultArray);
g_free(path);
-#endif
#ifdef HAVE_LIBSMI
/* SMI MIBs/PIBs */
diff --git a/ui/qt/endpoint_dialog.cpp b/ui/qt/endpoint_dialog.cpp
index 37e5ccdb86..00cddeaa84 100644
--- a/ui/qt/endpoint_dialog.cpp
+++ b/ui/qt/endpoint_dialog.cpp
@@ -8,17 +8,14 @@
#include "endpoint_dialog.h"
-#ifdef HAVE_GEOIP
-#include <GeoIP.h>
-#include <epan/geoip_db.h>
-#include <wsutil/pint.h>
-#endif
+#include <epan/maxmind_db.h>
#include <epan/prefs.h>
#include "ui/recent.h"
#include "ui/traffic_table_ui.h"
+#include "wsutil/pint.h"
#include "wsutil/str_util.h"
#include <ui/qt/utils/qt_ui_utils.h>
@@ -160,9 +157,7 @@ void init_endpoint_table(struct register_ct* ct, const char *filter)
// EndpointTreeWidgetItem
// TrafficTableTreeWidgetItem / QTreeWidgetItem subclass that allows sorting
-#ifdef HAVE_GEOIP
-static const char *geoip_none_ = UTF8_EM_DASH;
-#endif
+static const char *data_none_ = UTF8_EM_DASH;
class EndpointTreeWidgetItem : public TrafficTableTreeWidgetItem
{
@@ -198,17 +193,10 @@ public:
return QString("%L1").arg(endp_item->rx_frames);
case ENDP_COLUMN_BYTES_BA:
return gchar_free_to_qstring(format_size(endp_item->rx_bytes, format_size_unit_none|format_size_prefix_si));
-#ifdef HAVE_GEOIP
default:
- {
- QString geoip_str = colData(column, resolve_names, true).toString();
- if (geoip_str.isEmpty()) geoip_str = geoip_none_;
- return geoip_str;
- }
-#else
- default:
- return colData(column, resolve_names, true);
-#endif
+ QVariant col_data = colData(column, resolve_names);
+ if (col_data.isValid()) return col_data;
+ return QVariant(data_none_);
}
}
return QTreeWidgetItem::data(column, role);
@@ -216,12 +204,16 @@ public:
// Column text raw representation.
// Return a string, qulonglong, double, or invalid QVariant representing the raw column data.
- QVariant colData(int col, bool resolve_names, bool strings_only) const {
-#ifndef HAVE_GEOIP
- Q_UNUSED(strings_only)
-#endif
+ QVariant colData(int col, bool resolve_names) const {
hostlist_talker_t *endp_item = &g_array_index(conv_array_, hostlist_talker_t, conv_idx_);
+ const mmdb_lookup_t *mmdb_lookup = NULL;
+ if (endp_item->myaddress.type == AT_IPv4) {
+ mmdb_lookup = maxmind_db_lookup_ipv4(pntoh32(endp_item->myaddress.data));
+ } else if (endp_item->myaddress.type == AT_IPv6) {
+ mmdb_lookup = maxmind_db_lookup_ipv6((ws_in6_addr *) endp_item->myaddress.data);
+ }
+
switch (col) {
case ENDP_COLUMN_ADDR:
{
@@ -251,55 +243,32 @@ public:
return quint64(endp_item->rx_frames);
case ENDP_COLUMN_BYTES_BA:
return quint64(endp_item->rx_bytes);
-#ifdef HAVE_GEOIP
- default:
- {
- QString geoip_str;
- /* Filled in from the GeoIP config, if any */
- EndpointTreeWidget *ep_tree = qobject_cast<EndpointTreeWidget *>(treeWidget());
- if (!ep_tree) return geoip_str;
- foreach (unsigned db, ep_tree->columnToDb(col)) {
- if (endp_item->myaddress.type == AT_IPv4) {
- geoip_str = geoip_db_lookup_ipv4(db, pntoh32(endp_item->myaddress.data), NULL);
- } else if (endp_item->myaddress.type == AT_IPv6) {
- const ws_in6_addr *addr = (const ws_in6_addr *) endp_item->myaddress.data;
- geoip_str = geoip_db_lookup_ipv6(db, *addr, NULL);
- }
- if (!geoip_str.isEmpty()) {
- break;
- }
+ case ENDP_COLUMN_GEO_COUNTRY:
+ if (mmdb_lookup && mmdb_lookup->found && mmdb_lookup->country) {
+ return QVariant(mmdb_lookup->country);
}
-
- if (strings_only) return geoip_str;
-
- bool ok;
-
- double dval = geoip_str.toDouble(&ok);
- if (ok) { // Assume lat / lon
- return dval;
+ return QVariant();
+ case ENDP_COLUMN_GEO_CITY:
+ if (mmdb_lookup && mmdb_lookup->found && mmdb_lookup->city) {
+ return QVariant(mmdb_lookup->city);
}
-
- qulonglong ullval = geoip_str.toULongLong(&ok);
- if (ok) { // Assume uint
- return ullval;
+ return QVariant();
+ case ENDP_COLUMN_GEO_AS_NUM:
+ if (mmdb_lookup && mmdb_lookup->found && mmdb_lookup->as_number) {
+ return QVariant(mmdb_lookup->as_number);
}
-
- qlonglong llval = geoip_str.toLongLong(&ok);
- if (ok) { // Assume int
- return llval;
+ return QVariant();
+ case ENDP_COLUMN_GEO_AS_ORG:
+ if (mmdb_lookup && mmdb_lookup->found && mmdb_lookup->as_org) {
+ return QVariant(mmdb_lookup->as_org);
}
+ return QVariant();
- return geoip_str;
- }
-#else
default:
return QVariant();
-#endif
}
}
- virtual QVariant colData(int col, bool resolve_names) const { return colData(col, resolve_names, false); }
-
bool operator< (const QTreeWidgetItem &other) const
{
const EndpointTreeWidgetItem *other_row = static_cast<const EndpointTreeWidgetItem *>(&other);
@@ -325,26 +294,26 @@ public:
return endp_item->rx_frames < other_item->rx_frames;
case ENDP_COLUMN_BYTES_BA:
return endp_item->rx_bytes < other_item->rx_bytes;
-#ifdef HAVE_GEOIP
- default:
+ case ENDP_COLUMN_GEO_COUNTRY:
+ case ENDP_COLUMN_GEO_CITY:
+ case ENDP_COLUMN_GEO_AS_ORG:
{
- double ei_val, oi_val;
- bool ei_ok, oi_ok;
- ei_val = text(sort_col).toDouble(&ei_ok);
- oi_val = other.text(sort_col).toDouble(&oi_ok);
-
- if (ei_ok && oi_ok) { // Assume lat / lon
- return ei_val < oi_val;
- } else {
- // XXX Fall back to string comparison. We might want to try sorting naturally
- // using QCollator instead.
- return text(sort_col) < other.text(sort_col);
- }
+ QString this_str = data(sort_col, Qt::DisplayRole).toString();
+ QString other_str = other_row->data(sort_col, Qt::DisplayRole).toString();
+ return (this_str < other_str);
+ }
+ case ENDP_COLUMN_GEO_AS_NUM:
+ {
+ // Valid values first, similar to strings above.
+ bool ok;
+ unsigned this_asn = colData(sort_col, false).toUInt(&ok);
+ if (!ok) this_asn = UINT_MAX;
+ unsigned other_asn = other_row->colData(sort_col, false).toUInt(&ok);
+ if (!ok) other_asn = UINT_MAX;
+ return (this_asn < other_asn);
}
-#else
default:
return false;
-#endif
}
}
private:
@@ -359,40 +328,32 @@ private:
//
EndpointTreeWidget::EndpointTreeWidget(QWidget *parent, register_ct_t *table) :
- TrafficTableTreeWidget(parent, table)
-#ifdef HAVE_GEOIP
- , has_geoip_data_(false)
-#endif
+ TrafficTableTreeWidget(parent, table),
+ table_address_type_(AT_NONE)
{
setColumnCount(ENDP_NUM_COLUMNS);
setUniformRowHeights(true);
- for (int i = 0; i < ENDP_NUM_COLUMNS; i++) {
- headerItem()->setText(i, endp_column_titles[i]);
+ QString proto_filter_name = proto_get_protocol_filter_name(get_conversation_proto_id(table_));
+ if (proto_filter_name == "ip") {
+ table_address_type_ = AT_IPv4;
+ } else if (proto_filter_name == "ipv6") {
+ table_address_type_ = AT_IPv6;
}
-
if (get_conversation_hide_ports(table_)) {
hideColumn(ENDP_COLUMN_PORT);
- } else if (!strcmp(proto_get_protocol_filter_name(get_conversation_proto_id(table_)), "ncp")) {
+ } else if (proto_filter_name == "ncp") {
headerItem()->setText(ENDP_COLUMN_PORT, endp_conn_title);
}
-#ifdef HAVE_GEOIP
- QMap<QString, int> db_name_to_col;
- for (unsigned db = 0; db < geoip_db_num_dbs(); db++) {
- QString db_name = geoip_db_name(db);
- int col = db_name_to_col.value(db_name, -1);
-
- if (col < 0) {
- col = columnCount();
- setColumnCount(col + 1);
- headerItem()->setText(col, db_name);
- hideColumn(col);
- db_name_to_col[db_name] = col;
- }
- col_to_db_[col] << db;
+ int column_count = ENDP_NUM_COLUMNS;
+ if (table_address_type_ == AT_IPv4 || table_address_type_ == AT_IPv6) {
+ column_count = ENDP_NUM_GEO_COLUMNS;
}
-#endif
+ for (int col = 0; col < column_count; col++) {
+ headerItem()->setText(col, endp_column_titles[col]);
+ }
+
int one_en = fontMetrics().height() / 2;
for (int i = 0; i < columnCount(); i++) {
@@ -414,7 +375,7 @@ EndpointTreeWidget::EndpointTreeWidget(QWidget *parent, register_ct_t *table) :
setColumnWidth(i, one_en * (int) strlen("000,000"));
break;
default:
- setColumnWidth(i, one_en * (int) strlen("-00.000000")); // GeoIP
+ setColumnWidth(i, one_en * 15); // Geolocation
}
}
@@ -494,19 +455,6 @@ void EndpointTreeWidget::updateItems()
return;
}
-#ifdef HAVE_GEOIP
- if (topLevelItemCount() < 1 && hash_.conv_array->len > 0) {
- hostlist_talker_t *endp_item = &g_array_index(hash_.conv_array, hostlist_talker_t, 0);
- if (endp_item->myaddress.type == AT_IPv4 || endp_item->myaddress.type == AT_IPv6) {
- for (unsigned i = 0; i < geoip_db_num_dbs(); i++) {
- showColumn(ENDP_NUM_COLUMNS + i);
- }
- has_geoip_data_ = true;
- emit geoIPStatusChanged();
- }
- }
-#endif
-
setSortingEnabled(false);
QList<QTreeWidgetItem *>new_items;
diff --git a/ui/qt/endpoint_dialog.h b/ui/qt/endpoint_dialog.h
index b1186f4858..08bca0a759 100644
--- a/ui/qt/endpoint_dialog.h
+++ b/ui/qt/endpoint_dialog.h
@@ -18,28 +18,14 @@ public:
explicit EndpointTreeWidget(QWidget *parent, register_ct_t* table);
~EndpointTreeWidget();
-#ifdef HAVE_GEOIP
- bool hasGeoIPData() const { return has_geoip_data_; }
-#endif
-
static void tapReset(void *conv_hash_ptr);
static void tapDraw(void *conv_hash_ptr);
-#ifdef HAVE_GEOIP
-public:
- const QList<int> columnToDb(int column) const { return col_to_db_.value(column, QList<int>()); }
-
-signals:
- void geoIPStatusChanged();
-
-private:
- QMap<int, QList<int> > col_to_db_; // Map tree columns to GeoIP databases
- bool has_geoip_data_;
-#endif
-
private:
void updateItems();
+ address_type table_address_type_;
+
private slots:
void filterActionTriggered();
};
diff --git a/ui/traffic_table_ui.c b/ui/traffic_table_ui.c
index 02c6d16a5c..0f41f238f4 100644
--- a/ui/traffic_table_ui.c
+++ b/ui/traffic_table_ui.c
@@ -35,7 +35,7 @@ const char *conv_conn_a_title = "Connection A";
const char *conv_conn_b_title = "Connection B";
const char *conv_abs_start_title = "Abs Start";
-const char *endp_column_titles[ENDP_NUM_COLUMNS] = {
+const char *endp_column_titles[ENDP_NUM_GEO_COLUMNS] = {
"Address",
"Port",
"Packets",
@@ -43,7 +43,11 @@ const char *endp_column_titles[ENDP_NUM_COLUMNS] = {
"Tx Packets",
"Tx Bytes",
"Rx Packets",
- "Rx Bytes"
+ "Rx Bytes",
+ "Country",
+ "City",
+ "AS Number",
+ "AS Organization"
};
const char *endp_conn_title = "Connection";
diff --git a/ui/traffic_table_ui.h b/ui/traffic_table_ui.h
index c89564d24e..f067297808 100644
--- a/ui/traffic_table_ui.h
+++ b/ui/traffic_table_ui.h
@@ -53,10 +53,15 @@ typedef enum
ENDP_COLUMN_BYTES_AB,
ENDP_COLUMN_PKT_BA,
ENDP_COLUMN_BYTES_BA,
- ENDP_NUM_COLUMNS
+ ENDP_NUM_COLUMNS,
+ ENDP_COLUMN_GEO_COUNTRY = ENDP_NUM_COLUMNS,
+ ENDP_COLUMN_GEO_CITY,
+ ENDP_COLUMN_GEO_AS_NUM,
+ ENDP_COLUMN_GEO_AS_ORG,
+ ENDP_NUM_GEO_COLUMNS,
} endpoint_column_type_e;
-extern const char *endp_column_titles[ENDP_NUM_COLUMNS];
+extern const char *endp_column_titles[ENDP_NUM_GEO_COLUMNS];
extern const char *endp_conn_title;