]> The Tcpdump Group git mirrors - libpcap/commitdiff
Merge branch 'master' of https://github.com/rixed/libpcap into rixed-master
authorGuy Harris <[email protected]>
Mon, 7 Jan 2019 00:08:00 +0000 (16:08 -0800)
committerGuy Harris <[email protected]>
Mon, 7 Jan 2019 00:08:00 +0000 (16:08 -0800)
14 files changed:
1  2 
Makefile.in
aclocal.m4
config.h.in
configure
configure.ac
pcap-int.h
pcap-rpcap.c
pcap.c
pcap/pcap.h
rpcapd/Makefile.in
rpcapd/daemon.c
rpcapd/rpcapd.c
sockutils.c
sockutils.h

diff --combined Makefile.in
index 9f4683e43309cde58951dce33cd63e4f54eb5566,9f18c54328ac3dba8e425c5d7707f1b7a43b8c54..031a779004ebdf2502ebd3f7010163c76dac8e6a
@@@ -69,7 -69,7 +69,7 @@@ INSTALL_RPCAPD=@INSTALL_RPCAPD
  EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
  
  # Standard CFLAGS for building members of a shared library
 -FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
 +FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
  
  INSTALL = @INSTALL@
  INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@@ -86,8 -86,7 +86,8 @@@ YACC = @YACC
        @rm -f $@
        $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
  
 -PSRC =        pcap-@[email protected] @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@ @NETMAP_SRC@ @RDMA_SRC@
 +PSRC =        pcap-@[email protected]
 +MSRC =        @MSRC@
  FSRC =  @V_FINDALLDEVS@
  SSRC =  @SSRC@
  CSRC =        pcap.c gencode.c optimize.c nametoaddr.c etherent.c \
  GENSRC = scanner.c grammar.c
  LIBOBJS = @LIBOBJS@
  
 -SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
 +SRC = $(PSRC) $(MSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
  
  # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
  # hack the extra indirection
 -OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
 +OBJ = $(PSRC:.c=.o) $(MSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
  PUBHDR = \
        pcap.h \
        pcap-bpf.h \
@@@ -280,8 -279,6 +280,8 @@@ EXTRA_DIST = 
        missing/getopt.c \
        missing/getopt.h \
        missing/snprintf.c \
 +      missing/strlcat.c \
 +      missing/strlcpy.c \
        missing/strtok_r.c \
        missing/win_snprintf.c \
        mkdep \
        pcap-dlpi.c \
        pcap-dos.c \
        pcap-dos.h \
 +      pcap-dpdk.c \
 +      pcap-dpdk.h \
        pcap-enet.c \
        pcap-int.h \
        pcap-libdlpi.c \
        rpcapd/win32-svc.h \
        sockutils.c \
        sockutils.h \
+       sslutils.c \
+       sslutils.h \
        scanner.l \
        testprogs/CMakeLists.txt \
        testprogs/Makefile.in \
@@@ -422,7 -419,7 +424,7 @@@ libpcap.dylib: $(OBJ
        MAJOR_VER=A; \
        COMPAT_VER=1; \
        CURRENT_VER=`sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`; \
 -      $(CC) -dynamiclib -undefined error $(LDFLAGS) \
 +      $(CC) -dynamiclib -undefined error $(LDFLAGS) @V_LIB_LDFLAGS_FAT@ \
            -o libpcap.$$VER.dylib $(OBJ) $(ADDLOBJS) $(LIBS) \
            -install_name $(libdir)/libpcap.$$MAJOR_VER.dylib \
            -compatibility_version $$COMPAT_VER \
@@@ -497,12 -494,6 +499,12 @@@ gencode.o: $(srcdir)/gencode.c grammar.
  snprintf.o: $(srcdir)/missing/snprintf.c
        $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
  
 +strlcat.o: $(srcdir)/missing/strlcat.c
 +      $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcat.c
 +
 +strlcpy.o: $(srcdir)/missing/strlcpy.c
 +      $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcpy.c
 +
  strtok_r.o: $(srcdir)/missing/strtok_r.c
        $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
  
@@@ -765,5 -756,3 +767,5 @@@ depend:    $(GENSRC) $(GENHDR
        $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
        cd rpcapd; $(MAKE) depend
        cd testprogs; $(MAKE) depend
 +
 +
diff --combined aclocal.m4
index 1dfb1af5b849f00e682a39f352e48be5b59e93a4,256e631d90a4bdda125089916f74b1ba281dd9f7..e4c7208239baceb867bace0f1d73192be08307a8
@@@ -781,6 -781,7 +781,6 @@@ AC_DEFUN(AC_LBL_DEVEL
                    AC_LBL_CHECK_COMPILER_OPT($1, -W)
                    AC_LBL_CHECK_COMPILER_OPT($1, -Wall)
                    AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma)
 -                  AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
                    AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
                    AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
                    AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn)
@@@ -977,3 -978,281 +977,281 @@@ AC_DEFUN(AC_LBL_LIBRARY_NET, 
      # DLPI needs putmsg under HPUX so test for -lstr while we're at it
      AC_SEARCH_LIBS(putmsg, str)
  ])
+ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+ dnl pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
+ dnl serial 11 (pkg-config-0.29)
+ dnl
+ dnl Copyright © 2004 Scott James Remnant <[email protected]>.
+ dnl Copyright © 2012-2015 Dan Nicholson <[email protected]>
+ dnl
+ dnl This program is free software; you can redistribute it and/or modify
+ dnl it under the terms of the GNU General Public License as published by
+ dnl the Free Software Foundation; either version 2 of the License, or
+ dnl (at your option) any later version.
+ dnl
+ dnl This program is distributed in the hope that it will be useful, but
+ dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+ dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ dnl General Public License for more details.
+ dnl
+ dnl You should have received a copy of the GNU General Public License
+ dnl along with this program; if not, write to the Free Software
+ dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ dnl 02111-1307, USA.
+ dnl
+ dnl As a special exception to the GNU General Public License, if you
+ dnl distribute this file as part of a program that contains a
+ dnl configuration script generated by Autoconf, you may include it under
+ dnl the same distribution terms that you use for the rest of that
+ dnl program.
+ dnl PKG_PREREQ(MIN-VERSION)
+ dnl -----------------------
+ dnl Since: 0.29
+ dnl
+ dnl Verify that the version of the pkg-config macros are at least
+ dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+ dnl installed version of pkg-config, this checks the developer's version
+ dnl of pkg.m4 when generating configure.
+ dnl
+ dnl To ensure that this macro is defined, also add:
+ dnl m4_ifndef([PKG_PREREQ],
+ dnl     [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+ dnl
+ dnl See the "Since" comment for each macro you use to see what version
+ dnl of the macros you require.
+ m4_defun([PKG_PREREQ],
+ [m4_define([PKG_MACROS_VERSION], [0.29])
+ m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+     [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+ ])dnl PKG_PREREQ
+ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+ dnl ----------------------------------
+ dnl Since: 0.16
+ dnl
+ dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+ dnl first found in the path. Checks that the version of pkg-config found
+ dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+ dnl used since that's the first version where most current features of
+ dnl pkg-config existed.
+ AC_DEFUN([PKG_PROG_PKG_CONFIG],
+ [m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+ m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+ m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+ AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+ AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+ AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+ fi
+ if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=m4_default([$1], [0.9.0])
+       AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               PKG_CONFIG=""
+       fi
+ fi[]dnl
+ ])dnl PKG_PROG_PKG_CONFIG
+ dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+ dnl -------------------------------------------------------------------
+ dnl Since: 0.18
+ dnl
+ dnl Check to see whether a particular set of modules exists. Similar to
+ dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+ dnl
+ dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+ dnl only at the first occurence in configure.ac, so if the first place
+ dnl it's called might be skipped (such as if it is within an "if", you
+ dnl have to call PKG_CHECK_EXISTS manually
+ AC_DEFUN([PKG_CHECK_EXISTS],
+ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+ if test -n "$PKG_CONFIG" && \
+     AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+   m4_default([$2], [:])
+ m4_ifvaln([$3], [else
+   $3])dnl
+ fi])
+ dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+ dnl ---------------------------------------------
+ dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+ dnl pkg_failed based on the result.
+ m4_define([_PKG_CONFIG],
+ [if test -n "$$1"; then
+     pkg_cv_[]$1="$$1"
+  elif test -n "$PKG_CONFIG"; then
+     PKG_CHECK_EXISTS([$3],
+                      [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes ],
+                    [pkg_failed=yes])
+  else
+     pkg_failed=untried
+ fi[]dnl
+ ])dnl _PKG_CONFIG
+ dnl _PKG_SHORT_ERRORS_SUPPORTED
+ dnl ---------------------------
+ dnl Internal check to see if pkg-config supports short errors.
+ AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+         _pkg_short_errors_supported=yes
+ else
+         _pkg_short_errors_supported=no
+ fi[]dnl
+ ])dnl _PKG_SHORT_ERRORS_SUPPORTED
+ dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+ dnl   [ACTION-IF-NOT-FOUND])
+ dnl --------------------------------------------------------------
+ dnl Since: 0.4.0
+ dnl
+ dnl Note that if there is a possibility the first call to
+ dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+ dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+ AC_DEFUN([PKG_CHECK_MODULES],
+ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+ AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+ pkg_failed=no
+ AC_MSG_CHECKING([for $1])
+ _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+ _PKG_CONFIG([$1][_LIBS], [libs], [$2])
+ m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+ and $1[]_LIBS to avoid the need to call pkg-config.
+ See the pkg-config man page for more details.])
+ if test $pkg_failed = yes; then
+       AC_MSG_RESULT([no])
+         _PKG_SHORT_ERRORS_SUPPORTED
+         if test $_pkg_short_errors_supported = yes; then
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+         else 
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+         fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+       m4_default([$4], [AC_MSG_ERROR(
+ [Package requirements ($2) were not met:
+ $$1_PKG_ERRORS
+ Consider adjusting the PKG_CONFIG_PATH environment variable if you
+ installed software in a non-standard prefix.
+ _PKG_TEXT])[]dnl
+         ])
+ elif test $pkg_failed = untried; then
+       AC_MSG_RESULT([no])
+       m4_default([$4], [AC_MSG_FAILURE(
+ [The pkg-config script could not be found or is too old.  Make sure it
+ is in your PATH or set the PKG_CONFIG environment variable to the full
+ path to pkg-config.
+ _PKG_TEXT
+ To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+         ])
+ else
+       $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+       $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+         AC_MSG_RESULT([yes])
+       $3
+ fi[]dnl
+ ])dnl PKG_CHECK_MODULES
+ dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+ dnl   [ACTION-IF-NOT-FOUND])
+ dnl ---------------------------------------------------------------------
+ dnl Since: 0.29
+ dnl
+ dnl Checks for existence of MODULES and gathers its build flags with
+ dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+ dnl and VARIABLE-PREFIX_LIBS from --libs.
+ dnl
+ dnl Note that if there is a possibility the first call to
+ dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+ dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+ dnl configure.ac.
+ AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+ _save_PKG_CONFIG=$PKG_CONFIG
+ PKG_CONFIG="$PKG_CONFIG --static"
+ PKG_CHECK_MODULES($@)
+ PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+ ])dnl PKG_CHECK_MODULES_STATIC
+ dnl PKG_INSTALLDIR([DIRECTORY])
+ dnl -------------------------
+ dnl Since: 0.27
+ dnl
+ dnl Substitutes the variable pkgconfigdir as the location where a module
+ dnl should install pkg-config .pc files. By default the directory is
+ dnl $libdir/pkgconfig, but the default can be changed by passing
+ dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+ dnl parameter.
+ AC_DEFUN([PKG_INSTALLDIR],
+ [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+ m4_pushdef([pkg_description],
+     [pkg-config installation directory @<:@]pkg_default[@:>@])
+ AC_ARG_WITH([pkgconfigdir],
+     [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+     [with_pkgconfigdir=]pkg_default)
+ AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+ m4_popdef([pkg_default])
+ m4_popdef([pkg_description])
+ ])dnl PKG_INSTALLDIR
+ dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+ dnl --------------------------------
+ dnl Since: 0.27
+ dnl
+ dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+ dnl module should install arch-independent pkg-config .pc files. By
+ dnl default the directory is $datadir/pkgconfig, but the default can be
+ dnl changed by passing DIRECTORY. The user can override through the
+ dnl --with-noarch-pkgconfigdir parameter.
+ AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+ [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+ m4_pushdef([pkg_description],
+     [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+ AC_ARG_WITH([noarch-pkgconfigdir],
+     [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+     [with_noarch_pkgconfigdir=]pkg_default)
+ AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+ m4_popdef([pkg_default])
+ m4_popdef([pkg_description])
+ ])dnl PKG_NOARCH_INSTALLDIR
+ dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+ dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+ dnl -------------------------------------------
+ dnl Since: 0.28
+ dnl
+ dnl Retrieves the value of the pkg-config variable for the given module.
+ AC_DEFUN([PKG_CHECK_VAR],
+ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+ AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+ _PKG_CONFIG([$1], [variable="][$3]["], [$2])
+ AS_VAR_COPY([$1], [pkg_cv_][$1])
+ AS_VAR_IF([$1], [""], [$5], [$4])dnl
+ ])dnl PKG_CHECK_VAR
diff --combined config.h.in
index c554d25d70bceb5cf0f4366b2c1faf177ecc3389,bf2d0c2c15c2fedd9829e4de3f7d115c8b366fd6..e09bc60720fd6760e1c6ce7f422a462d5ad0b8ee
  /* Define to 1 if you have the <net/raw.h> header file. */
  #undef HAVE_NET_RAW_H
  
+ /* Use OpenSSL */
+ #undef HAVE_OPENSSL
  /* if there's an os_proto.h for this platform, to use additional prototypes */
  #undef HAVE_OS_PROTO_H
  
  /* Define to 1 if you have the <sys/dlpi.h> header file. */
  #undef HAVE_SYS_DLPI_H
  
 +/* Define to 1 if you have the <sys/eventfd.h> header file. */
 +#undef HAVE_SYS_EVENTFD_H
 +
  /* Define to 1 if you have the <sys/ioccom.h> header file. */
  #undef HAVE_SYS_IOCCOM_H
  
  /* support D-Bus sniffing */
  #undef PCAP_SUPPORT_DBUS
  
 +/* target host supports DPDK */
 +#undef PCAP_SUPPORT_DPDK
 +
  /* target host supports netfilter sniffing */
  #undef PCAP_SUPPORT_NETFILTER
  
diff --combined configure
index 7de6c1487e78f3a075632489ae30590a41293961,0928e11579b0e79fc76db5141b79188ad9bad0c2..0acb192d100ba4ac6c73eedcfd61b3e95089c50b
+++ b/configure
@@@ -623,13 -623,19 +623,13 @@@ ac_subst_vars='LTLIBOBJ
  INSTALL_DATA
  INSTALL_SCRIPT
  INSTALL_PROGRAM
 -RDMA_SRC
  PCAP_SUPPORT_RDMASNIFF
 -DBUS_SRC
  PCAP_SUPPORT_DBUS
  PKGCONFIG
 -BT_MONITOR_SRC
 -BT_SRC
  PCAP_SUPPORT_BT
 -NETMAP_SRC
 +PCAP_SUPPORT_DPDK
  PCAP_SUPPORT_NETMAP
 -NETFILTER_SRC
  PCAP_SUPPORT_NETFILTER
 -USB_SRC
  PCAP_SUPPORT_USB
  EXTRA_NETWORK_LIBS
  RPCAPD_LIBS
@@@ -642,7 -648,6 +642,7 @@@ MAN_FILE_FORMAT
  MAN_DEVICES
  DYEXT
  SSRC
 +MSRC
  ADDLARCHIVEOBJS
  ADDLOBJS
  V_YACC
@@@ -656,10 -661,6 +656,10 @@@ V_LE
  V_INCLS
  V_FINDALLDEVS
  V_DEFS
 +V_PROG_LDFLAGS_FAT
 +V_PROG_CCOPT_FAT
 +V_LIB_LDFLAGS_FAT
 +V_LIB_CCOPT_FAT
  V_CCOPT
  MKDEP
  DEPENDENCY_CFLAG
@@@ -671,6 -672,11 +671,11 @@@ YAC
  LEXLIB
  LEX_OUTPUT_ROOT
  LEX
+ OPENSSL_LIBS
+ OPENSSL_CFLAGS
+ PKG_CONFIG_LIBDIR
+ PKG_CONFIG_PATH
+ PKG_CONFIG
  PCAP_SUPPORT_PACKET_RING
  VALGRINDTEST_SRC
  LIBOBJS
@@@ -716,6 -722,7 +721,6 @@@ infodi
  docdir
  oldincludedir
  includedir
 -runstatedir
  localstatedir
  sharedstatedir
  sysconfdir
@@@ -760,7 -767,6 +765,7 @@@ enable_universa
  enable_shared
  enable_usb
  enable_netmap
 +with_dpdk
  enable_bluetooth
  enable_dbus
  enable_rdma
@@@ -774,6 -780,11 +779,11 @@@ LDFLAG
  LIBS
  CPPFLAGS
  CPP
+ PKG_CONFIG
+ PKG_CONFIG_PATH
+ PKG_CONFIG_LIBDIR
+ OPENSSL_CFLAGS
+ OPENSSL_LIBS
  YACC
  YFLAGS'
  
@@@ -814,6 -825,7 +824,6 @@@ datadir='${datarootdir}
  sysconfdir='${prefix}/etc'
  sharedstatedir='${prefix}/com'
  localstatedir='${prefix}/var'
 -runstatedir='${localstatedir}/run'
  includedir='${prefix}/include'
  oldincludedir='/usr/include'
  docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
    | -silent | --silent | --silen | --sile | --sil)
      silent=yes ;;
  
 -  -runstatedir | --runstatedir | --runstatedi | --runstated \
 -  | --runstate | --runstat | --runsta | --runst | --runs \
 -  | --run | --ru | --r)
 -    ac_prev=runstatedir ;;
 -  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
 -  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
 -  | --run=* | --ru=* | --r=*)
 -    runstatedir=$ac_optarg ;;
 -
    -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
      ac_prev=sbindir ;;
    -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 -              libdir localedir mandir runstatedir
 +              libdir localedir mandir
  do
    eval ac_val=\$$ac_var
    # Remove trailing slashes.
@@@ -1356,6 -1377,7 +1366,6 @@@ Fine tuning of the installation directo
    --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
    --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
    --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
 -  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
    --libdir=DIR            object code libraries [EPREFIX/lib]
    --includedir=DIR        C header files [PREFIX/include]
    --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@@ -1436,8 -1458,6 +1446,8 @@@ Optional Packages
    --with-turbocap[=DIR]   include Riverbed TurboCap support (located in
                            directory DIR, if supplied). [default=yes, if
                            present]
 +  --with-dpdk[=DIR]       include DPDK support (located in directory DIR, if
 +                          supplied). [default=yes, if present]
  
  Some influential environment variables:
    CC          C compiler command
    CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
                you have headers in a nonstandard directory <include dir>
    CPP         C preprocessor
+   PKG_CONFIG  path to pkg-config utility
+   PKG_CONFIG_PATH
+               directories to add to pkg-config's search path
+   PKG_CONFIG_LIBDIR
+               path overriding pkg-config's built-in search path
+   OPENSSL_CFLAGS
+               C compiler flags for OPENSSL, overriding pkg-config
+   OPENSSL_LIBS
+               linker flags for OPENSSL, overriding pkg-config
    YACC        The `Yet Another Compiler Compiler' implementation to use.
                Defaults to the first program found out of: `bison -y', `byacc',
                `yacc'.
@@@ -3577,10 -3606,6 +3596,10 @@@ if test "x$ac_cv_prog_cc_c99" != xno; t
  fi
  
  
 +if test "$ac_cv_prog_cc_c99" = "no"; then
 +      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The C compiler does not support C99; there may be compiler errors" >&5
 +$as_echo "$as_me: WARNING: The C compiler does not support C99; there may be compiler errors" >&2;}
 +fi
  
  
  
@@@ -4219,7 -4244,7 +4238,7 @@@ els
      We can't simply define LARGE_OFF_T to be 9223372036854775807,
      since some C++ compilers masquerading as C compilers
      incorrectly reject 9223372036854775807.  */
 -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
 +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
    int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@@ -4265,7 -4290,7 +4284,7 @@@ els
      We can't simply define LARGE_OFF_T to be 9223372036854775807,
      since some C++ compilers masquerading as C compilers
      incorrectly reject 9223372036854775807.  */
 -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
 +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
    int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@@ -4289,7 -4314,7 +4308,7 @@@ rm -f core conftest.err conftest.$ac_ob
      We can't simply define LARGE_OFF_T to be 9223372036854775807,
      since some C++ compilers masquerading as C compilers
      incorrectly reject 9223372036854775807.  */
 -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
 +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
    int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@@ -4334,7 -4359,7 +4353,7 @@@ els
      We can't simply define LARGE_OFF_T to be 9223372036854775807,
      since some C++ compilers masquerading as C compilers
      incorrectly reject 9223372036854775807.  */
 -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
 +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
    int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@@ -4358,7 -4383,7 +4377,7 @@@ rm -f core conftest.err conftest.$ac_ob
      We can't simply define LARGE_OFF_T to be 9223372036854775807,
      since some C++ compilers masquerading as C compilers
      incorrectly reject 9223372036854775807.  */
 -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
 +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
    int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
  
  case "$host_os" in
  linux*|uclinux*)
 +      #
 +      # linux/if_bonding.h requires sys/socket.h.
 +      #
        for ac_header in linux/sockios.h linux/if_bonding.h
  do :
    as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@@ -4955,22 -4977,6 +4974,22 @@@ _ACEO
  
  fi
  
 +done
 +
 +
 +      #
 +      # Check for the eventfd header.
 +      #
 +      for ac_header in sys/eventfd.h
 +do :
 +  ac_fn_c_check_header_mongrel "$LINENO" "sys/eventfd.h" "ac_cv_header_sys_eventfd_h" "$ac_includes_default"
 +if test "x$ac_cv_header_sys_eventfd_h" = xyes; then :
 +  cat >>confdefs.h <<_ACEOF
 +#define HAVE_SYS_EVENTFD_H 1
 +_ACEOF
 +
 +fi
 +
  done
  
        ;;
@@@ -5022,7 -5028,7 +5041,7 @@@ $as_echo "$ac_cv_lbl_gcc_fixincludes" >
            fi
      fi
  
 -for ac_func in strerror strerror_r strerror_s strlcpy strlcat
 +for ac_func in strerror strerror_r strerror_s
  do :
    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
  ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
  
  fi
  
 +needstrlcat=no
 +for ac_func in strlcat
 +do :
 +  ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
 +if test "x$ac_cv_func_strlcat" = xyes; then :
 +  cat >>confdefs.h <<_ACEOF
 +#define HAVE_STRLCAT 1
 +_ACEOF
 +
 +else
 +  needstrlcat=yes
 +fi
 +done
 +
 +if test $needstrlcat = yes; then
 +      case " $LIBOBJS " in
 +  *" strlcat.$ac_objext "* ) ;;
 +  *) LIBOBJS="$LIBOBJS strlcat.$ac_objext"
 + ;;
 +esac
 +
 +fi
 +
 +needstrlcpy=no
 +for ac_func in strlcpy
 +do :
 +  ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
 +if test "x$ac_cv_func_strlcpy" = xyes; then :
 +  cat >>confdefs.h <<_ACEOF
 +#define HAVE_STRLCPY 1
 +_ACEOF
 +
 +else
 +  needstrlcpy=yes
 +fi
 +done
 +
 +if test $needstrlcpy = yes; then
 +      case " $LIBOBJS " in
 +  *" strlcpy.$ac_objext "* ) ;;
 +  *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext"
 + ;;
 +esac
 +
 +fi
 +
  needstrtok_r=no
  for ac_func in strtok_r
  do :
        xxx_only=yes
        ;;
  
 +dpdk)
 +      #
 +      # --with-pcap=dpdk is the only way to get here, and it means
 +      # "DPDK support but nothing else"
 +      #
 +      V_DEFS="$V_DEFS -DDPDK_ONLY"
 +      xxx_only=yes
 +      ;;
 +
  septel)
        #
        # --with-pcap=septel is the only way to get here, and it means
@@@ -6983,7 -6934,7 +7002,7 @@@ don
        if test "$ac_cv_header_dagapi_h" = yes; then
  
                if test $V_PCAP != dag ; then
 -                       SSRC="$SSRC pcap-dag.c"
 +                       MSRC="$MSRC pcap-dag.c"
                fi
  
                # Check for various DAG API functions.
@@@ -7315,7 -7266,7 +7334,7 @@@ $as_echo "yes ($septel_include_dir)" >&
                ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o"
  
                if test "$V_PCAP" != septel ; then
 -                       SSRC="$SSRC pcap-septel.c"
 +                       MSRC="$MSRC pcap-septel.c"
                fi
  
  
@@@ -7477,7 -7428,7 +7496,7 @@@ $as_echo "yes ($snf_root)" >&6; 
                LDFLAGS="$LDFLAGS -L$snf_lib_dir"
  
                if test "$V_PCAP" != snf ; then
 -                      SSRC="$SSRC pcap-snf.c"
 +                      MSRC="$MSRC pcap-snf.c"
                fi
  
  
@@@ -7575,7 -7526,7 +7594,7 @@@ rm -f core conftest.err conftest.$ac_ob
                { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
  $as_echo "yes" >&6; }
  
 -              SSRC="$SSRC pcap-tc.c"
 +              MSRC="$MSRC pcap-tc.c"
                V_INCLS="$V_INCLS $TURBOCAP_CFLAGS"
                LIBS="$LIBS $TURBOCAP_LIBS -lTcApi -lpthread -lstdc++"
  
  fi
  
  
+   #
+   # Optionally, we may want to forward packets over SSL:
+   #
+ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       if test -n "$ac_tool_prefix"; then
+   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if ${ac_cv_path_PKG_CONFIG+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+   case $PKG_CONFIG in
+   [\\/]* | ?:[\\/]*)
+   ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+   ;;
+   *)
+   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+   IFS=$as_save_IFS
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+     ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+ done
+   done
+ IFS=$as_save_IFS
+   ;;
+ esac
+ fi
+ PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+ if test -n "$PKG_CONFIG"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+ $as_echo "$PKG_CONFIG" >&6; }
+ else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ fi
+ fi
+ if test -z "$ac_cv_path_PKG_CONFIG"; then
+   ac_pt_PKG_CONFIG=$PKG_CONFIG
+   # Extract the first word of "pkg-config", so it can be a program name with args.
+ set dummy pkg-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+   case $ac_pt_PKG_CONFIG in
+   [\\/]* | ?:[\\/]*)
+   ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+   ;;
+   *)
+   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+   IFS=$as_save_IFS
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+     ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+ done
+   done
+ IFS=$as_save_IFS
+   ;;
+ esac
+ fi
+ ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+ if test -n "$ac_pt_PKG_CONFIG"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+ $as_echo "$ac_pt_PKG_CONFIG" >&6; }
+ else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ fi
+   if test "x$ac_pt_PKG_CONFIG" = x; then
+     PKG_CONFIG=""
+   else
+     case $cross_compiling:$ac_tool_warned in
+ yes:)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+ $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ ac_tool_warned=yes ;;
+ esac
+     PKG_CONFIG=$ac_pt_PKG_CONFIG
+   fi
+ else
+   PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+ fi
+ fi
+ if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=0.9.0
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+ $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+       else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+               PKG_CONFIG=""
+       fi
+ fi
+ pkg_failed=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
+ $as_echo_n "checking for OPENSSL... " >&6; }
+ if test -n "$OPENSSL_CFLAGS"; then
+     pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
+  elif test -n "$PKG_CONFIG"; then
+     if test -n "$PKG_CONFIG" && \
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+   ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+   ac_status=$?
+   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+   test $ac_status = 0; }; then
+   pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+ else
+   pkg_failed=yes
+ fi
+  else
+     pkg_failed=untried
+ fi
+ if test -n "$OPENSSL_LIBS"; then
+     pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS"
+  elif test -n "$PKG_CONFIG"; then
+     if test -n "$PKG_CONFIG" && \
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+   ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+   ac_status=$?
+   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+   test $ac_status = 0; }; then
+   pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+ else
+   pkg_failed=yes
+ fi
+  else
+     pkg_failed=untried
+ fi
+ if test $pkg_failed = yes; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+         _pkg_short_errors_supported=yes
+ else
+         _pkg_short_errors_supported=no
+ fi
+         if test $_pkg_short_errors_supported = yes; then
+               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1`
+         else
+               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1`
+         fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$OPENSSL_PKG_ERRORS" >&5
+       { $as_echo "$as_me:${as_lineno-$LINENO}: No openssl detected" >&5
+ $as_echo "$as_me: No openssl detected" >&6;}
+ elif test $pkg_failed = untried; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+       { $as_echo "$as_me:${as_lineno-$LINENO}: No openssl detected" >&5
+ $as_echo "$as_me: No openssl detected" >&6;}
+ else
+       OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS
+       OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+ $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h
+      CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
+      LIBS="$LIBS $OPENSSL_LIBS"
+      HAVE_OPENSSL="yes"
+ fi
  
  $as_echo "#define ENABLE_REMOTE /**/" >>confdefs.h
  
-       MSRC="$MSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c"
 -      SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
++      MSRC="$MSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
        BUILD_RPCAPD=build-rpcapd
        INSTALL_RPCAPD=install-rpcapd
        ;;
        if test "$enable_universal" != "no"; then
                case "$host_os" in
  
 -              darwin0-7.*)
 +              darwin[0-7].*)
                        #
                        # Pre-Tiger.  Build only for 32-bit PowerPC; no
                        # need for any special compiler or linker flags.
                        #
                        ;;
  
 -              darwin8.0123*)
 +              darwin8.[0123]|darwin8.[0123].*)
                        #
 -                      # Tiger, prior to Intel support.  Build for 32-bit
 -                      # PowerPC and 64-bit PowerPC, with 32-bit PowerPC
 -                      # first.  (I'm guessing that's what Apple does.)
 +                      # Tiger, prior to Intel support.  Build
 +                      # libraries and executables for 32-bit PowerPC
 +                      # and 64-bit PowerPC, with 32-bit PowerPC first.
 +                      # (I'm guessing that's what Apple does.)
 +                      #
 +                      # (The double brackets are needed because
 +                      # autotools/m4 use brackets as a quoting
 +                      # character; the double brackets turn into
 +                      # single brackets in the generated configure
 +                      # file.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64"
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64"
                        ;;
  
 -              darwin8.456*)
 +              darwin8.[456]|darwin.[456].*)
                        #
 -                      # Tiger, subsequent to Intel support but prior to
 -                      # x86-64 support.  Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, and x86, with 32-bit PowerPC first.
 -                      # (I'm guessing that's what Apple does.)
 +                      # Tiger, subsequent to Intel support but prior
 +                      # to x86-64 support.  Build libraries and
 +                      # executables for 32-bit PowerPC, 64-bit
 +                      # PowerPC, and 32-bit x86, with 32-bit PowerPC
 +                      # first.  (I'm guessing that's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386"
 +                      # (The double brackets are needed because
 +                      # autotools/m4 use brackets as a quoting
 +                      # character; the double brackets turn into
 +                      # single brackets in the generated configure
 +                      # file.)
 +                      #
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
                        ;;
  
                darwin8.*)
                        #
                        # All other Tiger, so subsequent to x86-64
 -                      # support. Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, x86, and x86-64, and with 32-bit PowerPC
 -                      # first.  (I'm guessing that's what Apple does.)
 -                      #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      # support.  Build libraries and executables for
 +                      # 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
 +                      # and x86-64, with 32-bit PowerPC first.  (I'm
 +                      # guessing that's what Apple does.)
 +                      #
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
                        ;;
  
                darwin9.*)
                        #
 -                      # Leopard.  Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, x86, and x86-64, with 32-bit PowerPC
 -                      # first.  (That's what Apple does.)
 +                      # Leopard.  Build libraries for 32-bit PowerPC,
 +                      # 64-bit PowerPC, 32-bit x86, and x86-64, with
 +                      # 32-bit PowerPC first, and build executables
 +                      # for 32-bit x86 and 32-bit PowerPC, with 32-bit
 +                      # x86 first.  (That's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_CCOPT_FAT="-arch i386 -arch ppc"
 +                      V_PROG_LDFLAGS_FAT="-arch i386 -arch ppc"
                        ;;
  
                darwin10.*)
                        #
 -                      # Snow Leopard.  Build for x86-64, x86, and
 -                      # 32-bit PowerPC, with x86-64 first.  (That's
 -                      # what Apple does, even though Snow Leopard
 -                      # doesn't run on PPC, so PPC libpcap runs under
 -                      # Rosetta, and Rosetta doesn't support BPF
 -                      # ioctls, so PPC programs can't do live
 -                      # captures.)
 -                      #
 -                      V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
 -                      LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
 +                      # Snow Leopard.  Build libraries for x86-64,
 +                      # 32-bit x86, and 32-bit PowerPC, with x86-64
 +                      # first, and build executables for x86-64 and
 +                      # 32-bit x86, with x86-64 first.  (That's what
 +                      # Apple does, even though Snow Leopard doesn't
 +                      # run on PPC, so PPC libpcap runs under Rosetta,
 +                      # and Rosetta doesn't support BPF ioctls, so PPC
 +                      # programs can't do live captures.)
 +                      #
 +                      V_LIB_CCOPT_FAT="-arch x86_64 -arch i386 -arch ppc"
 +                      V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386 -arch ppc"
 +                      V_PROG_CCOPT_FAT="-arch x86_64 -arch i386"
 +                      V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386"
                        ;;
  
                darwin*)
                        #
 -                      # Post-Snow Leopard.  Build for x86-64 and
 -                      # x86, with x86-64 first.  (That's probably what
 -                      # Apple does, given that Rosetta is gone.)
 +                      # Post-Snow Leopard.  Build libraries for x86-64
 +                      # and 32-bit x86, with x86-64 first, and build
 +                      # executables only for x86-64.  (That's what
 +                      # Apple does.)  This requires no special flags
 +                      # for programs.
                        # XXX - update if and when Apple drops support
 -                      # for 32-bit x86 code.
 +                      # for 32-bit x86 code and if and when Apple adds
 +                      # ARM-based Macs.  (You're on your own for iOS
 +                      # etc.)
 +                      #
 +                      # XXX - check whether we *can* build for
 +                      # i386 and, if not, suggest that the user
 +                      # install the /usr/include headers if they
 +                      # want to build fat.
                        #
 -                      V_CCOPT="$V_CCOPT -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch x86_64"
 +                      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether building for 32-bit x86 is supported" >&5
 +$as_echo_n "checking whether building for 32-bit x86 is supported... " >&6; }
 +                      save_CFLAGS="$CFLAGS"
 +                      CFLAGS="$CFLAGS -arch i386"
 +                      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 +/* end confdefs.h.  */
 +
 +int
 +main ()
 +{
 +return 0;
 +  ;
 +  return 0;
 +}
 +_ACEOF
 +if ac_fn_c_try_compile "$LINENO"; then :
 +
 +                              { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 +$as_echo "yes" >&6; }
-                               V_LIB_CCOPT_FAT="-arch x86_64 -arch i386"
-                               V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386"
++                              V_LIB_CCOPT_FAT="-arch x86_64"
++                              V_LIB_LDFLAGS_FAT="-arch x86_64"
++
++                              #
++                              # OpenSSL installation on macOS seems
++                              # to install only the libs for 64-bit
++                              # x86 - at least that's what Brew does:
++                              # only configure 32-bit builds if we
++                              # don't have OpenSSL.
++                              #
++                              if test "$HAVE_OPENSSL" != yes; then
++                                      V_LIB_CCOPT_FAT="$V_LIB_CCOPT_FAT -arch i386"
++                                      V_LIB_LDFLAGS_FAT="$V_LIB_LDFLAGS_FAT -arch i386"
++                              fi
 +
 +else
 +
 +                              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 +$as_echo "no" >&6; }
 +                              V_LIB_CCOPT_FAT="-arch x86_64"
 +                              V_LIB_LDFLAGS_FAT="-arch x86_64"
 +                              case "$host_os" in
 +
 +                              darwin18.*)
 +                                      #
 +                                      # Mojave; you need to install the
 +                                      # /usr/include headers to get
 +                                      # 32-bit x86 builds to work.
 +                                      #
 +                                      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package" >&5
 +$as_echo "$as_me: WARNING: Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package" >&2;}
 +                                      ;;
 +
 +                              *)
 +                                      #
 +                                      # Pre-Mojave; the command-line
 +                                      # tools should be sufficient to
 +                                      # enable 32-bit x86 builds.
 +                                      #
 +                                      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiling for 32-bit x86 gives an error; try installing the command-line tools" >&5
 +$as_echo "$as_me: WARNING: Compiling for 32-bit x86 gives an error; try installing the command-line tools" >&2;}
 +                                      ;;
 +                              esac
 +
 +fi
 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 +                      CFLAGS="$save_CFLAGS"
+                       if test "$HAVE_OPENSSL" = yes; then
 -                              # If all else fail, look for openssl in /usr/local/opt:
++                              #
++                              # If all else fails, look for OpenSSL in
++                              # /usr/local/opt.
++                              #
+                               CFLAGS="$CFLAGS -I/usr/local/opt/openssl/include"
+                               LIBS="$LIBS -L/usr/local/opt/openssl/lib"
 -                      else
 -                              # Openssl installation on MacOS seems to install only the libs for
 -                              # the amd64 ABI; at least that's what brew does:
 -                              V_CCOPT="$V_CCOPT -arch i386"
 -                              LDFLAGS="$LDFLAGS -arch i386"
+                       fi
                        ;;
                esac
        fi
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  
  
 -      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wdeclaration-after-statement option" >&5
 -$as_echo_n "checking whether the compiler supports the -Wdeclaration-after-statement option... " >&6; }
 -      save_CFLAGS="$CFLAGS"
 -      if expr "x-Wdeclaration-after-statement" : "x-W.*" >/dev/null
 -      then
 -          CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wdeclaration-after-statement"
 -      elif expr "x-Wdeclaration-after-statement" : "x-f.*" >/dev/null
 -      then
 -          CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement"
 -      elif expr "x-Wdeclaration-after-statement" : "x-m.*" >/dev/null
 -      then
 -          CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement"
 -      else
 -          CFLAGS="$CFLAGS -Wdeclaration-after-statement"
 -      fi
 -      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 -/* end confdefs.h.  */
 -
 -int
 -main ()
 -{
 -return 0
 -  ;
 -  return 0;
 -}
 -_ACEOF
 -if ac_fn_c_try_compile "$LINENO"; then :
 -
 -              { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 -$as_echo "yes" >&6; }
 -              can_add_to_cflags=yes
 -              #
 -              # The compile supports this; do we have some C code for
 -              # which the warning should *not* appear?
 -              # We test the fourth argument because the third argument
 -              # could contain quotes, breaking the test.
 -              #
 -              if test "x" != "x"
 -              then
 -                  CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
 -                  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wdeclaration-after-statement " >&5
 -$as_echo_n "checking whether -Wdeclaration-after-statement ... " >&6; }
 -                  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 -/* end confdefs.h.  */
 -
 -_ACEOF
 -if ac_fn_c_try_compile "$LINENO"; then :
 -
 -                      #
 -                      # Not a problem.
 -                      #
 -                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 -$as_echo "no" >&6; }
 -
 -else
 -
 -                      #
 -                      # A problem.
 -                      #
 -                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 -$as_echo "yes" >&6; }
 -                      can_add_to_cflags=no
 -
 -fi
 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 -              fi
 -              CFLAGS="$save_CFLAGS"
 -              if test x"$can_add_to_cflags" = "xyes"
 -              then
 -                  V_CCOPT="$V_CCOPT -Wdeclaration-after-statement"
 -              fi
 -
 -else
 -
 -              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 -$as_echo "no" >&6; }
 -              CFLAGS="$save_CFLAGS"
 -
 -fi
 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 -
 -
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wdocumentation option" >&5
  $as_echo_n "checking whether the compiler supports the -Wdocumentation option... " >&6; }
        save_CFLAGS="$CFLAGS"
  
  
  
 +
 +
 +
 +
 +
  
  
  
@@@ -10179,7 -10330,7 +10420,7 @@@ $as_echo_n "checking for USB sniffing s
  
  $as_echo "#define PCAP_SUPPORT_USB 1" >>confdefs.h
  
 -      USB_SRC=pcap-usb-linux.c
 +      MSRC="$MSRC pcap-usb-linux.c"
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
  $as_echo "yes" >&6; }
        ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
  fi
  
  
 -
  if test "xxx_only" != yes; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the platform could support netfilter sniffing" >&5
  $as_echo_n "checking whether the platform could support netfilter sniffing... " >&6; }
@@@ -10338,7 -10490,7 +10579,7 @@@ $as_echo "$ac_cv_netfilter_can_compile
  
  $as_echo "#define PCAP_SUPPORT_NETFILTER 1" >>confdefs.h
  
 -                NETFILTER_SRC=pcap-netfilter-linux.c
 +                MSRC="$MSRC pcap-netfilter-linux.c"
                fi
                ;;
        *)
@@@ -10349,6 -10501,7 +10590,6 @@@ $as_echo "no" >&6; 
  fi
  
  
 -
  # Check whether --enable-netmap was given.
  if test "${enable_netmap+set}" = set; then :
    enableval=$enable_netmap;
@@@ -10397,124 -10550,10 +10638,124 @@@ $as_echo "$ac_cv_net_netmap_user_can_co
  
  $as_echo "#define PCAP_SUPPORT_NETMAP 1" >>confdefs.h
  
 -          NETMAP_SRC=pcap-netmap.c
 +          MSRC="$MSRC pcap-netmap.c"
        fi
  
 +fi
 +
 +# Check for DPDK support.
  
 +# Check whether --with-dpdk was given.
 +if test "${with_dpdk+set}" = set; then :
 +  withval=$with_dpdk;
 +      if test "$withval" = no
 +      then
 +              # User doesn't want DPDK support.
 +              want_dpdk=no
 +      elif test "$withval" = yes
 +      then
 +              # User wants DPDK support but hasn't specified a directory.
 +              want_dpdk=yes
 +      else
 +              # User wants DPDK support and has specified a directory, so use the provided value.
 +              want_dpdk=yes
 +              dpdk_dir=$withval
 +              dpdk_inc_dir="$dpdk_dir/include"
 +              dpdk_lib_dir="$dpdk_dir/lib"
 +      fi
 +
 +else
 +
 +      if test "$V_PCAP" = dpdk; then
 +              # User requested DPDK-only libpcap, so we'd better have
 +              # the DPDK API.
 +              want_dpdk=yes
 +      elif test "xxx_only" = yes; then
 +              # User requested something-else-only pcap, so they don't
 +              # want DPDK support.
 +              want_dpdk=no
 +      else
 +              #
 +              # Use DPDK API if present, otherwise don't
 +              #
 +              want_dpdk=ifpresent
 +      fi
 +
 +fi
 +
 +
 +if test "$want_dpdk" != no; then
 +      if test -z "$dpdk_dir"; then
 +              dpdk_inc_dir="/usr/local/include/dpdk"
 +              dpdk_lib_dir="/usr/local/lib"
 +      fi
 +      DPDK_MACHINE_CFLAGS="-march=native"
 +      DPDK_CFLAGS="$DPDK_MACHINE_CFLAGS -I$dpdk_inc_dir"
 +      DPDK_LDFLAGS="-L$dpdk_lib_dir -ldpdk -lrt -lm -lnuma -ldl -pthread"
 +
 +      save_CFLAGS="$CFLAGS"
 +      save_LIBS="$LIBS"
 +      save_LDFLAGS="$LDFLAGS"
 +      CFLAGS="$CFLAGS $DPDK_CFLAGS"
 +      LIBS="$LIBS $DPDK_LDFLAGS"
 +      LDFLAGS="$LDFLAGS $DPDK_LDFLAGS"
 +
 +      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can compile the DPDK support" >&5
 +$as_echo_n "checking whether we can compile the DPDK support... " >&6; }
 +      if ${ac_cv_dpdk_can_compile+:} false; then :
 +  $as_echo_n "(cached) " >&6
 +else
 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 +/* end confdefs.h.  */
 +
 +$ac_includes_default
 +#include <rte_common.h>
 +int
 +main ()
 +{
 +
 +  ;
 +  return 0;
 +}
 +_ACEOF
 +if ac_fn_c_try_compile "$LINENO"; then :
 +  ac_cv_dpdk_can_compile=yes
 +else
 +  ac_cv_dpdk_can_compile=no
 +fi
 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 +fi
 +
 +      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dpdk_can_compile" >&5
 +$as_echo "$ac_cv_dpdk_can_compile" >&6; }
 +
 +      CFLAGS=$save_LDFLAGS
 +      LIBS=$save_LIBS
 +      LDFLAGS=$save_LDFLAGS
 +
 +      if test "$ac_cv_dpdk_can_compile" = yes; then
 +              CFLAGS="$CFLAGS $DPDK_CFLAGS"
 +              LIBS="$LIBS $DPDK_LDFLAGS"
 +              LDFLAGS="$LDFLAGS $DPDK_LDFLAGS"
 +              V_INCLS="$V_INCLS $DPDK_CFLAGS"
 +
 +$as_echo "#define PCAP_SUPPORT_DPDK 1" >>confdefs.h
 +
 +              if test $V_PCAP != dpdk ; then
 +                      MSRC="$MSRC pcap-dpdk.c"
 +              fi
 +      else
 +              if test "$V_PCAP" = dpdk; then
 +                      # User requested "dpdk" capture type but we couldn't
 +                      # find the DPDK API support.
 +                      as_fn_error $? "DPDK support requested with --with-pcap=dpdk, but the DPDK headers weren't found at $dpdk_inc_dir: make sure the DPDK support is installed, specify a different path or paths if necessary, or don't request DPDK support" "$LINENO" 5
 +              fi
 +
 +              if test "$want_dpdk" = yes; then
 +                      # User wanted DPDK support but we couldn't find it.
 +                      as_fn_error $? "DPDK support requested with --with-pcap=dpdk, but the DPDK headers weren't found at $dpdk_inc_dir: make sure the DPDK support is installed, specify a different path or paths if necessary, or don't request DPDK support" "$LINENO" 5
 +              fi
 +      fi
  fi
  
  
@@@ -10545,7 -10584,7 +10786,7 @@@ if test "x$ac_cv_header_bluetooth_bluet
  
  $as_echo "#define PCAP_SUPPORT_BT 1" >>confdefs.h
  
 -                      BT_SRC=pcap-bt-linux.c
 +                      MSRC="$MSRC pcap-bt-linux.c"
                        { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is supported" >&5
  $as_echo "$as_me: Bluetooth sniffing is supported" >&6;}
                        ac_lbl_bluetooth_available=yes
@@@ -10597,7 -10636,7 +10838,7 @@@ $as_echo "yes" >&6; 
  
  $as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h
  
 -                                          BT_MONITOR_SRC=pcap-bt-monitor-linux.c
 +                                          MSRC="$MSRC pcap-bt-monitor-linux.c"
  
  else
  
@@@ -10639,6 -10678,8 +10880,6 @@@ $as_echo "$as_me: no Bluetooth sniffin
                ;;
        esac
  
 -
 -
  fi
  
  # Check whether --enable-dbus was given.
@@@ -10763,7 -10804,7 +11004,7 @@@ $as_echo "yes" >&6; 
  
  $as_echo "#define PCAP_SUPPORT_DBUS 1" >>confdefs.h
  
 -                              DBUS_SRC=pcap-dbus.c
 +                              MSRC="$MSRC pcap-dbus.c"
                                V_INCLS="$V_INCLS $DBUS_CFLAGS"
  
  else
@@@ -10788,23 -10829,24 +11029,23 @@@ $as_echo "no" >&6; 
                fi
        fi
  
 -
  fi
  
  # Check whether --enable-rdma was given.
  if test "${enable_rdma+set}" = set; then :
    enableval=$enable_rdma;
  else
 -  enable_rdmasniff=ifavailable
 +  enable_rdma=ifavailable
  fi
  
  
  if test "xxx_only" = yes; then
        # User requested something-else-only pcap, so they don't
        # want RDMA support.
 -      enable_rdmasniff=no
 +      enable_rdma=no
  fi
  
 -if test "x$enable_rdmasniff" != "xno"; then
 +if test "x$enable_rdma" != "xno"; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ibv_get_device_list in -libverbs" >&5
  $as_echo_n "checking for ibv_get_device_list in -libverbs... " >&6; }
  if ${ac_cv_lib_ibverbs_ibv_get_device_list+:} false; then :
@@@ -10882,7 -10924,7 +11123,7 @@@ $as_echo "yes" >&6; 
  
  $as_echo "#define PCAP_SUPPORT_RDMASNIFF /**/" >>confdefs.h
  
 -                                      RDMA_SRC=pcap-rdmasniff.c
 +                                      MSRC="$MSRC pcap-rdmasniff.c"
                                        LIBS="-libverbs $LIBS"
  
  else
  fi
  
  
 -
  fi
  
  # Find a good install program.  We prefer a C program (faster),
diff --combined configure.ac
index 55a794744790dcb899de472af8133f64e0a07ade,aeb7cb8bf0d1faf9185f546329a3438b1d01e609..069d9f8ab0c8ba9d648188b6b33ebf6b95a5b5ff
@@@ -28,9 -28,6 +28,9 @@@ AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCL
  # At minimum, we want C++/C99-style // comments.
  #
  AC_PROG_CC_C99
 +if test "$ac_cv_prog_cc_c99" = "no"; then
 +      AC_MSG_WARN([The C compiler does not support C99; there may be compiler errors])
 +fi
  AC_LBL_C_INIT(V_CCOPT, V_INCLS)
  AC_LBL_SHLIBS_INIT
  AC_LBL_C_INLINE
@@@ -76,25 -73,17 +76,25 @@@ f
  
  case "$host_os" in
  linux*|uclinux*)
 +      #
 +      # linux/if_bonding.h requires sys/socket.h.
 +      #
        AC_CHECK_HEADERS(linux/sockios.h linux/if_bonding.h,,,
        [
  #include <sys/socket.h>
  #include <linux/if.h>
        ])
 +
 +      #
 +      # Check for the eventfd header.
 +      #
 +      AC_CHECK_HEADERS(sys/eventfd.h)
        ;;
  esac
  
  AC_LBL_FIXINCLUDES
  
 -AC_CHECK_FUNCS(strerror strerror_r strerror_s strlcpy strlcat)
 +AC_CHECK_FUNCS(strerror strerror_r strerror_s)
  
  needsnprintf=no
  AC_CHECK_FUNCS(vsnprintf snprintf,,
@@@ -103,20 -92,6 +103,20 @@@ if test $needsnprintf = yes; the
        AC_LIBOBJ([snprintf])
  fi
  
 +needstrlcat=no
 +AC_CHECK_FUNCS(strlcat,,
 +      [needstrlcat=yes])
 +if test $needstrlcat = yes; then
 +      AC_LIBOBJ([strlcat])
 +fi
 +
 +needstrlcpy=no
 +AC_CHECK_FUNCS(strlcpy,,
 +      [needstrlcpy=yes])
 +if test $needstrlcpy = yes; then
 +      AC_LIBOBJ([strlcpy])
 +fi
 +
  needstrtok_r=no
  AC_CHECK_FUNCS(strtok_r,,
        [needstrtok_r=yes])
@@@ -902,15 -877,6 +902,15 @@@ dag
        xxx_only=yes
        ;;
  
 +dpdk)
 +      #
 +      # --with-pcap=dpdk is the only way to get here, and it means
 +      # "DPDK support but nothing else"
 +      #
 +      V_DEFS="$V_DEFS -DDPDK_ONLY"
 +      xxx_only=yes
 +      ;;
 +
  septel)
        #
        # --with-pcap=septel is the only way to get here, and it means
@@@ -1117,7 -1083,7 +1117,7 @@@ if test "$want_dag" != no; the
        if test "$ac_cv_header_dagapi_h" = yes; then
  
                if test $V_PCAP != dag ; then
 -                       SSRC="$SSRC pcap-dag.c"
 +                       MSRC="$MSRC pcap-dag.c"
                fi
  
                # Check for various DAG API functions.
@@@ -1228,7 -1194,7 +1228,7 @@@ if test "$with_septel" != no; the
                ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o"
  
                if test "$V_PCAP" != septel ; then
 -                       SSRC="$SSRC pcap-septel.c"
 +                       MSRC="$MSRC pcap-septel.c"
                fi
  
                AC_DEFINE(HAVE_SEPTEL_API, 1, [define if you have the Septel API])
@@@ -1335,7 -1301,7 +1335,7 @@@ if test "$with_snf" != no; the
                LDFLAGS="$LDFLAGS -L$snf_lib_dir"
  
                if test "$V_PCAP" != snf ; then
 -                      SSRC="$SSRC pcap-snf.c"
 +                      MSRC="$MSRC pcap-snf.c"
                fi
  
                AC_DEFINE(HAVE_SNF_API, 1, [define if you have the Myricom SNF API])
@@@ -1412,7 -1378,7 +1412,7 @@@ if test "$want_turbocap" != no; the
        if test $ac_cv_lbl_turbocap_api = yes; then
                AC_MSG_RESULT(yes)
  
 -              SSRC="$SSRC pcap-tc.c"
 +              MSRC="$MSRC pcap-tc.c"
                V_INCLS="$V_INCLS $TURBOCAP_CFLAGS"
                LIBS="$LIBS $TURBOCAP_LIBS -lTcApi -lpthread -lstdc++"
  
@@@ -1487,9 -1453,19 +1487,19 @@@ yes)  AC_MSG_RESULT(yes
                #include <sys/socket.h>
            ])
  
+   #
+   # Optionally, we may want to forward packets over SSL:
+   #
+   PKG_CHECK_MODULES([OPENSSL], [openssl],
+     [AC_DEFINE([HAVE_OPENSSL], [1], [Use OpenSSL])
+      CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
+      LIBS="$LIBS $OPENSSL_LIBS"
+      HAVE_OPENSSL="yes"],
+     AC_MSG_NOTICE(No openssl detected))
        AC_DEFINE(ENABLE_REMOTE,,
            [Define to 1 if remote packet capture is to be supported])
-       MSRC="$MSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c"
 -      SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
++      MSRC="$MSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
        BUILD_RPCAPD=build-rpcapd
        INSTALL_RPCAPD=install-rpcapd
        ;;
@@@ -1622,151 -1598,89 +1632,171 @@@ darwin*
        if test "$enable_universal" != "no"; then
                case "$host_os" in
  
 -              darwin[0-7].*)
 +              darwin[[0-7]].*)
                        #
                        # Pre-Tiger.  Build only for 32-bit PowerPC; no
                        # need for any special compiler or linker flags.
                        #
                        ;;
  
 -              darwin8.[0123]*)
 +              darwin8.[[0123]]|darwin8.[[0123]].*)
                        #
 -                      # Tiger, prior to Intel support.  Build for 32-bit
 -                      # PowerPC and 64-bit PowerPC, with 32-bit PowerPC
 -                      # first.  (I'm guessing that's what Apple does.)
 +                      # Tiger, prior to Intel support.  Build
 +                      # libraries and executables for 32-bit PowerPC
 +                      # and 64-bit PowerPC, with 32-bit PowerPC first.
 +                      # (I'm guessing that's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64"
 +                      # (The double brackets are needed because
 +                      # autotools/m4 use brackets as a quoting
 +                      # character; the double brackets turn into
 +                      # single brackets in the generated configure
 +                      # file.)
 +                      #
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64"
                        ;;
  
 -              darwin8.[456]*)
 +              darwin8.[[456]]|darwin.[[456]].*)
                        #
 -                      # Tiger, subsequent to Intel support but prior to
 -                      # x86-64 support.  Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, and x86, with 32-bit PowerPC first.
 -                      # (I'm guessing that's what Apple does.)
 +                      # Tiger, subsequent to Intel support but prior
 +                      # to x86-64 support.  Build libraries and
 +                      # executables for 32-bit PowerPC, 64-bit
 +                      # PowerPC, and 32-bit x86, with 32-bit PowerPC
 +                      # first.  (I'm guessing that's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386"
 +                      # (The double brackets are needed because
 +                      # autotools/m4 use brackets as a quoting
 +                      # character; the double brackets turn into
 +                      # single brackets in the generated configure
 +                      # file.)
 +                      #
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
                        ;;
  
                darwin8.*)
                        #
                        # All other Tiger, so subsequent to x86-64
 -                      # support. Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, x86, and x86-64, and with 32-bit PowerPC
 -                      # first.  (I'm guessing that's what Apple does.)
 +                      # support.  Build libraries and executables for
 +                      # 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
 +                      # and x86-64, with 32-bit PowerPC first.  (I'm
 +                      # guessing that's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
                        ;;
  
                darwin9.*)
                        #
 -                      # Leopard.  Build for 32-bit PowerPC, 64-bit
 -                      # PowerPC, x86, and x86-64, with 32-bit PowerPC
 -                      # first.  (That's what Apple does.)
 +                      # Leopard.  Build libraries for 32-bit PowerPC,
 +                      # 64-bit PowerPC, 32-bit x86, and x86-64, with
 +                      # 32-bit PowerPC first, and build executables
 +                      # for 32-bit x86 and 32-bit PowerPC, with 32-bit
 +                      # x86 first.  (That's what Apple does.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
 +                      V_PROG_CCOPT_FAT="-arch i386 -arch ppc"
 +                      V_PROG_LDFLAGS_FAT="-arch i386 -arch ppc"
                        ;;
  
                darwin10.*)
                        #
 -                      # Snow Leopard.  Build for x86-64, x86, and
 -                      # 32-bit PowerPC, with x86-64 first.  (That's
 -                      # what Apple does, even though Snow Leopard
 -                      # doesn't run on PPC, so PPC libpcap runs under
 -                      # Rosetta, and Rosetta doesn't support BPF
 -                      # ioctls, so PPC programs can't do live
 -                      # captures.)
 +                      # Snow Leopard.  Build libraries for x86-64,
 +                      # 32-bit x86, and 32-bit PowerPC, with x86-64
 +                      # first, and build executables for x86-64 and
 +                      # 32-bit x86, with x86-64 first.  (That's what
 +                      # Apple does, even though Snow Leopard doesn't
 +                      # run on PPC, so PPC libpcap runs under Rosetta,
 +                      # and Rosetta doesn't support BPF ioctls, so PPC
 +                      # programs can't do live captures.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
 -                      LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
 +                      V_LIB_CCOPT_FAT="-arch x86_64 -arch i386 -arch ppc"
 +                      V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386 -arch ppc"
 +                      V_PROG_CCOPT_FAT="-arch x86_64 -arch i386"
 +                      V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386"
                        ;;
  
                darwin*)
                        #
 -                      # Post-Snow Leopard.  Build for x86-64 and
 -                      # x86, with x86-64 first.  (That's probably what
 -                      # Apple does, given that Rosetta is gone.)
 +                      # Post-Snow Leopard.  Build libraries for x86-64
 +                      # and 32-bit x86, with x86-64 first, and build
 +                      # executables only for x86-64.  (That's what
 +                      # Apple does.)  This requires no special flags
 +                      # for programs.
                        # XXX - update if and when Apple drops support
 -                      # for 32-bit x86 code.
 +                      # for 32-bit x86 code and if and when Apple adds
 +                      # ARM-based Macs.  (You're on your own for iOS
 +                      # etc.)
                        #
 -                      V_CCOPT="$V_CCOPT -arch x86_64"
 -                      LDFLAGS="$LDFLAGS -arch x86_64"
 +                      # XXX - check whether we *can* build for
 +                      # i386 and, if not, suggest that the user
 +                      # install the /usr/include headers if they
 +                      # want to build fat.
 +                      #
 +                      AC_MSG_CHECKING(whether building for 32-bit x86 is supported)
 +                      save_CFLAGS="$CFLAGS"
 +                      CFLAGS="$CFLAGS -arch i386"
 +                      AC_TRY_COMPILE(
 +                          [],
 +                          [return 0;],
 +                          [
 +                              AC_MSG_RESULT(yes)
-                               V_LIB_CCOPT_FAT="-arch x86_64 -arch i386"
-                               V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386"
++                              V_LIB_CCOPT_FAT="-arch x86_64"
++                              V_LIB_LDFLAGS_FAT="-arch x86_64"
++
++                              #
++                              # OpenSSL installation on macOS seems
++                              # to install only the libs for 64-bit
++                              # x86 - at least that's what Brew does:
++                              # only configure 32-bit builds if we
++                              # don't have OpenSSL.
++                              #
++                              if test "$HAVE_OPENSSL" != yes; then
++                                      V_LIB_CCOPT_FAT="$V_LIB_CCOPT_FAT -arch i386"
++                                      V_LIB_LDFLAGS_FAT="$V_LIB_LDFLAGS_FAT -arch i386"
++                              fi
 +                          ],
 +                          [
 +                              AC_MSG_RESULT(no)
 +                              V_LIB_CCOPT_FAT="-arch x86_64"
 +                              V_LIB_LDFLAGS_FAT="-arch x86_64"
 +                              case "$host_os" in
 +
 +                              darwin18.*)
 +                                      #
 +                                      # Mojave; you need to install the
 +                                      # /usr/include headers to get
 +                                      # 32-bit x86 builds to work.
 +                                      #
 +                                      AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package])
 +                                      ;;
 +
 +                              *)
 +                                      #
 +                                      # Pre-Mojave; the command-line
 +                                      # tools should be sufficient to
 +                                      # enable 32-bit x86 builds.
 +                                      #
 +                                      AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools])
 +                                      ;;
 +                              esac
 +                          ])
 +                      CFLAGS="$save_CFLAGS"
+                       if test "$HAVE_OPENSSL" = yes; then
 -                              # If all else fail, look for openssl in /usr/local/opt:
++                              #
++                              # If all else fails, look for OpenSSL in
++                              # /usr/local/opt.
++                              #
+                               CFLAGS="$CFLAGS -I/usr/local/opt/openssl/include"
+                               LIBS="$LIBS -L/usr/local/opt/openssl/lib"
 -                      else
 -                              # Openssl installation on MacOS seems to install only the libs for
 -                              # the amd64 ABI; at least that's what brew does:
 -                              V_CCOPT="$V_CCOPT -arch i386"
 -                              LDFLAGS="$LDFLAGS -arch i386"
+                       fi
                        ;;
                esac
        fi
@@@ -1961,10 -1875,6 +1991,10 @@@ AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_m
      ])
  
  AC_SUBST(V_CCOPT)
 +AC_SUBST(V_LIB_CCOPT_FAT)
 +AC_SUBST(V_LIB_LDFLAGS_FAT)
 +AC_SUBST(V_PROG_CCOPT_FAT)
 +AC_SUBST(V_PROG_LDFLAGS_FAT)
  AC_SUBST(V_DEFS)
  AC_SUBST(V_FINDALLDEVS)
  AC_SUBST(V_INCLS)
@@@ -1978,7 -1888,6 +2008,7 @@@ AC_SUBST(V_RPATH_OPT
  AC_SUBST(V_YACC)
  AC_SUBST(ADDLOBJS)
  AC_SUBST(ADDLARCHIVEOBJS)
 +AC_SUBST(MSRC)
  AC_SUBST(SSRC)
  AC_SUBST(DYEXT)
  AC_SUBST(MAN_DEVICES)
@@@ -2008,7 -1917,7 +2038,7 @@@ if test "x$enable_usb" != "xno" ; the
     case "$host_os" in
     linux*)
        AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing])
 -      USB_SRC=pcap-usb-linux.c
 +      MSRC="$MSRC pcap-usb-linux.c"
        AC_MSG_RESULT(yes)
        ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
        if test $? -ne 0 ; then
  esac
  fi
  AC_SUBST(PCAP_SUPPORT_USB)
 -AC_SUBST(USB_SRC)
  
  dnl check for netfilter sniffing support
  if test "xxx_only" != yes; then
@@@ -2095,7 -2005,7 +2125,7 @@@ AC_INCLUDES_DEFAUL
                if test $ac_cv_netfilter_can_compile = yes ; then
                  AC_DEFINE(PCAP_SUPPORT_NETFILTER, 1,
                    [target host supports netfilter sniffing])
 -                NETFILTER_SRC=pcap-netfilter-linux.c
 +                MSRC="$MSRC pcap-netfilter-linux.c"
                fi
                ;;
        *)
        esac
  fi
  AC_SUBST(PCAP_SUPPORT_NETFILTER)
 -AC_SUBST(NETFILTER_SRC)
  
  AC_ARG_ENABLE([netmap],
  [AC_HELP_STRING([--enable-netmap],[enable netmap support @<:@default=yes, if support available@:>@])],
@@@ -2130,100 -2041,12 +2160,100 @@@ AC_INCLUDES_DEFAUL
        if test $ac_cv_net_netmap_user_can_compile = yes ; then
          AC_DEFINE(PCAP_SUPPORT_NETMAP, 1,
            [target host supports netmap])
 -          NETMAP_SRC=pcap-netmap.c
 +          MSRC="$MSRC pcap-netmap.c"
        fi
        AC_SUBST(PCAP_SUPPORT_NETMAP)
 -      AC_SUBST(NETMAP_SRC)
  fi
  
 +# Check for DPDK support.
 +AC_ARG_WITH([dpdk],
 +AC_HELP_STRING([--with-dpdk@<:@=DIR@:>@],[include DPDK support (located in directory DIR, if supplied).  @<:@default=yes, if present@:>@]),
 +[
 +      if test "$withval" = no
 +      then
 +              # User doesn't want DPDK support.
 +              want_dpdk=no
 +      elif test "$withval" = yes
 +      then
 +              # User wants DPDK support but hasn't specified a directory.
 +              want_dpdk=yes
 +      else
 +              # User wants DPDK support and has specified a directory, so use the provided value.
 +              want_dpdk=yes
 +              dpdk_dir=$withval
 +              dpdk_inc_dir="$dpdk_dir/include"
 +              dpdk_lib_dir="$dpdk_dir/lib"
 +      fi
 +],[
 +      if test "$V_PCAP" = dpdk; then
 +              # User requested DPDK-only libpcap, so we'd better have
 +              # the DPDK API.
 +              want_dpdk=yes
 +      elif test "xxx_only" = yes; then
 +              # User requested something-else-only pcap, so they don't
 +              # want DPDK support.
 +              want_dpdk=no
 +      else
 +              #
 +              # Use DPDK API if present, otherwise don't
 +              #
 +              want_dpdk=ifpresent
 +      fi
 +])
 +
 +if test "$want_dpdk" != no; then
 +      if test -z "$dpdk_dir"; then
 +              dpdk_inc_dir="/usr/local/include/dpdk"
 +              dpdk_lib_dir="/usr/local/lib"
 +      fi
 +      DPDK_MACHINE_CFLAGS="-march=native"
 +      DPDK_CFLAGS="$DPDK_MACHINE_CFLAGS -I$dpdk_inc_dir"
 +      DPDK_LDFLAGS="-L$dpdk_lib_dir -ldpdk -lrt -lm -lnuma -ldl -pthread"
 +
 +      save_CFLAGS="$CFLAGS"
 +      save_LIBS="$LIBS"
 +      save_LDFLAGS="$LDFLAGS"
 +      CFLAGS="$CFLAGS $DPDK_CFLAGS"
 +      LIBS="$LIBS $DPDK_LDFLAGS"
 +      LDFLAGS="$LDFLAGS $DPDK_LDFLAGS"
 +
 +      AC_MSG_CHECKING(whether we can compile the DPDK support)
 +      AC_CACHE_VAL(ac_cv_dpdk_can_compile,
 +      AC_TRY_COMPILE([
 +AC_INCLUDES_DEFAULT
 +#include <rte_common.h>],
 +          [],
 +          ac_cv_dpdk_can_compile=yes,
 +          ac_cv_dpdk_can_compile=no))
 +      AC_MSG_RESULT($ac_cv_dpdk_can_compile)
 +
 +      CFLAGS=$save_LDFLAGS
 +      LIBS=$save_LIBS
 +      LDFLAGS=$save_LDFLAGS
 +      
 +      if test "$ac_cv_dpdk_can_compile" = yes; then
 +              CFLAGS="$CFLAGS $DPDK_CFLAGS"
 +              LIBS="$LIBS $DPDK_LDFLAGS"
 +              LDFLAGS="$LDFLAGS $DPDK_LDFLAGS"
 +              V_INCLS="$V_INCLS $DPDK_CFLAGS"
 +              AC_DEFINE(PCAP_SUPPORT_DPDK, 1, [target host supports DPDK])
 +              if test $V_PCAP != dpdk ; then
 +                      MSRC="$MSRC pcap-dpdk.c"
 +              fi
 +      else
 +              if test "$V_PCAP" = dpdk; then
 +                      # User requested "dpdk" capture type but we couldn't
 +                      # find the DPDK API support.
 +                      AC_MSG_ERROR([DPDK support requested with --with-pcap=dpdk, but the DPDK headers weren't found at $dpdk_inc_dir: make sure the DPDK support is installed, specify a different path or paths if necessary, or don't request DPDK support])
 +              fi
 +
 +              if test "$want_dpdk" = yes; then
 +                      # User wanted DPDK support but we couldn't find it.
 +                      AC_MSG_ERROR([DPDK support requested with --with-pcap=dpdk, but the DPDK headers weren't found at $dpdk_inc_dir: make sure the DPDK support is installed, specify a different path or paths if necessary, or don't request DPDK support])
 +              fi
 +      fi
 +fi
 +AC_SUBST(PCAP_SUPPORT_DPDK)
  
  AC_ARG_ENABLE([bluetooth],
  [AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
@@@ -2247,7 -2070,7 +2277,7 @@@ if test "x$enable_bluetooth" != "xno" 
                        # sniffing.
                        #
                        AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
 -                      BT_SRC=pcap-bt-linux.c
 +                      MSRC="$MSRC pcap-bt-linux.c"
                        AC_MSG_NOTICE(Bluetooth sniffing is supported)
                        ac_lbl_bluetooth_available=yes
  
                                            AC_MSG_RESULT(yes)
                                            AC_DEFINE(PCAP_SUPPORT_BT_MONITOR,,
                                              [target host supports Bluetooth Monitor])
 -                                          BT_MONITOR_SRC=pcap-bt-monitor-linux.c
 +                                          MSRC="$MSRC pcap-bt-monitor-linux.c"
                                        ],
                                        [
                                            AC_MSG_RESULT(no)
                ;;
        esac
        AC_SUBST(PCAP_SUPPORT_BT)
 -      AC_SUBST(BT_SRC)
 -      AC_SUBST(BT_MONITOR_SRC)
  fi
  
  AC_ARG_ENABLE([dbus],
@@@ -2375,7 -2200,7 +2405,7 @@@ if test "x$enable_dbus" != "xno"; the
                            [
                                AC_MSG_RESULT([yes])
                                AC_DEFINE(PCAP_SUPPORT_DBUS, 1, [support D-Bus sniffing])
 -                              DBUS_SRC=pcap-dbus.c
 +                              MSRC="$MSRC pcap-dbus.c"
                                V_INCLS="$V_INCLS $DBUS_CFLAGS"
                            ],
                            [
                fi
        fi
        AC_SUBST(PCAP_SUPPORT_DBUS)
 -      AC_SUBST(DBUS_SRC)
  fi
  
  AC_ARG_ENABLE([rdma],
  [AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])],
      [],
 -    [enable_rdmasniff=ifavailable])
 +    [enable_rdma=ifavailable])
  
  if test "xxx_only" = yes; then
        # User requested something-else-only pcap, so they don't
        # want RDMA support.
 -      enable_rdmasniff=no
 +      enable_rdma=no
  fi
  
 -if test "x$enable_rdmasniff" != "xno"; then
 +if test "x$enable_rdma" != "xno"; then
        AC_CHECK_LIB(ibverbs, ibv_get_device_list, [
                AC_CHECK_HEADER(infiniband/verbs.h, [
                        #
                                [
                                        AC_MSG_RESULT([yes])
                                        AC_DEFINE(PCAP_SUPPORT_RDMASNIFF, , [target host supports RDMA sniffing])
 -                                      RDMA_SRC=pcap-rdmasniff.c
 +                                      MSRC="$MSRC pcap-rdmasniff.c"
                                        LIBS="-libverbs $LIBS"
                                ],
                                [
                ])
        ])
        AC_SUBST(PCAP_SUPPORT_RDMASNIFF)
 -      AC_SUBST(RDMA_SRC)
  fi
  
  AC_PROG_INSTALL
diff --combined pcap-int.h
index 4bab336fb752a60ecb2acdc8f8f4261a7a3d83c9,243e7831429148f2a9bbd6fe24439332c34919cc..ec643eba3359d9e16427b1a334627330470e260a
@@@ -126,7 -126,6 +126,7 @@@ typedef int        (*set_datalink_op_t)(pcap_
  typedef int   (*getnonblock_op_t)(pcap_t *);
  typedef int   (*setnonblock_op_t)(pcap_t *, int);
  typedef int   (*stats_op_t)(pcap_t *, struct pcap_stat *);
 +typedef void  (*breakloop_op_t)(pcap_t *);
  #ifdef _WIN32
  typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
  typedef int   (*setbuff_op_t)(pcap_t *, int);
@@@ -265,7 -264,6 +265,7 @@@ struct pcap 
        getnonblock_op_t getnonblock_op;
        setnonblock_op_t setnonblock_op;
        stats_op_t stats_op;
 +      breakloop_op_t breakloop_op;
  
        /*
         * Routine to use as callback for pcap_next()/pcap_next_ex().
@@@ -420,7 -418,6 +420,7 @@@ void       pcap_add_to_pcaps_to_close(pcap_t 
  void  pcap_remove_from_pcaps_to_close(pcap_t *);
  void  pcap_cleanup_live_common(pcap_t *);
  int   pcap_check_activated(pcap_t *);
 +void  pcap_breakloop_common(pcap_t *);
  
  /*
   * Internal interfaces for "pcap_findalldevs()".
@@@ -529,6 -526,13 +529,13 @@@ int      install_bpf_program(pcap_t *, struc
  
  int   pcap_strcasecmp(const char *, const char *);
  
+ /*
+  * Internal interface for pcap_parsesrcstr with the additional bit of
+  * information regarding SSL support (rpcap:// vs rpcaps://)
+  */
+ int pcap_parsesrcstr_ex(const char *source, int *type, char *host, char *port,
+                         char *name, unsigned char *uses_ssl, char *errbuf);
  #ifdef YYDEBUG
  extern int pcap_debug;
  #endif
diff --combined pcap-rpcap.c
index 16dcbf8f02bc5227cc25933d8cd1a0e86207c5ae,7dba6d590c7c592ffc1961b28ffbdee9db56e0f2..6e45c4331aabd94843e77874c09e0863b2bcc7aa
  #include "rpcap-protocol.h"
  #include "pcap-rpcap.h"
  
+ #ifdef HAVE_OPENSSL
+ #include "sslutils.h"
+ #endif
  /*
   * This file contains the pcap module for capturing from a remote machine's
   * interfaces using the RPCAP protocol.
@@@ -83,6 -87,7 +87,7 @@@ struct activehost
  {
        struct sockaddr_storage host;
        SOCKET sockctrl;
+       SSL *ssl;
        uint8 protocol_version;
        struct activehosts *next;
  };
@@@ -97,6 -102,7 +102,7 @@@ static struct activehosts *activeHosts
   * pcap_remoteact_cleanup() for more details.
   */
  static SOCKET sockmain;
+ static SSL *ssl_main;
  
  /*
   * Private data for capturing remotely using the rpcap protocol.
@@@ -111,11 -117,13 +117,13 @@@ struct pcap_rpcap 
  
        SOCKET rmt_sockctrl;            /* socket ID of the socket used for the control connection */
        SOCKET rmt_sockdata;            /* socket ID of the socket used for the data connection */
+       SSL *ctrl_ssl, *data_ssl;       /* optional transport of rmt_sockctrl and rmt_sockdata via TLS */
        int rmt_flags;                  /* we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture() */
        int rmt_capstarted;             /* 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture() */
        char *currentfilter;            /* Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on. */
  
        uint8 protocol_version;         /* negotiated protocol version */
+       uint8 uses_ssl;                         /* User asked for rpcaps scheme */
  
        unsigned int TotNetDrops;       /* keeps the number of packets that have been dropped by the network */
  
@@@ -155,15 -163,15 +163,15 @@@ static void pcap_save_current_filter_rp
  static int pcap_setfilter_rpcap(pcap_t *fp, struct bpf_program *prog);
  static int pcap_setsampling_remote(pcap_t *fp);
  static int pcap_startcapture_remote(pcap_t *fp);
- static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf);
- static int rpcap_recv_msg_header(SOCKET sock, struct rpcap_header *header, char *errbuf);
- static int rpcap_check_msg_ver(SOCKET sock, uint8 expected_ver, struct rpcap_header *header, char *errbuf);
- static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf);
- static int rpcap_process_msg_header(SOCKET sock, uint8 ver, uint8 request_type, struct rpcap_header *header, char *errbuf);
- static int rpcap_recv(SOCKET sock, void *buffer, size_t toread, uint32 *plen, char *errbuf);
- static void rpcap_msg_err(SOCKET sockctrl, uint32 plen, char *remote_errbuf);
- static int rpcap_discard(SOCKET sock, uint32 len, char *errbuf);
- static int rpcap_read_packet_msg(SOCKET sock, pcap_t *p, size_t size);
+ static int rpcap_sendauth(SOCKET sock, SSL *, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf);
+ static int rpcap_recv_msg_header(SOCKET sock, SSL *, struct rpcap_header *header, char *errbuf);
+ static int rpcap_check_msg_ver(SOCKET sock, SSL *, uint8 expected_ver, struct rpcap_header *header, char *errbuf);
+ static int rpcap_check_msg_type(SOCKET sock, SSL *, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf);
+ static int rpcap_process_msg_header(SOCKET sock, SSL *, uint8 ver, uint8 request_type, struct rpcap_header *header, char *errbuf);
+ static int rpcap_recv(SOCKET sock, SSL *, void *buffer, size_t toread, uint32 *plen, char *errbuf);
+ static void rpcap_msg_err(SOCKET sockctrl, SSL *, uint32 plen, char *remote_errbuf);
+ static int rpcap_discard(SOCKET sock, SSL *, uint32 len, char *errbuf);
+ static int rpcap_read_packet_msg(struct pcap_rpcap const *, pcap_t *p, size_t size);
  
  /****************************************************
   *                                                  *
@@@ -376,7 -384,7 +384,7 @@@ static int pcap_read_nocb_remote(pcap_
        struct rpcap_pkthdr *net_pkt_header;    /* header of the packet, from the message */
        u_char *net_pkt_data;                   /* packet data from the message */
        uint32 plen;
-       int retval;                             /* generic return value */
+       int retval = 0;                         /* generic return value */
        int msglen;
  
        /* Structures needed for the select() call */
        tv.tv_sec = p->opt.timeout / 1000;
        tv.tv_usec = (suseconds_t)((p->opt.timeout - tv.tv_sec * 1000) * 1000);
  
-       /* Watch out sockdata to see if it has input */
-       FD_ZERO(&rfds);
+ #ifdef HAVE_OPENSSL
+       /* Check if we still have bytes available in the last decoded TLS record.
+        * If that's the case, we know SSL_read will not block. */
+       retval = pr->data_ssl && SSL_pending(pr->data_ssl) > 0;
+ #endif
+       if (! retval)
+       {
+               /* Watch out sockdata to see if it has input */
+               FD_ZERO(&rfds);
  
-       /*
-        * 'fp->rmt_sockdata' has always to be set before calling the select(),
-        * since it is cleared by the select()
-        */
-       FD_SET(pr->rmt_sockdata, &rfds);
+               /*
+                * 'fp->rmt_sockdata' has always to be set before calling the select(),
+                * since it is cleared by the select()
+                */
+               FD_SET(pr->rmt_sockdata, &rfds);
  
-       retval = select((int) pr->rmt_sockdata + 1, &rfds, NULL, NULL, &tv);
-       if (retval == -1)
-       {
- #ifndef _WIN32
-               if (errno == EINTR)
+               retval = select((int) pr->rmt_sockdata + 1, &rfds, NULL, NULL, &tv);
+               if (retval == -1)
                {
-                       /* Interrupted. */
-                       return 0;
-               }
+ #ifndef _WIN32
+                       if (errno == EINTR)
+                       {
+                               /* Interrupted. */
+                               return 0;
+                       }
  #endif
-               sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE);
-               return -1;
+                       sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE);
+                       return -1;
+               }
        }
  
        /* There is no data waiting, so return '0' */
        if (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
        {
                /* Read the entire message from the network */
-               msglen = sock_recv_dgram(pr->rmt_sockdata, p->buffer,
+               msglen = sock_recv_dgram(pr->rmt_sockdata, pr->data_ssl, p->buffer,
                    p->bufsize, p->errbuf, PCAP_ERRBUF_SIZE);
                if (msglen == -1)
                {
                         * The size we should get is the size of the
                         * packet header.
                         */
-                       status = rpcap_read_packet_msg(pr->rmt_sockdata, p,
-                           sizeof(struct rpcap_header));
+                       status = rpcap_read_packet_msg(pr, p, sizeof(struct rpcap_header));
                        if (status == -1)
                        {
                                /* Network error. */
                            "Server sent us a message larger than the largest expected packet message");
                        return -1;
                }
-               status = rpcap_read_packet_msg(pr->rmt_sockdata, p,
-                   sizeof(struct rpcap_header) + plen);
+               status = rpcap_read_packet_msg(pr, p, sizeof(struct rpcap_header) + plen);
                if (status == -1)
                {
                        /* Network error. */
        /*
         * Did the server specify the version we negotiated?
         */
-       if (rpcap_check_msg_ver(pr->rmt_sockdata, pr->protocol_version,
+       if (rpcap_check_msg_ver(pr->rmt_sockdata, pr->data_ssl, pr->protocol_version,
            header, p->errbuf) == -1)
        {
                return 0;       /* Return 'no packets received' */
@@@ -715,7 -730,7 +730,7 @@@ static void pcap_cleanup_rpcap(pcap_t *
                 * we're closing this pcap_t, and have no place to report
                 * the error.  No reply is sent to this message.
                 */
-               (void)sock_send(pr->rmt_sockctrl, (char *)&header,
+               (void)sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, (char *)&header,
                    sizeof(struct rpcap_header), NULL, 0);
        }
        else
                 * as we're closing this pcap_t, and have no place to
                 * report the error.
                 */
-               if (sock_send(pr->rmt_sockctrl, (char *)&header,
+               if (sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, (char *)&header,
                    sizeof(struct rpcap_header), NULL, 0) == 0)
                {
                        /*
                         * as we're closing this pcap_t, and have no
                         * place to report the error.
                         */
-                       if (rpcap_process_msg_header(pr->rmt_sockctrl,
+                       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->ctrl_ssl,
                            pr->protocol_version, RPCAP_MSG_ENDCAP_REQ,
                            &header, NULL) == 0)
                        {
-                               (void)rpcap_discard(pr->rmt_sockctrl,
+                               (void)rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl,
                                    header.plen, NULL);
                        }
                }
  
        if (pr->rmt_sockdata)
        {
+ #ifdef HAVE_OPENSSL
+               if (pr->data_ssl)
+               {
+                       SSL_free(pr->data_ssl); // Has to be done before the socket is closed
+                       pr->data_ssl = NULL;
+               }
+ #endif
                sock_close(pr->rmt_sockdata, NULL, 0);
                pr->rmt_sockdata = 0;
        }
  
        if ((!active) && (pr->rmt_sockctrl))
+       {
+ #ifdef HAVE_OPENSSL
+               if (pr->ctrl_ssl)
+               {
+                       SSL_free(pr->ctrl_ssl);
+                       pr->ctrl_ssl = NULL;
+               }
+ #endif
                sock_close(pr->rmt_sockctrl, NULL, 0);
+       }
  
        pr->rmt_sockctrl = 0;
+       pr->ctrl_ssl = NULL;
  
        if (pr->currentfilter)
        {
                pr->currentfilter = NULL;
        }
  
 +      pcap_cleanup_live_common(fp);
 +
        /* To avoid inconsistencies in the number of sock_init() */
        sock_cleanup();
  }
@@@ -880,19 -910,19 +912,19 @@@ static struct pcap_stat *rpcap_stats_rp
            RPCAP_MSG_STATS_REQ, 0, 0);
  
        /* Send the PCAP_STATS command */
-       if (sock_send(pr->rmt_sockctrl, (char *)&header,
+       if (sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, (char *)&header,
            sizeof(struct rpcap_header), p->errbuf, PCAP_ERRBUF_SIZE) < 0)
                return NULL;            /* Unrecoverable network error */
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->ctrl_ssl, pr->protocol_version,
            RPCAP_MSG_STATS_REQ, &header, p->errbuf) == -1)
                return NULL;            /* Error */
  
        plen = header.plen;
  
        /* Read the reply body */
-       if (rpcap_recv(pr->rmt_sockctrl, (char *)&netstats,
+       if (rpcap_recv(pr->rmt_sockctrl, pr->ctrl_ssl, (char *)&netstats,
            sizeof(struct rpcap_stats), &plen, p->errbuf) == -1)
                goto error;
  
  #endif /* _WIN32 */
  
        /* Discard the rest of the message. */
-       if (rpcap_discard(pr->rmt_sockctrl, plen, p->errbuf) == -1)
+       if (rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, plen, p->errbuf) == -1)
                goto error_nodiscard;
  
        return ps;
@@@ -920,7 -950,7 +952,7 @@@ error
         * We already reported an error; if this gets an error, just
         * drive on.
         */
-       (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
+       (void)rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, plen, NULL);
  
  error_nodiscard:
        return NULL;
@@@ -1040,6 -1070,10 +1072,10 @@@ static int pcap_startcapture_remote(pca
        int sockbufsize = 0;
        uint32 server_sockbufsize;
  
+       // Take the opportunity to clear pr->data_ssl before any goto error,
+       // as it seems pr->priv is not zeroed after its malloced.
+       pr->data_ssl = NULL;
        /*
         * Let's check if sampling has been required.
         * If so, let's set it first
        if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, &fp->fcode))
                goto error_nodiscard;
  
-       if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+       if (sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, sendbuf, sendbufidx, fp->errbuf,
            PCAP_ERRBUF_SIZE) < 0)
                goto error_nodiscard;
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->ctrl_ssl, pr->protocol_version,
            RPCAP_MSG_STARTCAP_REQ, &header, fp->errbuf) == -1)
                goto error_nodiscard;
  
        plen = header.plen;
  
-       if (rpcap_recv(pr->rmt_sockctrl, (char *)&startcapreply,
+       if (rpcap_recv(pr->rmt_sockctrl, pr->ctrl_ssl, (char *)&startcapreply,
            sizeof(struct rpcap_startcapreply), &plen, fp->errbuf) == -1)
                goto error;
  
        /* Let's save the socket of the data connection */
        pr->rmt_sockdata = sockdata;
  
+ #ifdef HAVE_OPENSSL
+       if (pr->uses_ssl)
+       {
+               pr->data_ssl = ssl_promotion(0, sockdata, fp->errbuf, PCAP_ERRBUF_SIZE);
+               if (! pr->data_ssl) goto error;
+       }
+ #endif
        /*
         * Set the size of the socket buffer for the data socket.
         * It has the same size as the local capture buffer used
        fp->cc = 0;
  
        /* Discard the rest of the message. */
-       if (rpcap_discard(pr->rmt_sockctrl, plen, fp->errbuf) == -1)
+       if (rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, plen, fp->errbuf) == -1)
                goto error_nodiscard;
  
        /*
@@@ -1376,14 -1418,31 +1420,31 @@@ error
         * We already reported an error; if this gets an error, just
         * drive on.
         */
-       (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
+       (void)rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, plen, NULL);
  
  error_nodiscard:
+ #ifdef HAVE_OPENSSL
+       if (pr->data_ssl)
+       {
+               SSL_free(pr->data_ssl);  // Have to be done before the socket is closed
+               pr->data_ssl = NULL;
+       }
+ #endif
        if ((sockdata) && (sockdata != -1))             /* we can be here because sockdata said 'error' */
                sock_close(sockdata, NULL, 0);
  
        if (!active)
+       {
+ #ifdef HAVE_OPENSSL
+               if (pr->ctrl_ssl)
+               {
+                       SSL_free(pr->ctrl_ssl);
+                       pr->ctrl_ssl = NULL;
+               }
+ #endif
                sock_close(pr->rmt_sockctrl, NULL, 0);
+       }
  
        if (addrinfo != NULL)
                freeaddrinfo(addrinfo);
@@@ -1516,19 -1575,19 +1577,19 @@@ static int pcap_updatefilter_remote(pca
        if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, prog))
                return -1;
  
-       if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+       if (sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, sendbuf, sendbufidx, fp->errbuf,
            PCAP_ERRBUF_SIZE) < 0)
                return -1;
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->ctrl_ssl, pr->protocol_version,
            RPCAP_MSG_UPDATEFILTER_REQ, &header, fp->errbuf) == -1)
                return -1;
  
        /*
         * It shouldn't have any contents; discard it if it does.
         */
-       if (rpcap_discard(pr->rmt_sockctrl, header.plen, fp->errbuf) == -1)
+       if (rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, header.plen, fp->errbuf) == -1)
                return -1;
  
        return 0;
@@@ -1761,19 -1820,19 +1822,19 @@@ static int pcap_setsampling_remote(pcap
        sampling_pars->method = (uint8)fp->rmt_samp.method;
        sampling_pars->value = (uint16)htonl(fp->rmt_samp.value);
  
-       if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+       if (sock_send(pr->rmt_sockctrl, pr->ctrl_ssl, sendbuf, sendbufidx, fp->errbuf,
            PCAP_ERRBUF_SIZE) < 0)
                return -1;
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+       if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->ctrl_ssl, pr->protocol_version,
            RPCAP_MSG_SETSAMPLING_REQ, &header, fp->errbuf) == -1)
                return -1;
  
        /*
         * It shouldn't have any contents; discard it if it does.
         */
-       if (rpcap_discard(pr->rmt_sockctrl, header.plen, fp->errbuf) == -1)
+       if (rpcap_discard(pr->rmt_sockctrl, pr->ctrl_ssl, header.plen, fp->errbuf) == -1)
                return -1;
  
        return 0;
   * \return '0' if everything is fine, '-1' for an error.  For errors,
   * an error message string is returned in the 'errbuf' variable.
   */
- static int rpcap_doauth(SOCKET sockctrl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
+ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
  {
        int status;
  
         * First try with the maximum version number we support.
         */
        *ver = RPCAP_MAX_VERSION;
-       status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
+       status = rpcap_sendauth(sockctrl, ssl, ver, auth, errbuf);
        if (status == 0)
        {
                //
         * support that version.  *ver has been set to that version; try
         * authenticating again with that version.
         */
-       status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
+       status = rpcap_sendauth(sockctrl, ssl, ver, auth, errbuf);
        if (status == 0)
        {
                //
   * support, or '-1' for other errors.  For errors, an error message string
   * is returned in the 'errbuf' variable.
   */
- static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
+ static int rpcap_sendauth(SOCKET sock, SSL *ssl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
  {
        char sendbuf[RPCAP_NETBUF_SIZE];        /* temporary buffer in which data that has to be sent is buffered */
        int sendbufidx = 0;                     /* index which keeps the number of bytes currently buffered */
                rpauth->slen2 = htons(rpauth->slen2);
        }
  
-       if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
+       if (sock_send(sock, ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
                return -1;
  
        /* Receive the reply */
-       if (rpcap_recv_msg_header(sock, &header, errbuf) == -1)
+       if (rpcap_recv_msg_header(sock, ssl, &header, errbuf) == -1)
                return -1;
  
-       if (rpcap_check_msg_type(sock, RPCAP_MSG_AUTH_REQ, &header,
+       if (rpcap_check_msg_type(sock, ssl, RPCAP_MSG_AUTH_REQ, &header,
            &errcode, errbuf) == -1)
        {
                /* Error message - or something else, which is a protocol error. */
         *
         * Discard the rest of it.
         */
-       if (rpcap_discard(sock, header.plen, errbuf) == -1)
+       if (rpcap_discard(sock, ssl, header.plen, errbuf) == -1)
                return -1;
  
        return 0;
@@@ -2110,6 -2169,7 +2171,7 @@@ pcap_t *pcap_open_rpcap(const char *sou
        struct activehosts *activeconn;         /* active connection, if there is one */
        int error;                              /* '1' if rpcap_remoteact_getsock returned an error */
        SOCKET sockctrl;
+       SSL *ssl = NULL;
        uint8 protocol_version;                 /* negotiated protocol version */
        int active;
        uint32 plen;
        pr = fp->priv;
        pr->rmt_flags = flags;
  
+       // Also, SSL is not supported with UDP at the moment, so if the user
+       // asks for both we'd better bail out now:
+       if (pr->uses_ssl && (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
+       {
+               pcap_close(fp);
+               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                   "SSL not supported with UDP forward of remote packets");
+               return NULL;
+       }
        /*
         * determine the type of the source (NULL, file, local, remote)
         * You must have a valid source string even if we're in active mode, because otherwise
         * the call to the following function will fail.
         */
-       if (pcap_parsesrcstr(fp->opt.device, &retval, host, ctrlport, iface, errbuf) == -1)
+       if (pcap_parsesrcstr_ex(fp->opt.device, &retval, host, ctrlport, iface, &pr->uses_ssl, errbuf) == -1)
        {
                pcap_close(fp);
                return NULL;
        activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
        if (activeconn != NULL)
        {
+               active = 1;
                sockctrl = activeconn->sockctrl;
+               ssl = activeconn->ssl;
                protocol_version = activeconn->protocol_version;
-               active = 1;
        }
        else
        {
+               active = 0;  // Must be set before jumping to error
                struct addrinfo hints;                  /* temp, needed to open a socket connection */
                struct addrinfo *addrinfo;              /* temp, needed to open a socket connection */
  
                /* addrinfo is no longer used */
                freeaddrinfo(addrinfo);
  
-               if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+               if (pr->uses_ssl)
                {
-                       sock_close(sockctrl, NULL, 0);
+ #ifdef HAVE_OPENSSL
+                       ssl = ssl_promotion(0, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
+                       if (! ssl)
+                       {
+                               pcap_close(fp);
+                               return NULL;
+                       }
+ #else
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "No TLS support");
                        pcap_close(fp);
                        return NULL;
+ #endif
                }
-               active = 0;
+               if (rpcap_doauth(sockctrl, ssl, &protocol_version, auth, errbuf) == -1)
+                       goto error_nodiscard;
        }
  
+       /* All good so far, save the ssl handler */
+       ssl_main = ssl;
        /*
         * Now it's time to start playing with the RPCAP protocol
         * RPCAP open command: create the request message
                RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE))
                goto error_nodiscard;
  
-       if (sock_send(sockctrl, sendbuf, sendbufidx, errbuf,
+       if (sock_send(sockctrl, ssl, sendbuf, sendbufidx, errbuf,
            PCAP_ERRBUF_SIZE) < 0)
                goto error_nodiscard;
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(sockctrl, protocol_version,
+       if (rpcap_process_msg_header(sockctrl, ssl, protocol_version,
            RPCAP_MSG_OPEN_REQ, &header, errbuf) == -1)
                goto error_nodiscard;
        plen = header.plen;
  
        /* Read the reply body */
-       if (rpcap_recv(sockctrl, (char *)&openreply,
+       if (rpcap_recv(sockctrl, ssl, (char *)&openreply,
            sizeof(struct rpcap_openreply), &plen, errbuf) == -1)
                goto error;
  
        /* Discard the rest of the message, if there is any. */
-       if (rpcap_discard(sockctrl, plen, errbuf) == -1)
+       if (rpcap_discard(sockctrl, ssl, plen, errbuf) == -1)
                goto error_nodiscard;
  
        /* Set proper fields into the pcap_t struct */
        fp->linktype = ntohl(openreply.linktype);
        pr->rmt_sockctrl = sockctrl;
+       pr->ctrl_ssl = ssl;
        pr->protocol_version = protocol_version;
        pr->rmt_clientside = 1;
  
@@@ -2316,11 -2403,16 +2405,16 @@@ error
         * We already reported an error; if this gets an error, just
         * drive on.
         */
-       (void)rpcap_discard(sockctrl, plen, NULL);
+       (void)rpcap_discard(sockctrl, pr->ctrl_ssl, plen, NULL);
  
  error_nodiscard:
        if (!active)
+       {
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);  // Have to be done before the socket is closed
+ #endif
                sock_close(sockctrl, NULL, 0);
+       }
  
        pcap_close(fp);
        return NULL;
@@@ -2342,12 -2434,13 +2436,13 @@@ freeaddr(struct pcap_addr *addr
  }
  
  int
 -pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
 +pcap_findalldevs_ex_remote(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
  {
        struct activehosts *activeconn; /* active connection, if there is one */
        int error;                      /* '1' if rpcap_remoteact_getsock returned an error */
        uint8 protocol_version;         /* protocol version */
        SOCKET sockctrl;                /* socket descriptor of the control connection */
+       SSL *ssl = NULL;                /* optional SSL handler for sockctrl */
        uint32 plen;
        struct rpcap_header header;     /* structure that keeps the general header of the rpcap protocol */
        int i, j;               /* temp variables */
        int active;                     /* 'true' if we the other end-party is in active mode */
        int type;
        char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE];
+       uint8 uses_ssl;
        char tmpstring[PCAP_BUF_SIZE + 1];              /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
        pcap_if_t *lastdev;     /* Last device in the pcap_if_t list */
        pcap_if_t *dev;         /* Device we're adding to the pcap_if_t list */
        lastdev = NULL;
  
        /* Retrieve the needed data for getting adapter list */
-       if (pcap_parsesrcstr(source, &type, host, port, NULL, errbuf) == -1)
+       if (pcap_parsesrcstr_ex(source, &type, host, port, NULL, &uses_ssl, errbuf) == -1)
                return -1;
  
        /* Warning: this call can be the first one called by the user. */
        activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
        if (activeconn != NULL)
        {
+               active = 1;
                sockctrl = activeconn->sockctrl;
+               ssl = activeconn->ssl;
                protocol_version = activeconn->protocol_version;
-               active = 1;
        }
        else
        {
+               active = 0;
                struct addrinfo hints;          /* temp variable needed to resolve hostnames into to socket representation */
                struct addrinfo *addrinfo;      /* temp variable needed to resolve hostnames into to socket representation */
  
                freeaddrinfo(addrinfo);
                addrinfo = NULL;
  
-               if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+               if (uses_ssl)
+               {
+ #ifdef HAVE_OPENSSL
+                       ssl = ssl_promotion(0, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
+                       if (! ssl)
+                       {
+                               sock_close(sockctrl, NULL, 0);
+                               return -1;
+                       }
+ #else
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "No TLS support");
+                       sock_close(sockctrl, NULL, 0);;
+                       return -1;
+ #endif
+               }
+               if (rpcap_doauth(sockctrl, ssl, &protocol_version, auth, errbuf) == -1)
                {
+ #ifdef HAVE_OPENSSL
+                       if (ssl) SSL_free(ssl); // Must be done before the socket is closed
+ #endif
                        sock_close(sockctrl, NULL, 0);
                        return -1;
                }
-               active = 0;
        }
  
        /* RPCAP findalldevs command */
        rpcap_createhdr(&header, protocol_version, RPCAP_MSG_FINDALLIF_REQ,
            0, 0);
  
-       if (sock_send(sockctrl, (char *)&header, sizeof(struct rpcap_header),
+       if (sock_send(sockctrl, ssl, (char *)&header, sizeof(struct rpcap_header),
            errbuf, PCAP_ERRBUF_SIZE) < 0)
                goto error_nodiscard;
  
        /* Receive and process the reply message header. */
-       if (rpcap_process_msg_header(sockctrl, protocol_version,
+       if (rpcap_process_msg_header(sockctrl, ssl, protocol_version,
            RPCAP_MSG_FINDALLIF_REQ, &header, errbuf) == -1)
                goto error_nodiscard;
  
                tmpstring2[PCAP_BUF_SIZE] = 0;
  
                /* receive the findalldevs structure from remote host */
-               if (rpcap_recv(sockctrl, (char *)&findalldevs_if,
+               if (rpcap_recv(sockctrl, ssl, (char *)&findalldevs_if,
                    sizeof(struct rpcap_findalldevs_if), &plen, errbuf) == -1)
                        goto error;
  
                        }
  
                        /* Retrieve adapter name */
-                       if (rpcap_recv(sockctrl, tmpstring,
+                       if (rpcap_recv(sockctrl, ssl, tmpstring,
                            findalldevs_if.namelen, &plen, errbuf) == -1)
                                goto error;
  
                        }
  
                        /* Copy the new device name into the correct memory location */
 -                      strlcpy(dev->name, tmpstring2, stringlen + 1);
 +                      pcap_strlcpy(dev->name, tmpstring2, stringlen + 1);
                }
  
                if (findalldevs_if.desclen)
                        }
  
                        /* Retrieve adapter description */
-                       if (rpcap_recv(sockctrl, tmpstring,
+                       if (rpcap_recv(sockctrl, ssl, tmpstring,
                            findalldevs_if.desclen, &plen, errbuf) == -1)
                                goto error;
  
                        }
  
                        /* Copy the new device description into the correct memory location */
 -                      strlcpy(dev->description, tmpstring2, stringlen + 1);
 +                      pcap_strlcpy(dev->description, tmpstring2, stringlen + 1);
                }
  
                dev->flags = ntohl(findalldevs_if.flags);
                        struct rpcap_findalldevs_ifaddr ifaddr;
  
                        /* Retrieve the interface addresses */
-                       if (rpcap_recv(sockctrl, (char *)&ifaddr,
+                       if (rpcap_recv(sockctrl, ssl, (char *)&ifaddr,
                            sizeof(struct rpcap_findalldevs_ifaddr),
                            &plen, errbuf) == -1)
                                goto error;
        }
  
        /* Discard the rest of the message. */
-       if (rpcap_discard(sockctrl, plen, errbuf) == 1)
+       if (rpcap_discard(sockctrl, ssl, plen, errbuf) == 1)
                goto error_nodiscard;
  
        /* Control connection has to be closed only in case the remote machine is in passive mode */
        if (!active)
        {
                /* DO not send RPCAP_CLOSE, since we did not open a pcap_t; no need to free resources */
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl); // Has to be done before the socket is closed
+ #endif
                if (sock_close(sockctrl, errbuf, PCAP_ERRBUF_SIZE))
                        return -1;
        }
@@@ -2679,12 -2796,17 +2798,17 @@@ error
         *
         * Checks if all the data has been read; if not, discard the data in excess
         */
-       (void) rpcap_discard(sockctrl, plen, NULL);
+       (void) rpcap_discard(sockctrl, ssl, plen, NULL);
  
  error_nodiscard:
        /* Control connection has to be closed only in case the remote machine is in passive mode */
        if (!active)
+       {
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl); // Has to be done before the socket is closed
+ #endif
                sock_close(sockctrl, NULL, 0);
+       }
  
        /* To avoid inconsistencies in the number of sock_init() */
        sock_cleanup();
   * to implement; we provide some APIs for it that work only with rpcap.
   */
  
- SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)
+ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, int uses_ssl, char *errbuf)
  {
        /* socket-related variables */
        struct addrinfo hints;                  /* temporary struct to keep settings needed to open the new socket */
        struct sockaddr_storage from;   /* generic sockaddr_storage variable */
        socklen_t fromlen;                              /* keeps the length of the sockaddr_storage variable */
        SOCKET sockctrl;                                /* keeps the main socket identifier */
+       SSL *ssl = NULL;                                /* Optional SSL handler for sockctrl */
        uint8 protocol_version;                 /* negotiated protocol version */
        struct activehosts *temp, *prev;        /* temp var needed to scan he host list chain */
  
                return (SOCKET)-2;
        }
  
+       /* Promote to SSL early before any error message may be sent */
+       if (uses_ssl)
+       {
+ #ifdef HAVE_OPENSSL
+               ssl = ssl_promotion(0, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
+               if (! ssl)
+               {
+                       sock_close(sockctrl, NULL, 0);
+                       return (SOCKET)-1;
+               }
+ #else
+               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "No TLS support");
+               sock_close(sockctrl, NULL, 0);
+               return (SOCKET)-1;
+ #endif
+       }
        /* Get the numeric for of the name of the connecting host */
        if (getnameinfo((struct sockaddr *) &from, fromlen, connectinghost, RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST))
        {
                sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE);
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);
+ #endif
                sock_close(sockctrl, NULL, 0);
                return (SOCKET)-1;
        }
        /* checks if the connecting host is among the ones allowed */
        if (sock_check_hostlist((char *)hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
        {
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);
+ #endif
                sock_close(sockctrl, NULL, 0);
                return (SOCKET)-1;
        }
        /*
         * Send authentication to the remote machine.
         */
-       if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+       if (rpcap_doauth(sockctrl, ssl, &protocol_version, auth, errbuf) == -1)
        {
                /* Unrecoverable error. */
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);
+ #endif
                sock_close(sockctrl, NULL, 0);
                return (SOCKET)-3;
        }
        {
                pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
                    errno, "malloc() failed");
-               rpcap_senderror(sockctrl, protocol_version, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+               rpcap_senderror(sockctrl, ssl, protocol_version, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);
+ #endif
                sock_close(sockctrl, NULL, 0);
                return (SOCKET)-1;
        }
  
        memcpy(&temp->host, &from, fromlen);
        temp->sockctrl = sockctrl;
+       temp->ssl = ssl;
        temp->protocol_version = protocol_version;
        temp->next = NULL;
  
@@@ -2883,7 -3036,7 +3038,7 @@@ int pcap_remoteact_close(const char *ho
                                 * Don't check for errors, since we're
                                 * just cleaning up.
                                 */
-                               if (sock_send(temp->sockctrl,
+                               if (sock_send(temp->sockctrl, temp->ssl,
                                    (char *)&header,
                                    sizeof(struct rpcap_header), errbuf,
                                    PCAP_ERRBUF_SIZE) < 0)
                                         * Let that error be the one we
                                         * report.
                                         */
+ #ifdef HAVE_OPENSSL
+                                       if (temp->ssl) SSL_free(temp->ssl);
+ #endif
                                        (void)sock_close(temp->sockctrl, NULL,
                                           0);
                                        status = -1;
                                }
                                else
                                {
+ #ifdef HAVE_OPENSSL
+                                       if (temp->ssl) SSL_free(temp->ssl);
+ #endif
                                        if (sock_close(temp->sockctrl, errbuf,
                                           PCAP_ERRBUF_SIZE) == -1)
                                                status = -1;
@@@ -2949,6 -3108,13 +3110,13 @@@ void pcap_remoteact_cleanup(void
                sock_cleanup();
        }
  
+ #     ifdef HAVE_OPENSSL
+       if (ssl_main)
+       {
+               SSL_free(ssl_main);
+               ssl_main = NULL;
+       }
+ #     endif
  }
  
  int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
                        return -1;
                }
  
 -              strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
 +              pcap_strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
                hostlist[len - 1] = sep;
                hostlist[len] = 0;
  
  /*
   * Receive the header of a message.
   */
- static int rpcap_recv_msg_header(SOCKET sock, struct rpcap_header *header, char *errbuf)
+ static int rpcap_recv_msg_header(SOCKET sock, SSL *ssl, struct rpcap_header *header, char *errbuf)
  {
        int nrecv;
  
-       nrecv = sock_recv(sock, (char *) header, sizeof(struct rpcap_header),
+       nrecv = sock_recv(sock, ssl, (char *) header, sizeof(struct rpcap_header),
            SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
            PCAP_ERRBUF_SIZE);
        if (nrecv == -1)
   * Make sure the protocol version of a received message is what we were
   * expecting.
   */
- static int rpcap_check_msg_ver(SOCKET sock, uint8 expected_ver, struct rpcap_header *header, char *errbuf)
+ static int rpcap_check_msg_ver(SOCKET sock, SSL *ssl, uint8 expected_ver, struct rpcap_header *header, char *errbuf)
  {
        /*
         * Did the server specify the version we negotiated?
                /*
                 * Discard the rest of the message.
                 */
-               if (rpcap_discard(sock, header->plen, errbuf) == -1)
+               if (rpcap_discard(sock, ssl, header->plen, errbuf) == -1)
                        return -1;
  
                /*
   * Check the message type of a received message, which should either be
   * the expected message type or RPCAP_MSG_ERROR.
   */
- static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf)
+ static int rpcap_check_msg_type(SOCKET sock, SSL *ssl, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf)
  {
        const char *request_type_string;
        const char *msg_type_string;
                 * Hand that error back to our caller.
                 */
                *errcode = ntohs(header->value);
-               rpcap_msg_err(sock, header->plen, errbuf);
+               rpcap_msg_err(sock, ssl, header->plen, errbuf);
                return -1;
        }
  
                /*
                 * Discard the rest of the message.
                 */
-               if (rpcap_discard(sock, header->plen, errbuf) == -1)
+               if (rpcap_discard(sock, ssl, header->plen, errbuf) == -1)
                        return -1;
  
                /*
  /*
   * Receive and process the header of a message.
   */
- static int rpcap_process_msg_header(SOCKET sock, uint8 expected_ver, uint8 request_type, struct rpcap_header *header, char *errbuf)
+ static int rpcap_process_msg_header(SOCKET sock, SSL *ssl, uint8 expected_ver, uint8 request_type, struct rpcap_header *header, char *errbuf)
  {
        uint16 errcode;
  
-       if (rpcap_recv_msg_header(sock, header, errbuf) == -1)
+       if (rpcap_recv_msg_header(sock, ssl, header, errbuf) == -1)
        {
                /* Network error. */
                return -1;
        /*
         * Did the server specify the version we negotiated?
         */
-       if (rpcap_check_msg_ver(sock, expected_ver, header, errbuf) == -1)
+       if (rpcap_check_msg_ver(sock, ssl, expected_ver, header, errbuf) == -1)
                return -1;
  
        /*
         * Check the message type.
         */
-       return rpcap_check_msg_type(sock, request_type, header,
+       return rpcap_check_msg_type(sock, ssl, request_type, header,
            &errcode, errbuf);
  }
  
   * Returns 0 on success, logs a message and returns -1 on a network
   * error.
   */
- static int rpcap_recv(SOCKET sock, void *buffer, size_t toread, uint32 *plen, char *errbuf)
+ static int rpcap_recv(SOCKET sock, SSL *ssl, void *buffer, size_t toread, uint32 *plen, char *errbuf)
  {
        int nread;
  
                pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
                return -1;
        }
-       nread = sock_recv(sock, buffer, toread,
+       nread = sock_recv(sock, ssl, buffer, toread,
            SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
        if (nread == -1)
        {
  /*
   * This handles the RPCAP_MSG_ERROR message.
   */
- static void rpcap_msg_err(SOCKET sockctrl, uint32 plen, char *remote_errbuf)
+ static void rpcap_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen, char *remote_errbuf)
  {
        char errbuf[PCAP_ERRBUF_SIZE];
  
                 * Message is too long; just read as much of it as we
                 * can into the buffer provided, and discard the rest.
                 */
-               if (sock_recv(sockctrl, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
+               if (sock_recv(sockctrl, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
                    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
                    PCAP_ERRBUF_SIZE) == -1)
                {
                /*
                 * Throw away the rest.
                 */
-               (void)rpcap_discard(sockctrl, plen - (PCAP_ERRBUF_SIZE - 1), remote_errbuf);
+               (void)rpcap_discard(sockctrl, ssl, plen - (PCAP_ERRBUF_SIZE - 1), remote_errbuf);
        }
        else if (plen == 0)
        {
        }
        else
        {
-               if (sock_recv(sockctrl, remote_errbuf, plen,
+               if (sock_recv(sockctrl, ssl, remote_errbuf, plen,
                    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
                    PCAP_ERRBUF_SIZE) == -1)
                {
   * Returns 0 on success, logs a message and returns -1 on a network
   * error.
   */
- static int rpcap_discard(SOCKET sock, uint32 len, char *errbuf)
+ static int rpcap_discard(SOCKET sock, SSL *ssl, uint32 len, char *errbuf)
  {
        if (len != 0)
        {
-               if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
+               if (sock_discard(sock, ssl, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
                {
                        // Network error.
                        return -1;
   * Read bytes into the pcap_t's buffer until we have the specified
   * number of bytes read or we get an error or interrupt indication.
   */
- static int rpcap_read_packet_msg(SOCKET sock, pcap_t *p, size_t size)
+ static int rpcap_read_packet_msg(struct pcap_rpcap const *rp, pcap_t *p, size_t size)
  {
        u_char *bp;
        int cc;
                 * We haven't read all of the packet header yet.
                 * Read what remains, which could be all of it.
                 */
-               bytes_read = sock_recv(sock, bp, size - cc,
+               bytes_read = sock_recv(rp->rmt_sockdata, rp->data_ssl, bp, size - cc,
                    SOCK_RECEIVEALL_NO|SOCK_EOF_IS_ERROR, p->errbuf,
                    PCAP_ERRBUF_SIZE);
                if (bytes_read == -1)
                {
                        /*
diff --combined pcap.c
index f053811b80cd90e19096f24436844fbd22c548ae,c4aba74bb3928e325d72c83f53f605b229bdd79b..6fe8e16aabce9047a8c1e0cfddb009fa84084c71
--- 1/pcap.c
--- 2/pcap.c
+++ b/pcap.c
@@@ -120,10 -120,6 +120,10 @@@ struct rtentry;          /* declarations in <ne
  #include "pcap-rdmasniff.h"
  #endif
  
 +#ifdef PCAP_SUPPORT_DPDK
 +#include "pcap-dpdk.h"
 +#endif
 +
  #ifdef _WIN32
  /*
   * DllMain(), required when built as a Windows DLL.
@@@ -450,9 -446,6 +450,9 @@@ static struct capture_source_type 
  #endif
  #ifdef PCAP_SUPPORT_RDMASNIFF
        { rdmasniff_findalldevs, rdmasniff_create },
 +#endif
 +#ifdef PCAP_SUPPORT_DPDK
 +      { pcap_dpdk_findalldevs, pcap_dpdk_create },
  #endif
        { NULL, NULL }
  };
@@@ -662,7 -655,7 +662,7 @@@ get_if_description(const char *name
         * Get the description for the interface.
         */
        memset(&ifrdesc, 0, sizeof ifrdesc);
 -      strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
 +      pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
        s = socket(AF_INET, SOCK_DGRAM, 0);
        if (s >= 0) {
  #ifdef __FreeBSD__
@@@ -1295,14 -1288,14 +1295,14 @@@ pcap_lookupdev(char *errbuf
                 * on the list, there aren't any non-loopback devices,
                 * so why not just supply it as the default device?
                 */
 -              (void)strlcpy(errbuf, "no suitable device found",
 +              (void)pcap_strlcpy(errbuf, "no suitable device found",
                    PCAP_ERRBUF_SIZE);
                ret = NULL;
        } else {
                /*
                 * Return the name of the first device on the list.
                 */
 -              (void)strlcpy(device, alldevs->name, sizeof(device));
 +              (void)pcap_strlcpy(device, alldevs->name, sizeof(device));
                ret = device;
        }
  
@@@ -1352,9 -1345,6 +1352,9 @@@ pcap_lookupnet(const char *device, bpf_
  #ifdef PCAP_SUPPORT_NETMAP
            || strncmp(device, "netmap:", 7) == 0
            || strncmp(device, "vale", 4) == 0
 +#endif
 +#ifdef PCAP_SUPPORT_DPDK
 +          || strncmp(device, "dpdk:", 5) == 0
  #endif
            ) {
                *netp = *maskp = 0;
        /* XXX Work around Linux kernel bug */
        ifr.ifr_addr.sa_family = AF_INET;
  #endif
 -      (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
 +      (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
                if (errno == EADDRNOTAVAIL) {
                        (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
        /* XXX Work around Linux kernel bug */
        ifr.ifr_addr.sa_family = AF_INET;
  #endif
 -      (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
 +      (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
                pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
                    errno, "SIOCGIFNETMASK: %s", device);
@@@ -1599,7 -1589,8 +1599,8 @@@ pcap_parse_source(const char *source, c
         *
         * XXX - %-escaping?
         */
-       if (pcap_strcasecmp(scheme, "rpcap") == 0 &&
+       if ((pcap_strcasecmp(scheme, "rpcap") == 0 ||
+           pcap_strcasecmp(scheme, "rpcaps") == 0) &&
            strchr(colonp + 3, '/') == NULL) {
                /*
                 * Local device.
@@@ -1811,9 -1802,9 +1812,9 @@@ pcap_createsrcstr(char *source, int typ
        switch (type) {
  
        case PCAP_SRC_FILE:
 -              strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
 +              pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
                if (name != NULL && *name != '\0') {
 -                      strlcat(source, name, PCAP_BUF_SIZE);
 +                      pcap_strlcat(source, name, PCAP_BUF_SIZE);
                        return (0);
                } else {
                        pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
                }
  
        case PCAP_SRC_IFREMOTE:
 -              strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
 +              pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
                if (host != NULL && *host != '\0') {
                        if (strchr(host, ':') != NULL) {
                                /*
                                 * probably an IPv6 address, and needs to
                                 * be included in square brackets.
                                 */
 -                              strlcat(source, "[", PCAP_BUF_SIZE);
 -                              strlcat(source, host, PCAP_BUF_SIZE);
 -                              strlcat(source, "]", PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, "[", PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, host, PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, "]", PCAP_BUF_SIZE);
                        } else
 -                              strlcat(source, host, PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, host, PCAP_BUF_SIZE);
  
                        if (port != NULL && *port != '\0') {
 -                              strlcat(source, ":", PCAP_BUF_SIZE);
 -                              strlcat(source, port, PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, ":", PCAP_BUF_SIZE);
 +                              pcap_strlcat(source, port, PCAP_BUF_SIZE);
                        }
  
 -                      strlcat(source, "/", PCAP_BUF_SIZE);
 +                      pcap_strlcat(source, "/", PCAP_BUF_SIZE);
                } else {
                        pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
                            "The host name cannot be NULL.");
                }
  
                if (name != NULL && *name != '\0')
 -                      strlcat(source, name, PCAP_BUF_SIZE);
 +                      pcap_strlcat(source, name, PCAP_BUF_SIZE);
  
                return (0);
  
        case PCAP_SRC_IFLOCAL:
 -              strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
 +              pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
  
                if (name != NULL && *name != '\0')
 -                      strlcat(source, name, PCAP_BUF_SIZE);
 +                      pcap_strlcat(source, name, PCAP_BUF_SIZE);
  
                return (0);
  
  }
  
  int
- pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
-     char *name, char *errbuf)
+ pcap_parsesrcstr_ex(const char *source, int *type, char *host, char *port,
+     char *name, unsigned char *uses_ssl, char *errbuf)
  {
        char *scheme, *tmpuserinfo, *tmphost, *tmpport, *tmppath;
  
                *port = '\0';
        if (name)
                *name = '\0';
+       if (uses_ssl)
+               *uses_ssl = 0;
  
        /* Parse the source string */
        if (pcap_parse_source(source, &scheme, &tmpuserinfo, &tmphost,
                 * Local device.
                 */
                if (name && tmppath)
 -                      strlcpy(name, tmppath, PCAP_BUF_SIZE);
 +                      pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
                if (type)
                        *type = PCAP_SRC_IFLOCAL;
                free(tmppath);
                return (0);
        }
  
-       if (strcmp(scheme, "rpcap") == 0) {
+       int is_rpcap = 0;
+       if (strcmp(scheme, "rpcaps") == 0) {
+               is_rpcap = 1;
+               if (uses_ssl) *uses_ssl = 1;
+       } else if (strcmp(scheme, "rpcap") == 0) {
+               is_rpcap = 1;
+       }
+       if (is_rpcap) {
                /*
-                * rpcap://
+                * rpcap[s]://
                 *
                 * pcap_parse_source() has already handled the case of
-                * rpcap://device
+                * rpcap[s]://device
                 */
                if (host && tmphost) {
                        if (tmpuserinfo)
                                pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
                                    tmpuserinfo, tmphost);
                        else
 -                              strlcpy(host, tmphost, PCAP_BUF_SIZE);
 +                              pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
                }
                if (port && tmpport)
 -                      strlcpy(port, tmpport, PCAP_BUF_SIZE);
 +                      pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
                if (name && tmppath)
 -                      strlcpy(name, tmppath, PCAP_BUF_SIZE);
 +                      pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
                if (type)
                        *type = PCAP_SRC_IFREMOTE;
                free(tmppath);
                 * file://
                 */
                if (name && tmppath)
 -                      strlcpy(name, tmppath, PCAP_BUF_SIZE);
 +                      pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
                if (type)
                        *type = PCAP_SRC_FILE;
                free(tmppath);
         * as a local device.
         */
        if (name)
 -              strlcpy(name, source, PCAP_BUF_SIZE);
 +              pcap_strlcpy(name, source, PCAP_BUF_SIZE);
        if (type)
                *type = PCAP_SRC_IFLOCAL;
        free(tmppath);
        free(scheme);
        return (0);
  }
+ int
+ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
+     char *name, char *errbuf)
+ {
+   return pcap_parsesrcstr_ex(source, type, host, port, name, NULL, errbuf);
+ }
  #endif
  
  pcap_t *
@@@ -2117,13 -2125,6 +2135,13 @@@ initialize_ops(pcap_t *p
         * be used for pcap_next()/pcap_next_ex().
         */
        p->oneshot_callback = pcap_oneshot;
 +
 +    /*
 +     * Default breakloop operation - implementations can override
 +     * this, but should call pcap_breakloop_common() before doing
 +     * their own logic.
 +     */
 +    p->breakloop_op = pcap_breakloop_common;
  }
  
  static pcap_t *
@@@ -2614,7 -2615,7 +2632,7 @@@ pcap_loop(pcap_t *p, int cnt, pcap_hand
  void
  pcap_breakloop(pcap_t *p)
  {
 -      p->break_loop = 1;
 +      p->breakloop_op(p);
  }
  
  int
@@@ -2982,8 -2983,6 +3000,8 @@@ static struct dlt_choice dlt_choices[] 
        DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
        DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
        DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
 +      DLT_CHOICE(OPENVIZSLA, "OpenVizsla USB"),
 +      DLT_CHOICE(EBHSCR, "Elektrobit High Speed Capture and Replay (EBHSCR)"),
        DLT_CHOICE_SENTINEL
  };
  
@@@ -3175,7 -3174,7 +3193,7 @@@ pcap_getnonblock(pcap_t *p, char *errbu
                 * We copy the error message to errbuf, so callers
                 * can find it in either place.
                 */
 -              strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
 +              pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
        }
        return (ret);
  }
@@@ -3219,7 -3218,7 +3237,7 @@@ pcap_setnonblock(pcap_t *p, int nonbloc
                 * We copy the error message to errbuf, so callers
                 * can find it in either place.
                 */
 -              strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
 +              pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
        }
        return (ret);
  }
@@@ -3355,7 -3354,7 +3373,7 @@@ pcap_strerror(int errnum
        errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
  
        if (err != 0) /* err = 0 if successful */
 -              strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
 +              pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
        return (errbuf);
  #else
        return (strerror(errnum));
@@@ -3577,7 -3576,7 +3595,7 @@@ pcap_do_addexit(pcap_t *p
                        /*
                         * "atexit()" failed; let our caller know.
                         */
 -                      strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
 +                      pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
                        return (0);
                }
                did_atexit = 1;
@@@ -3619,13 -3618,6 +3637,13 @@@ pcap_remove_from_pcaps_to_close(pcap_t 
        }
  }
  
 +void
 +pcap_breakloop_common(pcap_t *p)
 +{
 +      p->break_loop = 1;
 +}
 +
 +
  void
  pcap_cleanup_live_common(pcap_t *p)
  {
@@@ -3697,7 -3689,7 +3715,7 @@@ pcap_inject(pcap_t *p, const void *buf
  
        if (size == 0) {
                pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
 -                  errno, "The number of bytes to be injected must not be zero", INT_MAX);
 +                  errno, "The number of bytes to be injected must not be zero");
                return (PCAP_ERROR);
        }
  
diff --combined pcap/pcap.h
index 8b5ecba563020721b88796cdc1a2d6bce3325614,6b6437fa20d25af527fa62d31d8c3dc7f2493879..571c88c0104650be6549ff1f3d761d45513e642a
@@@ -631,6 -631,9 +631,9 @@@ PCAP_API const char *pcap_lib_version(v
   * - rpcap:// [lists all local adapters]
   * - rpcap://host:port/ [lists the devices available on a remote host]
   *
+  * In all the above, "rpcaps://" can be substituted for "rpcap://" to enable
+  * SSL (if it has been compiled in).
+  *
   * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since
   * IPv6 is fully supported, these are the allowed formats:
   *
@@@ -845,8 -848,8 +848,8 @@@ PCAP_API int       pcap_parsesrcstr(const cha
   * For listing remote capture devices, pcap_findalldevs_ex() is currently
   * the only API available.
   */
 -PCAP_API int  pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth,
 -          pcap_if_t **alldevs, char *errbuf);
 +PCAP_API int  pcap_findalldevs_ex(const char *source,
 +          struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
  
  /*
   * Sampling methods.
@@@ -947,7 -950,7 +950,7 @@@ PCAP_API struct pcap_samp *pcap_setsamp
  
  PCAP_API SOCKET       pcap_remoteact_accept(const char *address, const char *port,
            const char *hostlist, char *connectinghost,
-           struct pcap_rmtauth *auth, char *errbuf);
+           struct pcap_rmtauth *auth, int uses_ssl, char *errbuf);
  PCAP_API int  pcap_remoteact_list(char *hostlist, char sep, int size,
            char *errbuf);
  PCAP_API int  pcap_remoteact_close(const char *host, char *errbuf);
diff --combined rpcapd/Makefile.in
index 1b530d5abf43eb7c060195808515ca4502d5be68,4ad94b8c1d7be4f36f61ceaa60043ea3006ede5e..659f0a7c0f8cdb5a79452a73f9898599d6d6a905
@@@ -66,7 -66,7 +66,7 @@@ PROG=libpca
  RPCAPD_LIBS = @RPCAPD_LIBS@
  
  # Standard CFLAGS
 -FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
 +FULL_CFLAGS = $(CCOPT) @V_PROG_CCOPT_FAT@ $(INCLS) $(DEFS) $(CFLAGS)
  
  INSTALL = @INSTALL@
  INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@@ -84,7 -84,7 +84,7 @@@ SRC = daemon.c 
        log-stderr.c \
        rpcapd.c
  
- OBJ = $(SRC:.c=.o) ../rpcap-protocol.o ../sockutils.o ../fmtutils.o
+ OBJ = $(SRC:.c=.o) ../rpcap-protocol.o ../sockutils.o ../fmtutils.o ../sslutils.o
  PUBHDR =
  
  HDR = $(PUBHDR) log.h
@@@ -98,8 -98,7 +98,8 @@@ MANADMIN = 
        rpcapd.manadmin.in
  
  rpcapd: $(OBJ) ../libpcap.a
 -      $(CC) $(CCOPT) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) ../libpcap.a $(LIBS) $(RPCAPD_LIBS) $(PTHREAD_LIBS)
 +      $(CC) $(CCOPT) $(CFLAGS) $(LDFLAGS) @V_PROG_LDFLAGS_FAT@ \
 +          -o $@ $(OBJ) ../libpcap.a $(LIBS) $(RPCAPD_LIBS) $(PTHREAD_LIBS)
  clean:
        rm -f $(CLEANFILES)
  
diff --combined rpcapd/daemon.c
index e30eeef1b73d4d2f5d07f63616ccbfbb06e7f8db,2c7abd786ad612736fb63343fb757fcedf00abf9..12b555ecceeb0189e3c03a55c15f701434dac311
  #include "daemon.h"
  #include "log.h"
  
+ #ifdef HAVE_OPENSSL
+ #include <openssl/ssl.h>
+ #include "sslutils.h"
+ #endif
  #define RPCAP_TIMEOUT_INIT 90         /* Initial timeout for RPCAP connections (default: 90 sec) */
  #define RPCAP_TIMEOUT_RUNTIME 180     /* Run-time timeout for RPCAP connections (default: 3 min) */
  #define RPCAP_SUSPEND_WRONGAUTH 1     /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
@@@ -73,6 -78,7 +78,7 @@@ struct daemon_slpar
  {
        SOCKET sockctrl_in;     //!< SOCKET ID of the input side of the control connection
        SOCKET sockctrl_out;    //!< SOCKET ID of the output side of the control connection
+       SSL *ssl;               //!< Optional SSL handler for the controlling sockets
        uint8 protocol_version; //!< negotiated protocol version
        int isactive;           //!< Not null if the daemon has to run in active mode
        int nullAuthAllowed;    //!< '1' if we permit NULL authentication, '0' otherwise
@@@ -84,6 -90,7 +90,7 @@@
  struct session {
        SOCKET sockctrl_out;
        SOCKET sockdata;
+       SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl_out and sockdata.
        uint8 protocol_version;
        pcap_t *fp;
        unsigned int TotCapt;
@@@ -107,18 -114,18 +114,18 @@@ struct thread_handle 
  };
  
  // Locally defined functions
- static int daemon_msg_err(SOCKET sockctrl_in, uint32 plen);
+ static int daemon_msg_err(SOCKET sockctrl_in, SSL *, uint32 plen);
  static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen);
  static int daemon_AuthUserPwd(char *username, char *password, char *errbuf);
  
  static int daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen);
  
  static int daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen);
- static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param);
+ static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param, int uses_ssl);
  static int daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata);
  
  static int daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen);
- static int daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errbuf);
+ static int daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *, struct session *session, uint32 *plenp, char *errbuf);
  
  static int daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt);
  
@@@ -131,12 -138,13 +138,13 @@@ static unsigned __stdcall daemon_thrdat
  static void *daemon_thrdatamain(void *ptr);
  #endif
  
- static int rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp);
- static int rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
- static int rpcapd_discard(SOCKET sock, uint32 len);
+ static int rpcapd_recv_msg_header(SOCKET sock, SSL *, struct rpcap_header *headerp);
+ static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
+ static int rpcapd_discard(SOCKET sock, SSL *, uint32 len);
+ static void session_close(struct session *);
  
  int
- daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, int isactive, int nullAuthAllowed)
+ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, SSL *ssl, int isactive, int nullAuthAllowed, int uses_ssl)
  {
        struct daemon_slpars pars;              // service loop parameters
        char errbuf[PCAP_ERRBUF_SIZE + 1];      // keeps the error string, prior to be printed
        // Set parameters structure
        pars.sockctrl_in = sockctrl_in;
        pars.sockctrl_out = sockctrl_out;
+       pars.ssl = ssl;
        pars.protocol_version = 0;              // not yet known
        pars.isactive = isactive;               // active mode
        pars.nullAuthAllowed = nullAuthAllowed;
  
                        FD_SET(pars.sockctrl_in, &rfds);
  
 -                      retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
 +                      retval = select((int)pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
                        if (retval == -1)
                        {
                                sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
-                               if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
                                        rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                                goto end;
                        }
                        // So, this was a fake connection. Drop it down
                        if (retval == 0)
                        {
-                               if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1)
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1)
                                        rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                                goto end;
                        }
                //
                // Read the message header from the client.
                //
-               nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
+               nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, pars.ssl, &header);
                if (nrecv == -1)
                {
                        // Fatal error.
                                //
                                reply_version = RPCAP_MAX_VERSION;
                        }
-                       if (rpcap_senderror(pars.sockctrl_out, reply_version,
+                       if (rpcap_senderror(pars.sockctrl_out, pars.ssl, reply_version,
                            PCAP_ERR_WRONGVER, "RPCAP version number mismatch",
                            errbuf) == -1)
                        {
                        }
  
                        // Discard the rest of the message.
-                       if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                       if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                        {
                                // Network error.
                                goto end;
                                // Discard the rest of the message, if
                                // there is anything more.
                                //
-                               (void)rpcapd_discard(pars.sockctrl_in, plen);
+                               (void)rpcapd_discard(pars.sockctrl_in, pars.ssl, plen);
                                // We're done with this client.
                                goto end;
  
                                // an error message rather than a "let
                                // me log in" message, indicating that
                                // we're not allowed to connect to them?
-                               (void)daemon_msg_err(pars.sockctrl_in, plen);
+                               (void)daemon_msg_err(pars.sockctrl_in, pars.ssl, plen);
                                goto end;
  
                        case RPCAP_MSG_FINDALLIF_REQ:
                                {
                                        pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type);
                                }
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_WRONGMSG,
                                    errmsgbuf, errbuf) == -1)
                                {
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Network error.
                                        goto end;
                                {
                                        pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
                                }
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_WRONGMSG,
                                    errmsgbuf, errbuf) == -1)
                                {
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Fatal error.
                                        goto end;
                                // Unknown message type.
                                //
                                pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_WRONGMSG,
                                    errmsgbuf, errbuf) == -1)
                                {
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Fatal error.
                                        goto end;
  
                        FD_SET(pars.sockctrl_in, &rfds);
  
 -                      retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
 +                      retval = select((int)pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
                        if (retval == -1)
                        {
                                sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_NETW,
                                    errmsgbuf, errbuf) == -1)
                                        rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                        // So, this was a fake connection. Drop it down
                        if (retval == 0)
                        {
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version,
                                    PCAP_ERR_INITTIMEOUT,
                                    "The RPCAP initial timeout has expired",
                //
                // Read the message header from the client.
                //
-               nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
+               nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, pars.ssl, &header);
                if (nrecv == -1)
                {
                        // Fatal error.
                        // so they don't reject it as having the wrong
                        // version.
                        //
-                       if (rpcap_senderror(pars.sockctrl_out,
+                       if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                            header.ver, PCAP_ERR_WRONGVER,
                            "RPCAP version in message isn't the negotiated version",
                            errbuf) == -1)
                        }
  
                        // Discard the rest of the message.
-                       (void)rpcapd_discard(pars.sockctrl_in, plen);
+                       (void)rpcapd_discard(pars.sockctrl_in, pars.ssl, plen);
                        // Give up on them.
                        goto end;
                }
                {
                        case RPCAP_MSG_ERROR:           // The other endpoint reported an error
                        {
-                               (void)daemon_msg_err(pars.sockctrl_in, plen);
+                               (void)daemon_msg_err(pars.sockctrl_in, pars.ssl, plen);
                                // Do nothing; just exit; the error code is already into the errbuf
                                // XXX - actually exit....
                                break;
                                {
                                        // They never told us what device
                                        // to capture on!
-                                       if (rpcap_senderror(pars.sockctrl_out,
+                                       if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                            pars.protocol_version,
                                            PCAP_ERR_STARTCAPTURE,
                                            "No capture device was specified",
                                                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                                                goto end;
                                        }
-                                       if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                                       if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                        {
                                                goto end;
                                        }
                                        break;
                                }
  
-                               if (daemon_msg_startcap_req(&pars, plen, &threaddata, source, &session, &samp_param) == -1)
+                               if (daemon_msg_startcap_req(&pars, plen, &threaddata, source, &session, &samp_param, uses_ssl) == -1)
                                {
                                        // Fatal error; a message has
                                        // been logged, so just give up.
                                }
                                else
                                {
-                                       if (rpcap_senderror(pars.sockctrl_out,
+                                       if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                            pars.protocol_version,
                                            PCAP_ERR_UPDATEFILTER,
                                            "Device not opened. Cannot update filter",
                                }
                                else
                                {
-                                       rpcap_senderror(pars.sockctrl_out,
+                                       rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                            pars.protocol_version,
                                            PCAP_ERR_ENDCAPTURE,
                                            "Device not opened. Cannot close the capture",
                                // get to reauthenticate.
                                //
                                rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version,
                                    PCAP_ERR_WRONGMSG,
                                    "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Fatal error.
                                        goto end;
                                        rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type);
                                        pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
                                }
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_WRONGMSG,
                                    errmsgbuf, errbuf) == -1)
                                {
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Fatal error.
                                        goto end;
                                //
                                rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type);
                                pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
-                               if (rpcap_senderror(pars.sockctrl_out,
+                               if (rpcap_senderror(pars.sockctrl_out, pars.ssl,
                                    pars.protocol_version, PCAP_ERR_WRONGMSG,
                                    errbuf, errmsgbuf) == -1)
                                {
                                        goto end;
                                }
                                // Discard the rest of the message.
-                               if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+                               if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1)
                                {
                                        // Fatal error.
                                        goto end;
@@@ -865,12 -874,8 +874,8 @@@ end
  #endif
                        threaddata.have_thread = 0;
                }
-               if (session->sockdata)
-               {
-                       sock_close(session->sockdata, NULL, 0);
-                       session->sockdata = 0;
-               }
-               pcap_close(session->fp);
+               session_close(session);
                free(session);
                session = NULL;
        }
   * This handles the RPCAP_MSG_ERR message.
   */
  static int
- daemon_msg_err(SOCKET sockctrl_in, uint32 plen)
+ daemon_msg_err(SOCKET sockctrl_in, SSL *ssl, uint32 plen)
  {
        char errbuf[PCAP_ERRBUF_SIZE];
        char remote_errbuf[PCAP_ERRBUF_SIZE];
                 * Message is too long; just read as much of it as we
                 * can into the buffer provided, and discard the rest.
                 */
-               if (sock_recv(sockctrl_in, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
+               if (sock_recv(sockctrl_in, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
                    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
                    PCAP_ERRBUF_SIZE) == -1)
                {
                        rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
                        return -1;
                }
-               if (rpcapd_discard(sockctrl_in, plen - (PCAP_ERRBUF_SIZE - 1)) == -1)
+               if (rpcapd_discard(sockctrl_in, ssl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1)
                {
                        // Network error.
                        return -1;
        }
        else
        {
-               if (sock_recv(sockctrl_in, remote_errbuf, plen,
+               if (sock_recv(sockctrl_in, ssl, remote_errbuf, plen,
                    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
                    PCAP_ERRBUF_SIZE) == -1)
                {
@@@ -973,7 -978,7 +978,7 @@@ daemon_msg_auth_req(struct daemon_slpar
        int status;
        struct rpcap_auth auth;                 // RPCAP authentication header
  
-       status = rpcapd_recv(pars->sockctrl_in, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
+       status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
        if (status == -1)
        {
                return -1;
                                    PCAP_ERRBUF_SIZE, errno, "malloc() failed");
                                goto error;
                        }
-                       status = rpcapd_recv(pars->sockctrl_in, username, usernamelen, &plen, errmsgbuf);
+                       status = rpcapd_recv(pars->sockctrl_in, pars->ssl, username, usernamelen, &plen, errmsgbuf);
                        if (status == -1)
                        {
                                free(username);
                                free(username);
                                goto error;
                        }
-                       status = rpcapd_recv(pars->sockctrl_in, passwd, passwdlen, &plen, errmsgbuf);
+                       status = rpcapd_recv(pars->sockctrl_in, pars->ssl, passwd, passwdlen, &plen, errmsgbuf);
                        if (status == -1)
                        {
                                free(username);
                                //
                                free(username);
                                free(passwd);
-                               if (rpcap_senderror(pars->sockctrl_out,
+                               if (rpcap_senderror(pars->sockctrl_out, pars->ssl,
                                    pars->protocol_version,
                                    PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
                                {
        rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_AUTH_REPLY, 0, 0);
  
        // Send the ok message back
-       if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                // That failed; log a messsage and give up.
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
        }
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
        return 0;
  
  error:
-       if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
        {
                // That failed; log a message and give up.
  
  error_noreply:
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
@@@ -1262,7 -1267,7 +1267,7 @@@ daemon_msg_findallif_req(struct daemon_
        uint16 nif = 0;                         // counts the number of interface listed
  
        // Discard the rest of the message; there shouldn't be any payload.
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                // Network error.
                return -1;
  
        if (alldevs == NULL)
        {
-               if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+               if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
                        PCAP_ERR_NOREMOTEIF,
                        "No interfaces found! Make sure libpcap/WinPcap is properly installed"
                        " and you have the right to access to the remote device.",
        pcap_freealldevs(alldevs);
  
        // Send a final command that says "now send it!"
-       if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                return -1;
@@@ -1440,7 -1445,7 +1445,7 @@@ error
        if (alldevs)
                pcap_freealldevs(alldevs);
  
-       if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1)
        {
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@@ -1470,7 -1475,7 +1475,7 @@@ daemon_msg_open_req(struct daemon_slpar
                goto error;
        }
  
-       nread = sock_recv(pars->sockctrl_in, source, plen,
+       nread = sock_recv(pars->sockctrl_in, pars->ssl, source, plen,
            SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
        if (nread == -1)
        {
        pcap_close(fp);
  
        // Send the reply.
-       if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                return -1;
        return 0;
  
  error:
-       if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1)
        {
                // That failed; log a message and give up.
        }
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
        to discard excess data in the message, if present)
  */
  static int
- daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param _U_)
+ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param _U_, int uses_ssl)
  {
        char errbuf[PCAP_ERRBUF_SIZE];          // buffer for network errors
        char errmsgbuf[PCAP_ERRBUF_SIZE];       // buffer for errors to send to the client
  
        addrinfo = NULL;
  
-       status = rpcapd_recv(pars->sockctrl_in, (char *) &startcapreq,
+       status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &startcapreq,
            sizeof(struct rpcap_startcapreq), &plen, errmsgbuf);
        if (status == -1)
        {
  
        startcapreq.flags = ntohs(startcapreq.flags);
  
+       // Check that the client does not ask for UDP is the server has been asked
+       // to enforce encryption, as SSL is not supported yet with UDP:
+       if (uses_ssl && (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM))
+       {
+               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+                   "SSL not supported with UDP forward of remote packets");
+               goto error;
+       }
        // Create a session structure
        session = malloc(sizeof(struct session));
        if (session == NULL)
                goto error;
        }
  
+       session->ctrl_ssl = session->data_ssl = NULL;
        // Open the selected device
        if ((session->fp = pcap_open_live(source,
                        ntohl(startcapreq.snaplen),
  
        // Needed to send an error on the ctrl connection
        session->sockctrl_out = pars->sockctrl_out;
+       session->ctrl_ssl = pars->ssl;
        session->protocol_version = pars->protocol_version;
  
        // Now I can set the filter
-       ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
+       ret = daemon_unpackapplyfilter(pars->sockctrl_in, pars->ssl, session, &plen, errmsgbuf);
        if (ret == -1)
        {
                // Fatal error.  A message has been logged; just give up.
                startcapreply->portdata = htons(port);
        }
  
-       if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                // That failed; log a message and give up.
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                sockdata = socktemp;
        }
  
+       SSL *ssl = NULL;
+       if (uses_ssl)
+       {
+ #ifdef HAVE_OPENSSL
+               /* In both active or passive cases, wait for the client to initiate the
+                * TLS handshake. Yes during that time the control socket will not be
+                * served, but the same was true from the above call to accept(). */
+               ssl = ssl_promotion(1, sockdata, errbuf, PCAP_ERRBUF_SIZE);
+               if (! ssl)
+               {
+                       rpcapd_log(LOGPRIO_ERROR, "TLS handshake failed: %s", errbuf);
+                       goto error;
+               }
+ #endif
+       }
+       session->data_ssl = ssl;
        session->sockdata = sockdata;
  
        // Now we have to create a new thread to receive packets
        threaddata->have_thread = 1;
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
                goto fatal_error;
  
        *sessionp = session;
@@@ -1822,10 -1855,16 +1855,16 @@@ error
        {
                if (session->fp)
                        pcap_close(session->fp);
+ #ifdef HAVE_OPENSSL
+               if (session->ctrl_ssl)
+                       SSL_free(session->ctrl_ssl);
+               if (session->data_ssl)
+                       SSL_free(session->data_ssl);
+ #endif
                free(session);
        }
  
-       if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1)
        {
                // That failed; log a message and give up.
        }
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                // Network error.
                return -1;
@@@ -1894,6 -1933,12 +1933,12 @@@ fatal_error
        {
                if (session->fp)
                        pcap_close(session->fp);
+ #ifdef HAVE_OPENSSL
+               if (session->ctrl_ssl)
+                       SSL_free(session->ctrl_ssl);
+               if (session->data_ssl)
+                       SSL_free(session->data_ssl);
+ #endif
                free(session);
        }
  
@@@ -1940,18 -1985,13 +1985,13 @@@ daemon_msg_endcap_req(struct daemon_slp
  #endif
                threaddata->have_thread = 0;
        }
-       if (session->sockdata)
-       {
-               sock_close(session->sockdata, NULL, 0);
-               session->sockdata = 0;
-       }
  
-       pcap_close(session->fp);
+       session_close(session);
  
        rpcap_createhdr(&header, pars->protocol_version,
            RPCAP_MSG_ENDCAP_REPLY, 0, 0);
  
-       if (sock_send(pars->sockctrl_out, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                // That failed; log a message and give up.
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
  }
  
  static int
- daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errmsgbuf)
+ daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf)
  {
        int status;
        struct rpcap_filter filter;
        struct bpf_program bf_prog;
        unsigned int i;
  
-       status = rpcapd_recv(sockctrl_in, (char *) &filter,
+       status = rpcapd_recv(sockctrl_in, ctrl_ssl, (char *) &filter,
            sizeof(struct rpcap_filter), plenp, errmsgbuf);
        if (status == -1)
        {
  
        for (i = 0; i < bf_prog.bf_len; i++)
        {
-               status = rpcapd_recv(sockctrl_in, (char *) &insn,
+               status = rpcapd_recv(sockctrl_in, ctrl_ssl, (char *) &insn,
                    sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf);
                if (status == -1)
                {
@@@ -2047,7 -2087,7 +2087,7 @@@ daemon_msg_updatefilter_req(struct daem
        int ret;                                // status of daemon_unpackapplyfilter()
        struct rpcap_header header;             // keeps the answer to the updatefilter command
  
-       ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
+       ret = daemon_unpackapplyfilter(pars->sockctrl_in, pars->ssl, session, &plen, errmsgbuf);
        if (ret == -1)
        {
                // Fatal error.  A message has been logged; just give up.
        }
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                // Network error.
                return -1;
        rpcap_createhdr(&header, pars->protocol_version,
            RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);
  
-       if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE))
+       if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE))
        {
                // That failed; log a messsage and give up.
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
        return 0;
  
  error:
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
-       rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL);
  
        return 0;
@@@ -2102,7 -2142,7 +2142,7 @@@ daemon_msg_setsampling_req(struct daemo
        struct rpcap_sampling rpcap_samp;
        int status;
  
-       status = rpcapd_recv(pars->sockctrl_in, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf);
+       status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf);
        if (status == -1)
        {
                return -1;
        rpcap_createhdr(&header, pars->protocol_version,
            RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);
  
-       if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                // That failed; log a messsage and give up.
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                return -1;
        }
  
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
        return 0;
  
  error:
-       if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
        {
                // That failed; log a message and give up.
        }
  
        // Check if all the data has been read; if not, discard the data in excess
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                return -1;
        }
@@@ -2162,7 -2202,7 +2202,7 @@@ daemon_msg_stats_req(struct daemon_slpa
        struct rpcap_stats *netstats;           // statistics sent on the network
  
        // Checks that the header does not contain other data; if so, discard it
-       if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+       if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1)
        {
                // Network error.
                return -1;
        }
  
        // Send the packet
-       if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+       if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
        {
                rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
                return -1;
        return 0;
  
  error:
-       rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+       rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version,
            PCAP_ERR_GETSTATS, errmsgbuf, NULL);
        return 0;
  }
@@@ -2359,8 -2399,8 +2399,8 @@@ daemon_thrdatamain(void *ptr
                // This protocol needs to be updated with a new version
                // before 2038-01-19 03:14:07 UTC.
                //
 -              net_pkt_header->timestamp_sec = (uint32)htonl(pkt_header->ts.tv_sec);
 -              net_pkt_header->timestamp_usec = (uint32)htonl(pkt_header->ts.tv_usec);
 +              net_pkt_header->timestamp_sec = htonl((uint32)pkt_header->ts.tv_sec);
 +              net_pkt_header->timestamp_usec = htonl((uint32)pkt_header->ts.tv_usec);
  
                // Bufferize the pkt data
                if (sock_bufferize((char *) pkt_data, pkt_header->caplen,
                // Send the packet
                // If the client dropped the connection, don't report an
                // error, just quit.
-               status = sock_send(session->sockdata, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE);
+               status = sock_send(session->sockdata, session->data_ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE);
                if (status < 0)
                {
                        if (status == -1)
        if (retval == -1)
        {
                pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp));
-               rpcap_senderror(session->sockctrl_out, session->protocol_version,
+               rpcap_senderror(session->sockctrl_out, session->ctrl_ssl, session->protocol_version,
                    PCAP_ERR_READEX, errbuf, NULL);
                goto error;
        }
  
  error:
-       closesocket(session->sockdata);
-       session->sockdata = 0;
+       session_close(session);
  
        free(sendbuf);
  
@@@ -2497,12 -2536,12 +2536,12 @@@ void sleep_secs(int secs
   * Read the header of a message.
   */
  static int
- rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp)
+ rpcapd_recv_msg_header(SOCKET sock, SSL *ssl, struct rpcap_header *headerp)
  {
        int nread;
        char errbuf[PCAP_ERRBUF_SIZE];          // buffer for network errors
  
-       nread = sock_recv(sock, (char *) headerp, sizeof(struct rpcap_header),
+       nread = sock_recv(sock, ssl, (char *) headerp, sizeof(struct rpcap_header),
            SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE);
        if (nread == -1)
        {
   * error.
   */
  static int
- rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
+ rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
  {
        int nread;
        char errbuf[PCAP_ERRBUF_SIZE];          // buffer for network errors
                pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
                return -2;
        }
-       nread = sock_recv(sock, buffer, toread,
+       nread = sock_recv(sock, ssl, buffer, toread,
            SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
        if (nread == -1)
        {
   * error.
   */
  static int
- rpcapd_discard(SOCKET sock, uint32 len)
+ rpcapd_discard(SOCKET sock, SSL *ssl, uint32 len)
  {
        char errbuf[PCAP_ERRBUF_SIZE + 1];      // keeps the error string, prior to be printed
  
        if (len != 0)
        {
-               if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
+               if (sock_discard(sock, ssl, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
                {
                        // Network error.
                        rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
        }
        return 0;
  }
+ /*
+  * Close the socket associated with the session, the optional SSL handle,
+  * and the underlying packet capture handle. We of course do not touch
+  * the controlling socket that's also copied into the session.
+  */
+ static void session_close(struct session *session)
+ {
+ #ifdef HAVE_OPENSSL
+       if (session->data_ssl)
+       {
+               SSL_free(session->data_ssl); // Must happen *before* the socket is closed
+               session->data_ssl = NULL;
+       }
+ #endif
+       if (session->sockdata)
+       {
+               sock_close(session->sockdata, NULL, 0);
+               session->sockdata = 0;
+       }
+       pcap_close(session->fp);
+ }
diff --combined rpcapd/rpcapd.c
index 9e46a2de5c464a3f3fdd65ee7d98b3e08211e9de,645828eab81ebd31ed95821978969e17033148f8..0509147a841845969084163e521b24ec2b295091
  #include "daemon.h"           // the true main() method of this daemon
  #include "log.h"
  
+ #ifdef HAVE_OPENSSL
+ #include "sslutils.h"
+ #endif
  #ifdef _WIN32
    #include <process.h>                // for thread stuff
    #include "win32-svc.h"      // for Win32 service stuff
@@@ -86,6 -90,7 +90,7 @@@ static HANDLE state_change_event;             //!
  #endif
  static volatile sig_atomic_t shutdown_server; //!< '1' if the server is to shut down
  static volatile sig_atomic_t reread_config;   //!< '1' if the server is to re-read its configuration
+ static int uses_ssl; //!< '1' to use TLS over the data socket
  
  extern char *optarg;  // for getopt()
  
@@@ -143,6 -148,12 +148,12 @@@ static void printusage(void
        "                  the service is started from the control panel\n\n"
  #ifndef _WIN32
        "  -i              run in inetd mode (UNIX only)\n\n"
+ #endif
+ #ifdef HAVE_OPENSSL
+       "  -S              encrypt all communication with SSL (implements rpcaps://)\n"
+       "  -C              enable compression\n"
+       "  -K <pem_file>   uses the SSL private key in this file (default: key.pem)\n"
+       "  -X <pem_file>   uses the certificate from this file (default: cert.pem)\n"
  #endif
        "  -s <config_file> save the current configuration to file\n\n"
        "  -f <config_file> load the current configuration from file; all switches\n"
@@@ -169,6 -180,9 +180,9 @@@ int main(int argc, char *argv[]
  #ifndef _WIN32
        struct sigaction action;
  #endif
+ #ifdef HAVE_OPENSSL
+       int enable_compression = 0;
+ #endif
  
        savefile[0] = 0;
        loadfile[0] = 0;
        mainhints.ai_socktype = SOCK_STREAM;
  
        // Getting the proper command line options
-       while ((retval = getopt(argc, argv, "b:dhip:4l:na:s:f:v")) != -1)
+ #     ifdef HAVE_OPENSSL
+ #             define SSL_CLOPTS  "SK:X:C"
+ #     else
+ #             define SSL_CLOPTS ""
+ #     endif
+ #     define CLOPTS "b:dhip:4l:na:s:f:v" SSL_CLOPTS
+       while ((retval = getopt(argc, argv, CLOPTS)) != -1)
        {
                switch (retval)
                {
                                {
                                        tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
  
 -                                      strlcpy(activelist[i].address, tmpaddress, MAX_LINE);
 +                                      pcap_strlcpy(activelist[i].address, tmpaddress, MAX_LINE);
  
                                        if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
 -                                              strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE);
 +                                              pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE);
                                        else
 -                                              strlcpy(activelist[i].port, tmpport, MAX_LINE);
 +                                              pcap_strlcpy(activelist[i].port, tmpport, MAX_LINE);
  
                                        tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
  
                                break;
                        }
                        case 'f':
 -                              strlcpy(loadfile, optarg, MAX_LINE);
 +                              pcap_strlcpy(loadfile, optarg, MAX_LINE);
                                break;
                        case 's':
 -                              strlcpy(savefile, optarg, MAX_LINE);
 +                              pcap_strlcpy(savefile, optarg, MAX_LINE);
                                break;
+ #ifdef HAVE_OPENSSL
+                       case 'S':
+                               uses_ssl = 1;
+                               break;
+                       case 'C':
+                               enable_compression = 1;
+                               break;
+                       case 'K':
+                               snprintf(ssl_keyfile, sizeof ssl_keyfile, "%s", optarg);
+                               break;
+                       case 'X':
+                               snprintf(ssl_certfile, sizeof ssl_certfile, "%s", optarg);
+                               break;
+ #endif
                        case 'h':
                                printusage();
                                exit(0);
 -                              break;
 +                              /*NOTREACHED*/
                        default:
                                exit(1);
 -                              break;
 +                              /*NOTREACHED*/
                }
        }
  
        signal(SIGPIPE, SIG_IGN);
  #endif
  
+ # ifdef HAVE_OPENSSL
+       if (uses_ssl) init_ssl_or_die(1, enable_compression);
+ # endif
  #ifndef _WIN32
        if (isrunbyinetd)
        {
                        close(devnull_fd);
                }
  
+               SSL *ssl = NULL;
+ #ifdef HAVE_OPENSSL
+               if (uses_ssl)
+               {
+                       ssl = ssl_promotion_rw(1, sockctrl_in, sockctrl_out, errbuf, PCAP_ERRBUF_SIZE);
+                       if (! ssl)
+                       {
+                               rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
+                                   errbuf);
+                               exit(2);
+                       }
+               }
+ #endif
                //
                // Handle this client.
                // This is passive mode, so we don't care whether we were
                // told by the client to close.
                //
-               (void)daemon_serviceloop(sockctrl_in, sockctrl_out, 0,
-                   nullAuthAllowed);
+               (void)daemon_serviceloop(sockctrl_in, sockctrl_out, ssl, 0,
+                   nullAuthAllowed, uses_ssl);
  
                //
                // Nothing more to do.
@@@ -1033,6 -1086,22 +1086,22 @@@ accept_connections(void
        sock_cleanup();
  }
  
+ #ifdef _WIN32
+ //
+ // A structure to hold the parameter to the windows thread
+ // (on unix there is no need for this explicit copy since the
+ // fork "inherits" the parent stack)
+ //
+ struct sock_copy {
+       SOCKET sockctrl;
+ #     ifdef HAVE_OPENSSL
+       SSL *ssl;
+ #     else
+       void *ssl;
+ #     endif
+ };
+ #endif
  //
  // Accept a connection and start a worker thread, on Windows, or a
  // worker process, on UN*X, to handle the connection.
@@@ -1045,10 -1114,12 +1114,12 @@@ accept_connection(SOCKET listen_sock
        struct sockaddr_storage from;           // generic sockaddr_storage variable
        socklen_t fromlen;                      // keeps the length of the sockaddr_storage variable
  
+       SSL *ssl = NULL;
  #ifdef _WIN32
        HANDLE threadId;                        // handle for the subthread
        u_long off = 0;
-       SOCKET *sockctrl_temp;
+       struct sock_copy *sock_copy = NULL;
  #else
        pid_t pid;
  #endif
                return;
        }
  
+ #ifdef HAVE_OPENSSL
+       /* We have to upgrade to TLS as soon as possible so that the whole protocol
+        * goes through the encrypted tunnel, including early error messages. */
+       if (uses_ssl)
+       {
+               ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
+               if (! ssl)
+               {
+                       rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
+                           errbuf);
+                       goto error;
+               }
+       }
+ #endif
        //
        // We have a connection.
        // Check whether the connecting host is among the ones allowed.
        //
        if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
        {
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+               goto error;
        }
  
  #ifdef _WIN32
        if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
        {
                sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+               goto error;
        }
        if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
        {
                sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+               goto error;
        }
  
        //
        // I guess we *could* just cast sockctrl to a void *, but that's
        // a bit ugly.
        //
-       sockctrl_temp = (SOCKET *)malloc(sizeof (SOCKET));
-       if (sockctrl_temp == NULL)
+       sock_copy = malloc(sizeof(*sock_copy));
+       if (sock_copy == NULL)
        {
                pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
                    errno, "malloc() failed");
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+               goto error;
        }
-       *sockctrl_temp = sockctrl;
+       sock_copy->sockctrl = sockctrl;
+       sock_copy->ssl = NULL;
  
        threadId = (HANDLE)_beginthreadex(NULL, 0,
-           main_passive_serviceloop_thread, (void *) sockctrl_temp, 0, NULL);
+           main_passive_serviceloop_thread, (void *) sock_copy, 0, NULL);
        if (threadId == 0)
        {
                pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child thread");
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               free(sockctrl_temp);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+               goto error;
        }
        CloseHandle(threadId);
  #else
        if (pid == -1)
        {
                pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child process");
-               rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
-               sock_close(sockctrl, NULL, 0);
-               return;
+               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+               goto error;
        }
        if (pid == 0)
        {
                // This is passive mode, so we don't care whether we were
                // told by the client to close.
                //
-               (void)daemon_serviceloop(sockctrl, sockctrl, 0,
-                   nullAuthAllowed);
+               (void)daemon_serviceloop(sockctrl, sockctrl, ssl, 0,
+                   nullAuthAllowed, uses_ssl);
  
                close(sockctrl);
  
  
        // I am the parent
        // Close the socket for this session (must be open only in the child)
+ #ifdef HAVE_OPENSSL
+       if (ssl)
+       {
+               SSL_free(ssl);
+               ssl = NULL;
+       }
+ #endif
        closesocket(sockctrl);
  #endif
+   return;
+ error:
+ #ifdef _WIN32
+       if (sock_copy) free(sock_copy);
+ #endif
+ #ifdef HAVE_OPENSSL
+       if (ssl) SSL_free(ssl);  // Have to be done before closing soskctrl
+ #endif
+       sock_close(sockctrl, NULL, 0);
  }
  
  /*!
@@@ -1225,6 -1322,7 +1322,7 @@@ main_active(void *ptr
        struct addrinfo hints;                  // temporary struct to keep settings needed to open the new socket
        struct addrinfo *addrinfo;              // keeps the addrinfo chain; required to open a new socket
        struct active_pars *activepars;
+       SSL *ssl = NULL;
  
        activepars = (struct active_pars *) ptr;
  
                        continue;
                }
  
-               activeclose = daemon_serviceloop(sockctrl, sockctrl, 1,
-                   nullAuthAllowed);
+ #ifdef HAVE_OPENSSL
+               /* Even in active mode the other other end has to initiate the TLS handshake
+                * as we still are the server as far as TLS is concerned: */
+               if (uses_ssl)
+               {
+                       ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
+                       if (! ssl)
+                       {
+                               rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
+                                   errbuf);
+                               sock_close(sockctrl, NULL, 0);
+                               continue;
+                       }
+               }
+ #endif
+               activeclose = daemon_serviceloop(sockctrl, sockctrl, ssl, 1,
+                   nullAuthAllowed, uses_ssl);
  
+ #ifdef HAVE_OPENSSL
+               if (ssl) SSL_free(ssl);
+ #endif
                sock_close(sockctrl, NULL, 0);
  
                // If the connection is closed by the user explicitely, don't try to connect to it again
  //
  unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
  {
-       SOCKET sockctrl;
-       sockctrl = *((SOCKET *)ptr);
+       struct sock_copy sock = *(struct sock_copy *)ptr;
        free(ptr);
  
        //
        // This is passive mode, so we don't care whether we were
        // told by the client to close.
        //
-       (void)daemon_serviceloop(sockctrl, sockctrl, 0, nullAuthAllowed);
+       (void)daemon_serviceloop(sock.sockctrl, sock.sockctrl, sock.ssl, 0,
+           nullAuthAllowed, uses_ssl);
  
-       sock_close(sockctrl, NULL, 0);
+       sock_close(sock.sockctrl, NULL, 0);
  
        return 0;
  }
diff --combined sockutils.c
index 7ed7d2984a4a69df1af801c74a038d21bdd77216,8474552712c02b36e9b49c785cc2903e808ac6ed..25844c6cd53d9dee0998b2c34f53bd03e8ffbd3e
@@@ -640,7 -640,7 +640,7 @@@ int sock_initaddress(const char *host, 
   * '-2' if we got one of those errors.
   * For errors, an error message is returned in the 'errbuf' variable.
   */
- int sock_send(SOCKET sock, const char *buffer, size_t size,
+ int sock_send(SOCKET sock, SSL *ssl, const char *buffer, size_t size,
      char *errbuf, int errbuflen)
  {
        int remaining;
        remaining = (int)size;
  
        do {
+ #ifdef HAVE_OPENSSL
+               if (ssl) return ssl_send(ssl, buffer, remaining, errbuf, errbuflen);
+ #else
+               (void)ssl;
+ #endif
  #ifdef MSG_NOSIGNAL
                /*
                 * Send with MSG_NOSIGNAL, so that we don't get SIGPIPE
@@@ -835,10 -841,9 +841,10 @@@ int sock_bufferize(const char *buffer, 
   * The error message is returned in the 'errbuf' variable.
   */
  
- int sock_recv(SOCKET sock, void *buffer, size_t size, int flags,
+ int sock_recv(SOCKET sock, SSL *ssl, void *buffer, size_t size, int flags,
      char *errbuf, int errbuflen)
  {
 +      int recv_flags = 0;
        char *bufp = buffer;
        int remaining;
        ssize_t nread;
                return -1;
        }
  
 +      if (flags & SOCK_MSG_PEEK)
 +              recv_flags |= MSG_PEEK;
 +
        bufp = (char *) buffer;
        remaining = (int) size;
  
         * Win32.
         */
        for (;;) {
 -              (void)ssl;
+ #ifdef HAVE_OPENSSL
+               if (ssl)
+               {
++                      /*
++                       * XXX - what about MSG_PEEK?
++                       */
+                       nread = ssl_recv(ssl, bufp, remaining, errbuf, errbuflen);
+                       if (nread == -2) return -1;
+               }
+               else
++                      nread = recv(sock, bufp, remaining, recv_flags);
+ #else
 -              nread = recv(sock, bufp, remaining, 0);
 +              nread = recv(sock, bufp, remaining, recv_flags);
+ #endif
  
                if (nread == -1)
                {
   *
   * Returns the size of the datagram on success or -1 on error.
   */
- int sock_recv_dgram(SOCKET sock, void *buffer, size_t size,
+ int sock_recv_dgram(SOCKET sock, SSL *ssl, void *buffer, size_t size,
      char *errbuf, int errbuflen)
  {
        ssize_t nread;
                return -1;
        }
  
+       // TODO: DTLS
+       if (ssl)
+       {
+               pcap_snprintf(errbuf, errbuflen, "DTLS not implemented yet");
+               return -1;
+       }
        /*
         * This should be a datagram socket, so we should get the
         * entire datagram in one recv() or recvmsg() call, and
         * don't need to loop.
         */
  #ifdef _WIN32
 -      nread = recv(sock, buffer, size, 0);
 +      nread = recv(sock, buffer, (int)size, 0);
        if (nread == SOCKET_ERROR)
        {
                /*
   * \return '0' if everything is fine, '-1' if some errors occurred.
   * The error message is returned in the 'errbuf' variable.
   */
- int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen)
+ int sock_discard(SOCKET sock, SSL *ssl, int size, char *errbuf, int errbuflen)
  {
  #define TEMP_BUF_SIZE 32768
  
         */
        while (size > TEMP_BUF_SIZE)
        {
-               if (sock_recv(sock, buffer, TEMP_BUF_SIZE, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
+               if (sock_recv(sock, ssl, buffer, TEMP_BUF_SIZE, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
                        return -1;
  
                size -= TEMP_BUF_SIZE;
         */
        if (size)
        {
-               if (sock_recv(sock, buffer, size, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
+               if (sock_recv(sock, ssl, buffer, size, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
                        return -1;
        }
  
@@@ -1389,7 -1408,7 +1415,7 @@@ int sock_getascii_addrport(const struc
                        (memcmp(&((struct sockaddr_in6 *) sockaddr)->sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(struct in6_addr)) == 0))
                {
                        if (address)
 -                              strlcpy(address, SOCKET_NAME_NULL_DAD, addrlen);
 +                              pcap_strlcpy(address, SOCKET_NAME_NULL_DAD, addrlen);
                        return retval;
                }
        }
  
                if (address)
                {
 -                      strlcpy(address, SOCKET_NO_NAME_AVAILABLE, addrlen);
 +                      pcap_strlcpy(address, SOCKET_NO_NAME_AVAILABLE, addrlen);
                        address[addrlen - 1] = 0;
                }
  
                if (port)
                {
 -                      strlcpy(port, SOCKET_NO_PORT_AVAILABLE, portlen);
 +                      pcap_strlcpy(port, SOCKET_NO_PORT_AVAILABLE, portlen);
                        port[portlen - 1] = 0;
                }
  
diff --combined sockutils.h
index 3102fcef988b4663efee6b54c1a69b153da3cbed,95bd8ddb30846d3df475cb03fc7761e241471fbb..fc271bf9ddeb5e7b89fe203dfed24dd7d5df248f
    #define closesocket(a) close(a)
  #endif
  
+ #include "sslutils.h"  // for SSL type, whatever that turns out to be
  /*
   * MingW headers include this definition, but only for Windows XP and above.
   * MSDN states that this function is available for most versions on Windows.
@@@ -182,8 -184,6 +184,8 @@@ int WSAAPI getnameinfo(const struct soc
  #define SOCK_EOF_ISNT_ERROR   0x00000000      /* Return 0 on EOF */
  #define SOCK_EOF_IS_ERROR     0x00000002      /* Return an error on EOF */
  
 +#define SOCK_MSG_PEEK         0x00000004      /* Return data but leave it in the socket queue */
 +
  /*
   * \}
   */
@@@ -208,17 -208,17 +210,17 @@@ void sock_geterror(const char *caller, 
  int sock_initaddress(const char *address, const char *port,
      struct addrinfo *hints, struct addrinfo **addrinfo,
      char *errbuf, int errbuflen);
- int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
+ int sock_recv(SOCKET sock, SSL *, void *buffer, size_t size, int receiveall,
      char *errbuf, int errbuflen);
- int sock_recv_dgram(SOCKET sock, void *buffer, size_t size,
+ int sock_recv_dgram(SOCKET sock, SSL *, void *buffer, size_t size,
      char *errbuf, int errbuflen);
  SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen);
  int sock_close(SOCKET sock, char *errbuf, int errbuflen);
  
- int sock_send(SOCKET sock, const char *buffer, size_t size,
+ int sock_send(SOCKET sock, SSL *, const char *buffer, size_t size,
      char *errbuf, int errbuflen);
  int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen);
- int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen);
+ int sock_discard(SOCKET sock, SSL *, int size, char *errbuf, int errbuflen);
  int   sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen);
  int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second);