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@
@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@
+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 \
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 \
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 \
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
$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
cd rpcapd; $(MAKE) depend
cd testprogs; $(MAKE) depend
+
+
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)
# 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
+ 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
+
/* 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
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
MAN_DEVICES
DYEXT
SSRC
+MSRC
ADDLARCHIVEOBJS
ADDLOBJS
V_YACC
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
LEXLIB
LEX_OUTPUT_ROOT
LEX
+ OPENSSL_LIBS
+ OPENSSL_CFLAGS
+ PKG_CONFIG_LIBDIR
+ PKG_CONFIG_PATH
+ PKG_CONFIG
PCAP_SUPPORT_PACKET_RING
VALGRINDTEST_SRC
LIBOBJS
docdir
oldincludedir
includedir
-runstatedir
localstatedir
sharedstatedir
sysconfdir
enable_shared
enable_usb
enable_netmap
+with_dpdk
enable_bluetooth
enable_dbus
enable_rdma
LIBS
CPPFLAGS
CPP
+ PKG_CONFIG
+ PKG_CONFIG_PATH
+ PKG_CONFIG_LIBDIR
+ OPENSSL_CFLAGS
+ OPENSSL_LIBS
YACC
YFLAGS'
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.
--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]
--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'.
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
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];
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];
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];
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];
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`
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
;;
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
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.
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
LDFLAGS="$LDFLAGS -L$snf_lib_dir"
if test "$V_PCAP" != snf ; then
- SSRC="$SSRC pcap-snf.c"
+ MSRC="$MSRC pcap-snf.c"
fi
{ $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"
+
+
+
+
+
$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; }
$as_echo "#define PCAP_SUPPORT_NETFILTER 1" >>confdefs.h
- NETFILTER_SRC=pcap-netfilter-linux.c
+ MSRC="$MSRC pcap-netfilter-linux.c"
fi
;;
*)
fi
-
# Check whether --enable-netmap was given.
if test "${enable_netmap+set}" = set; then :
enableval=$enable_netmap;
$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
$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
$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
;;
esac
-
-
fi
# Check whether --enable-dbus was given.
$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
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 :
$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),
# 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
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,,
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])
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
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.
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])
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])
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++"
#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
;;
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
])
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)
AC_SUBST(V_YACC)
AC_SUBST(ADDLOBJS)
AC_SUBST(ADDLARCHIVEOBJS)
+AC_SUBST(MSRC)
AC_SUBST(SSRC)
AC_SUBST(DYEXT)
AC_SUBST(MAN_DEVICES)
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
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@:>@])],
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@:>@])],
# 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],
[
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
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);
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().
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()".
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
#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.
{
struct sockaddr_storage host;
SOCKET sockctrl;
+ SSL *ssl;
uint8 protocol_version;
struct activehosts *next;
};
* pcap_remoteact_cleanup() for more details.
*/
static SOCKET sockmain;
+ static SSL *ssl_main;
/*
* Private data for capturing remotely using the rpcap protocol.
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 */
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);
/****************************************************
* *
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' */
* 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();
}
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;
* 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;
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;
/*
* 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);
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;
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;
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;
* 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;
}
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;
}
*
* 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;
* 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;
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)
{
/*
#include "pcap-rdmasniff.h"
#endif
+#ifdef PCAP_SUPPORT_DPDK
+#include "pcap-dpdk.h"
+#endif
+
#ifdef _WIN32
/*
* DllMain(), required when built as a Windows DLL.
#endif
#ifdef PCAP_SUPPORT_RDMASNIFF
{ rdmasniff_findalldevs, rdmasniff_create },
+#endif
+#ifdef PCAP_SUPPORT_DPDK
+ { pcap_dpdk_findalldevs, pcap_dpdk_create },
#endif
{ NULL, NULL }
};
* 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__
* 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;
}
#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);
*
* 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.
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 *
* 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 *
void
pcap_breakloop(pcap_t *p)
{
- p->break_loop = 1;
+ p->breakloop_op(p);
}
int
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
};
* 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);
}
* 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);
}
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));
/*
* "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;
}
}
+void
+pcap_breakloop_common(pcap_t *p)
+{
+ p->break_loop = 1;
+}
+
+
void
pcap_cleanup_live_common(pcap_t *p)
{
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);
}
* - 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:
*
* 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.
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);
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@
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
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)
#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 */
{
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
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;
};
// 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);
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;
#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)
{
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;
}
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;
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);
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;
{
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;
{
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);
}
#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)
{
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;
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;
}
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;
}
// 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);
* 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);
+ }
#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
#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()
" 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"
#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.
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.
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);
}
/*!
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;
}
* '-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
* 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;
}
(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;
}
#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.
#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 */
+
/*
* \}
*/
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);