Transition from GeoIP Legacy to MaxMindDB.
authorGerald Combs <gerald@wireshark.org>
Fri, 9 Feb 2018 01:20:26 +0000 (17:20 -0800)
committerGerald Combs <gerald@wireshark.org>
Tue, 6 Mar 2018 18:02:21 +0000 (18:02 +0000)
MaxMind is discontinuing its legacy databases in April in favor of
GeoIP2, which use a newer database format (MaxMind DB). The reference C
library (libmaxminddb) is available under the Apache 2.0 license which
isn't quite compatible with ours.

Add mmdbresolve, a utility that reads IPv4 and IPv6 addresses on stdin
and prints resolved information on stdout. Place it under a liberal
license (MIT) so that we can keep libmaxminddb at arm's length. Add
epan/maxmind_db.[ch], which spawns mmdbresolve and communicates with it
via stdio.

Migrate the preferences and documentation to MaxMindDB.

Change the IPv4 and IPv6 asnum fields to FT_UINT32s. Change the
geographic coordinate fields to FT_DOUBLEs.

Bug: 10658
Change-Id: I24aeed637bea1b41d173270bda413af230f4425f
Reviewed-on: https://code.wireshark.org/review/26214
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Gerald Combs <gerald@wireshark.org>
55 files changed:
CMakeLists.txt
CMakeOptions.txt
Makefile.am
README.macos
acinclude.m4
cmake/modules/FindGEOIP.cmake [deleted file]
cmake/modules/FindMaxMindDB.cmake [new file with mode: 0644]
cmakeconfig.h.in
configure.ac
debian/control
debian/libwireshark-data.install
debian/libwireshark0.symbols
debian/maxmind_db_paths [moved from debian/geoip_db_paths with 100% similarity]
doc/CMakeLists.txt
doc/Makefile.am
doc/mmdbresolve.pod [new file with mode: 0644]
docbook/release-notes.asciidoc
docbook/wsdg_src/WSDG_chapter_libraries.asciidoc
docbook/wsug_src/WSUG_chapter_customize.asciidoc
docbook/wsug_src/WSUG_chapter_statistics.asciidoc
docbook/wsug_src/WSUG_chapter_use.asciidoc
epan/CMakeLists.txt
epan/Makefile.am
epan/addr_resolv.c
epan/addr_resolv.h
epan/dissectors/Makefile.am
epan/dissectors/packet-ip.c
epan/dissectors/packet-ipv6.c
epan/epan.c
epan/geoip_db.c [deleted file]
epan/geoip_db.h [deleted file]
epan/maxmind_db.c [new file with mode: 0644]
epan/maxmind_db.h [new file with mode: 0644]
epan/prefs.c
mmdbresolve.c [new file with mode: 0644]
packaging/macosx/Scripts/cli-postinstall.sh
packaging/nsis/CMakeLists.txt
packaging/nsis/uninstall.nsi
packaging/nsis/wireshark.nsi
packaging/rpm/SPECS/wireshark.spec.in
packaging/wix/CMakeLists.txt
packaging/wix/ComponentGroups.wxi
packaging/wix/Features.wxi
tools/Get-HardenFlags.ps1
tools/debian-setup.sh
tools/install_rpms_for_devel.sh
tools/macos-setup.sh
tools/pre-commit-ignore.conf
tools/rpm_setup.sh
tools/win-setup.ps1
tshark.c
ui/qt/endpoint_dialog.cpp
ui/qt/endpoint_dialog.h
ui/traffic_table_ui.c
ui/traffic_table_ui.h

index 747223adf65cb58ba2a7267bea4012d279c4f099..96b013892abd13f6b727e147e3efc77eb604b4c3 100644 (file)
@@ -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,
index c011f3e65b2894203ff024532c21d551cd3d2d4e..e7903f5b0f607b896b2cdf3bcad0decb82e25758 100644 (file)
@@ -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()
index 3f381f8a0efcf6f99d8a9688fe263e11af4b48d4..f90fda4c321daa3cfce856e543c8b2c9f4f0fda2 100644 (file)
@@ -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                \
index 7e533ca3f7145005183595486a4fcf41a7738465..e53e946d2f8aa719326fdf645eb1af75ce20f89c 100644 (file)
@@ -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
index c53ac7c46a5ac26ff4aafaa7186745451bfb8149..bfc715c3f172c484c7f2b99664939fc99e49127b 100644 (file)
@@ -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 (file)
index 518837b..0000000
+++ /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 (file)
index 0000000..cad4499
--- /dev/null
@@ -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 )
index 30660c259a94538c1df53a47ccaa066ec9ab7ef2..c78328ae082f341ee2597e99cebbea6336f4763c 100644 (file)
 /* 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
index 11ef8825e60b9188d0f78bfca05f57dcc8617db1..ebb8ba0364aa5874975902e7b8425d218a47e4de 100644 (file)
@@ -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"
index 2f1c62fd29ce6a07e0043f932bb327f63b64062e..e1b1511cdda2db50677de617ae544ebfc6f3ccb1 100644 (file)
@@ -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
index 568526fc2ef0bc3ce1ad014187b3dd5cc10e109e..b717c62e2a8a203889fc0beca1502b1a57fee8a2 100644 (file)
@@ -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
index a1bdc2116f186df6bb59e1a17b0df604ca78af53..ea313849ce520d60233e490651259ba1f9b51c72 100644 (file)
@@ -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
index c0cf6c11fc53764a5f1e760d2997fadd2a927f0a..798c49ee2088cda7006d4d0b2ac6ca69c9468be4 100644 (file)
@@ -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()
index 7c5b31ca15303cf678a2db2c55edbe9589c0fe42..c88ebc7bc4cda53e77c8d7ac9830e667076726b1 100644 (file)
@@ -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 (file)
index 0000000..43a827e
--- /dev/null
@@ -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>
index b2db89ff998b8c89a0f42c36434cf235d012f983..073d634a1d855a1ecf6d02c8febf18eff1c43939 100644 (file)
@@ -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.
 
index 247649d5a722e63e1a6ae517115c7392f6a85491..c184f867cfcf23a7101a23b0166322f01a2b01a1 100644 (file)
@@ -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]]
index 96e443468e74f56ea7cefd8a834df1d87e3e287e..66ea7288da9d8ff3c50174ee07d4570a771b6592 100644 (file)
@@ -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]]
 
index 6580c5c090584609a3a977de3fba059c4709cfcb..607ccfc9d7d552686611b8210d30d9964507e1c9 100644 (file)
@@ -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.
index fd21e7afa26682d511305c16390cba93f0fbec04..1ea8d650382e663ef50cc510a20ec5fb3814c3a0 100644 (file)
@@ -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
index 5bd3d40e4e30ba2ec9e6a51e0ad034a0863d8403..f0196fc57fea7804ba36eff2cc7ef965d6b4eac1 100644 (file)
@@ -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}
index d22d68e18be70cadde4449cb4ba3bad0f59a945d..c85fcd2d5210321396bb08e4808eac2f36b8e3ee 100644 (file)
@@ -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@        \
index 1cae8a5733fb97c20305121804facaa3d90278e6..56da73bf693e8f038b6e8fcac3a30d1af5892258 100644 (file)
@@ -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;
 }
 
index cfac1fc5c1b09c60a555faf004f07dcce4ca4a69..bc1d78d61abc74b919730fa5cc0c98a015757d24 100644 (file)
@@ -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 */
index 423a5dda34e6409ddeac153e81dd11bbb6acfaf6..0367141e8ec98b7e00ca48142729a45a8759864e 100644 (file)
@@ -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
 
index 1ab1b2581235cd2e711de5862d68a9bcce5fc7a7..02432764f1d8da07aae46642078708aa374c668b 100644 (file)
@@ -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>
 #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",
index 852cf192a6c1c6d71a134b14e0a8bfb80b068d6b..40e11edd99b2956aa8180092c336e3c9cd3b75ba 100644 (file)
@@ -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>
 #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",
index 076b557b5a43d82a593e756642c3820822d992ee..a1a9240a81febb718b1de97c78837a89c794f576 100644 (file)
@@ -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 (file)
index f79b0f6..0000000
+++ /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 (file)
index 20aa46a..0000000
+++ /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 (file)
index 0000000..03e7056
--- /dev/null
@@ -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 (file)
index 0000000..1b8e5fe
--- /dev/null
@@ -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:
+ */
index 1ccf5ac18513ef144ea536f0da479b363663051e..eb30c1628a7b0fcc26eafc239a32aa2be2b6e616 100644 (file)
@@ -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 (file)
index 0000000..3568a0b
--- /dev/null
@@ -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:
+ */
index f83cf4faac8f0de7f28d72acf04b5ca974e87d4c..4c74a42847e61ac8f400ee5ba4ef0786987be559 100755 (executable)
@@ -7,6 +7,7 @@ BINARIES="
     dumpcap
     editcap
     mergecap
+    mmdbresolve
     randpkt
     rawshark
     text2pcap
index 6237f5b38271af17c53e877da7b3caebdf32cd14..ce6024ad7b20124c37a190ccc052a35dac502cdd 100644 (file)
@@ -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()
index f552ffed74941b53e67e7721b2c399a23b6c4ad2..74d2e28eae542308d803158ce0ca7f3295effd88 100644 (file)
@@ -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}
index 21c67e31a5452ffd951966361c42db629c03247e..404c6a326d75996f99913bd75eba7c93d1bbbb03 100644 (file)
@@ -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
index 024e9fd4b2ba1bd1a3fece2c6abcc392f0fdaea0..3ddd8a00e89280c3271a5e0bcd355b4c3a0e1bf2 100644 (file)
@@ -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
 
index ec07991dc7dbd039719efe200dd278c0ee58543e..352e53f85458b7edbc3ce0301ddc63af4316bfd1 100644 (file)
@@ -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}(;|$)")
index 92fc09b157c60031f11bc73a25e4c8363f23238c..8631c805d26c51eb3ae6cf6678b09f9d80396561 100644 (file)
     </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">
index 891d689b5e9a3d70e33800fa340782b0a25dc30c..277a713a14a2d0bff48ce7cf9fe697e230d078a1 100644 (file)
@@ -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>
index 7503f1382677dda67249f33e682cdc4cca117074..5f45cab3e84be0191b1bd715d5497ea49724cb2d 100644 (file)
@@ -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",
index 2b7c672aac9385eb889abfd95214d41d6c5c1e0d..44abcf76c1e9b5403aecdf28182d673d439b1fab 100755 (executable)
@@ -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
index f6ac3f077cfcd8165e910667af9e002de2df45d5..c2362e70ffbefde58ed82d3514af605d2aad8ac6 100755 (executable)
@@ -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):"
index a76ff3271e81b01259ae030f495a15295d2fd761..30eb3d8928053634e50c2a49a001478c8f70844c 100755 (executable)
@@ -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/'`
index 27a860f63df4af41e732b637bf82f0588c86d3a0..e10030d87f2e5f7e1e3c5edc2a10325d447ce07f 100644 (file)
@@ -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
index 4e6bf7fd54b989e19898b803847a5b60491176d6..c52afbfde8fb2241a413c4699345e70190ba4f2b 100755 (executable)
@@ -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
index ccfffd13c6a5afba6bb9a8f13cb786a2b265aab8..6403aa42defbc2e8db0c8cdcc6495a280f5ac0a5 100644 (file)
@@ -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" = "";
index 289ea98239bc0ae27db58ac2929850fde38a64dd..9061fa3444cc8792a8b6481c3b778776b3f0cc84 100644 (file)
--- 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 */
index 37e5ccdb8651c20ac241cf212ca25577ef8059fb..00cddeaa842b745fe1934b4dea56f443396293f1 100644 (file)
@@ -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;
index b1186f48580861f04cb5589a6d14d57789f23a40..08bca0a7591effc48c4f43a42ee0578fa879453a 100644 (file)
@@ -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();
 };
index 02c6d16a5c3f8ce6e1dabab83b39d8807c96e2eb..0f41f238f4f6bd0adfe03c6b2deaa2a156c5db74 100644 (file)
@@ -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";
index c89564d24ea89b62f6c007751017981f619f5402..f067297808bf74e34f49198d4fe6b67dcbdccb94 100644 (file)
@@ -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;