Merge remote-tracking branch 'microsoft/master'

* microsoft/master: (71 commits)
  Clang formatting
  Mask ports before inserting them into the map
  Fix compiler warning from applied patch
  Remove statistics plugin in favor of stats bif
  Add EventHandler version of stats plugin
  Mark a few EventHandler methods const
  Changed implementation from std::map to std::unordered_map of Val.cc
  Removed const, Windows build is now working
  Added fixes suggested in PR
  Update src/packet_analysis/protocol/ip/IP.cc
  Apply suggestions from code review
  Clang format again but now with v13.0.1
  Rewrote usages of define(_MSC_VER) to ifdef _MSC_VER
  Clang format it all
  Fixed initial CR comments
  Add NEWS entry about Windows port
  Add a couple of extra unistd.h includes to fix a build failure
  Use std::chrono instead of gettimeofday
  Update libkqueue submodule [nomail]
  Don't call tokenize_string if the input string is empty
  ...
This commit is contained in:
Tim Wojtulewicz 2022-11-11 15:13:47 -07:00
commit a8fc63e182
86 changed files with 1001 additions and 261 deletions

View file

@ -357,3 +357,23 @@ ubsan_sanitizer_task:
# CXXFLAGS: -DZEEK_DICT_DEBUG # CXXFLAGS: -DZEEK_DICT_DEBUG
# ZEEK_CI_CONFIGURE_FLAGS: *TSAN_SANITIZER_CONFIG # ZEEK_CI_CONFIGURE_FLAGS: *TSAN_SANITIZER_CONFIG
# ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 # ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1
windows_task:
# 2 hour timeout just for potential of building Docker image taking a while
timeout_in: 120m
windows_container:
# image: cirrusci/windowsservercore:cmake
# image: zeekurity/broker-ci-windows:latest
dockerfile: ci/windows/Dockerfile
os_version: 2019
cpu: 8
# Not allowed to request less than 8GB for an 8 CPU Windows VM.
memory: 8GB
sync_submodules_script: git submodule update --recursive --init
prepare_script: ci/windows/prepare.cmd
build_script: ci/windows/build.cmd
test_script: ci/windows/test.cmd
env:
ZEEK_CI_CPUS: 8
# Give verbose error output on a test failure.
CTEST_OUTPUT_ON_FAILURE: 1

10
.gitignore vendored
View file

@ -1,6 +1,7 @@
# Ignore anything prefixed with build since people # Ignore anything prefixed with build since people
# tend to name all of their build directories prefixed that way. # tend to name all of their build directories prefixed that way.
build* build*
!ci/windows/build.cmd
tmp tmp
*.gcov *.gcov
@ -17,3 +18,12 @@ cmake-build-*
# clangd # clangd
.cache .cache
out/
# Visual Studio
.vs/
.vscode/
CMakeSettings.json
src/include

3
.gitmodules vendored
View file

@ -70,3 +70,6 @@
[submodule "auxil/zeek-af_packet-plugin"] [submodule "auxil/zeek-af_packet-plugin"]
path = auxil/zeek-af_packet-plugin path = auxil/zeek-af_packet-plugin
url = https://github.com/zeek/zeek-af_packet-plugin.git url = https://github.com/zeek/zeek-af_packet-plugin.git
[submodule "auxil/libunistd"]
path = auxil/libunistd
url = https://github.com/zeek/libunistd

View file

@ -1,3 +1,7 @@
5.2.0-dev.307 | 2022-11-11 15:13:47 -0700
* Merged support for Microsoft Windows (Tomer Lev, Elad Solomon, Microsoft)
5.2.0-dev.234 | 2022-11-11 12:48:20 -0700 5.2.0-dev.234 | 2022-11-11 12:48:20 -0700
* Spelling src (Josh Soref) * Spelling src (Josh Soref)

View file

@ -2,9 +2,110 @@
# auxil/zeek-aux/plugin-support/skeleton/CMakeLists.txt # auxil/zeek-aux/plugin-support/skeleton/CMakeLists.txt
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
if ( WIN32 )
# Enable usage of CMAKE_MSVC_RUNTIME_LIBRARY variable
cmake_policy(SET CMP0091 NEW)
endif()
project(Zeek C CXX) project(Zeek C CXX)
option(ZEEK_STANDALONE "Is Zeek compiled stand-alone or embedded in a parent project." ON)
option(ENABLE_ZEEK_UNIT_TESTS "Should the doctest unit tests be built?" ON)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
# Windows: Configure runtime and dependencies
if ( MSVC )
# Remove existing runtime flags
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REGEX REPLACE "[/|-]MDd" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]MD" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]MTd" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]MT" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]Zi" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]W3" "" ${CompilerFlag} "${${CompilerFlag}}")
string(REGEX REPLACE "[/|-]W4" "" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
# Set compilation flags for Windows
add_compile_options(
/guard:cf # required by CheckCFlags
/Z7) # required by CheckCFlags
add_link_options(
/debug:full # required by CheckCFlags
)
# Set always to static runtime
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug")
set(CMAKE_MSVC_RUNTIME_LIBRARY_FLAG "MTd")
else ()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_MSVC_RUNTIME_LIBRARY_FLAG "MT")
endif ()
set(OPENSSL_USE_STATIC_LIBS true)
set(OPENSSL_MSVC_STATIC_RT true)
if ( ZEEK_STANDALONE )
include(${CMAKE_SOURCE_DIR}/cmake/conan.cmake)
conan_cmake_autodetect(settings)
# Install packages from conanfile
conan_cmake_install(PATH_OR_REFERENCE ${CMAKE_SOURCE_DIR}/ci/windows/conanfile_windows.txt
BUILD missing
SETTINGS ${settings})
endif()
# Set LibPCAP to point to libpcap binaries.
find_package(libpcap)
set(PCAP_ROOT_DIR "${libpcap_LIB_DIRS}/../")
set(PCAP_INCLUDE_DIR ${libpcap_INCLUDES})
set(PCAP_LIBRARY ${libpcap_LIBS})
set(LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER false)
# Set ZLib to point at the right variable.
find_package(ZLIB)
set(ZLIB_LIBRARY ${ZLIB_LIBRARIES})
# Set CAres
find_package(c-ares)
set(HAVE_CARES true) # Disable FindCAres cmake file
include_directories(BEFORE ${c-ares_INCLUDE_DIRS})
set(zeekdeps ${zeekdeps} ${c-ares_LIBRARIES})
add_definitions(-DCARES_STATICLIB)
add_subdirectory(auxil/libunistd)
set(UNISTD_INCLUDES ${CMAKE_SOURCE_DIR}/auxil/libunistd/unistd ${CMAKE_SOURCE_DIR}/auxil/libunistd/regex)
include_directories(BEFORE ${UNISTD_INCLUDES})
# Required for `check_include_files` to operate correctly
list(APPEND CMAKE_REQUIRED_INCLUDES ${UNISTD_INCLUDES})
list(APPEND zeekdeps libunistd libregex)
# Set CMAKE flags for supported windows build.
set(DISABLE_PYTHON_BINDINGS true)
set(BROKER_DISABLE_TESTS true)
set(BROKER_DISABLE_DOC_EXAMPLES true)
add_definitions(-DDOCTEST_CONFIG_NO_MULTITHREADING)
# Disable Spicy as it is not yet supported in Windows.
set(DISABLE_SPICY true)
else ()
include(GNUInstallDirs) include(GNUInstallDirs)
endif ()
include(cmake/CommonCMakeConfig.cmake) include(cmake/CommonCMakeConfig.cmake)
include(cmake/FindClangTidy.cmake) include(cmake/FindClangTidy.cmake)
@ -65,6 +166,21 @@ else ()
CACHE STRING "Installation path for plugins" FORCE) CACHE STRING "Installation path for plugins" FORCE)
endif() endif()
set(bro_plugin_install_path "${BRO_PLUGIN_INSTALL_PATH}")
set(cmake_binary_dir "${CMAKE_BINARY_DIR}")
set(cmake_current_binary_dir "${CMAKE_CURRENT_BINARY_DIR}")
set(cmake_install_prefix "${CMAKE_INSTALL_PREFIX}")
set(cmake_source_dir "${CMAKE_SOURCE_DIR}")
set(zeek_script_install_path "${ZEEK_SCRIPT_INSTALL_PATH}")
if ( MSVC )
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" bro_plugin_install_path "${bro_plugin_install_path}")
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" cmake_binary_dir "${cmake_binary_dir}")
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" cmake_current_binary_dir "${cmake_current_binary_dir}")
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" cmake_install_prefix "${cmake_install_prefix}")
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" cmake_source_dir "${cmake_source_dir}")
string(REGEX REPLACE "^([A-Za-z]):/(.*)" "/\\1/\\2" zeek_script_install_path "${zeek_script_install_path}")
endif ()
if ( NOT ZEEK_ETC_INSTALL_DIR ) if ( NOT ZEEK_ETC_INSTALL_DIR )
set(ZEEK_ETC_INSTALL_DIR ${ZEEK_ROOT_DIR}/etc) set(ZEEK_ETC_INSTALL_DIR ${ZEEK_ROOT_DIR}/etc)
endif () endif ()
@ -81,6 +197,10 @@ if ( NOT ZEEK_LOG_DIR )
set(ZEEK_LOG_DIR ${ZEEK_ROOT_DIR}/logs) set(ZEEK_LOG_DIR ${ZEEK_ROOT_DIR}/logs)
endif () endif ()
if ( NOT MSVC )
set(HAVE_SUPERVISOR true)
endif ()
install(DIRECTORY DESTINATION ${ZEEK_ETC_INSTALL_DIR}) install(DIRECTORY DESTINATION ${ZEEK_ETC_INSTALL_DIR})
install(DIRECTORY DESTINATION ${ZEEK_STATE_DIR}) install(DIRECTORY DESTINATION ${ZEEK_STATE_DIR})
install(DIRECTORY DESTINATION ${ZEEK_SPOOL_DIR}) install(DIRECTORY DESTINATION ${ZEEK_SPOOL_DIR})
@ -300,7 +420,9 @@ FindRequiredPackage(FLEX)
FindRequiredPackage(BISON) FindRequiredPackage(BISON)
FindRequiredPackage(PCAP) FindRequiredPackage(PCAP)
FindRequiredPackage(OpenSSL) FindRequiredPackage(OpenSSL)
if ( NOT MSVC )
FindRequiredPackage(BIND) FindRequiredPackage(BIND)
endif ()
FindRequiredPackage(ZLIB) FindRequiredPackage(ZLIB)
# Installation directory for the distribution's Python modules. An # Installation directory for the distribution's Python modules. An
@ -325,6 +447,9 @@ set(PY_MOD_INSTALL_DIR ${py_mod_install_dir}
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/auxil/binpac/CMakeLists.txt) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/auxil/binpac/CMakeLists.txt)
set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY}) set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY})
if ( MSVC )
set(BUILD_STATIC_BINPAC true)
endif()
if ( BUILD_STATIC_BINPAC ) if ( BUILD_STATIC_BINPAC )
set(ENABLE_STATIC_ONLY true) set(ENABLE_STATIC_ONLY true)
@ -381,6 +506,11 @@ if ( PYTHON_VERSION_STRING VERSION_LESS ${ZEEK_PYTHON_MIN} )
endif () endif ()
add_subdirectory(auxil/paraglob) add_subdirectory(auxil/paraglob)
if ( MSVC )
cmake_policy(SET CMP0079 NEW)
target_link_libraries(paraglob shlwapi)
set(BROKER_DISABLE_TOOLS true)
endif ()
set(zeekdeps ${zeekdeps} paraglob) set(zeekdeps ${zeekdeps} paraglob)
if ( Broker_ROOT ) if ( Broker_ROOT )
@ -397,6 +527,9 @@ else ()
endif () endif ()
set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY}) set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY})
if ( MSVC )
set(BUILD_STATIC_BROKER true)
endif()
if ( BUILD_STATIC_BROKER ) if ( BUILD_STATIC_BROKER )
set(ENABLE_STATIC_ONLY true) set(ENABLE_STATIC_ONLY true)
@ -599,7 +732,12 @@ if ( ${CMAKE_SYSTEM_NAME} MATCHES Linux )
endif () endif ()
endif () endif ()
set(DEFAULT_ZEEKPATH .:${ZEEK_SCRIPT_INSTALL_PATH}:${ZEEK_SCRIPT_INSTALL_PATH}/policy:${ZEEK_SCRIPT_INSTALL_PATH}/site:${ZEEK_SCRIPT_INSTALL_PATH}/builtin-plugins) set(DEFAULT_ZEEKPATH_PATHS . ${ZEEK_SCRIPT_INSTALL_PATH} ${ZEEK_SCRIPT_INSTALL_PATH}/policy ${ZEEK_SCRIPT_INSTALL_PATH}/site ${ZEEK_SCRIPT_INSTALL_PATH}/builtin-plugins)
if ( MSVC )
list(JOIN DEFAULT_ZEEKPATH_PATHS ";" DEFAULT_ZEEKPATH)
else ()
list(JOIN DEFAULT_ZEEKPATH_PATHS ":" DEFAULT_ZEEKPATH)
endif ()
if ( NOT BINARY_PACKAGING_MODE ) if ( NOT BINARY_PACKAGING_MODE )
set(ZEEK_DIST ${PROJECT_SOURCE_DIR}) set(ZEEK_DIST ${PROJECT_SOURCE_DIR})
@ -653,11 +791,13 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake DESTINATION share/zeek
USE_SOURCE_PERMISSIONS USE_SOURCE_PERMISSIONS
PATTERN ".git" EXCLUDE) PATTERN ".git" EXCLUDE)
if ( NOT MSVC )
# Install wrapper script for Bro-to-Zeek renaming. # Install wrapper script for Bro-to-Zeek renaming.
include(InstallShellScript) include(InstallShellScript)
include(InstallSymlink) include(InstallSymlink)
InstallShellScript("bin" "zeek-wrapper.in" "zeek-wrapper") InstallShellScript("bin" "zeek-wrapper.in" "zeek-wrapper")
InstallSymlink("${CMAKE_INSTALL_PREFIX}/bin/zeek-wrapper" "${CMAKE_INSTALL_PREFIX}/bin/bro-config") InstallSymlink("${CMAKE_INSTALL_PREFIX}/bin/zeek-wrapper" "${CMAKE_INSTALL_PREFIX}/bin/bro-config")
endif ()
######################################################################## ########################################################################
## zkg configuration ## zkg configuration

View file

@ -754,3 +754,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
==============================================================================
%%% auxil/libunistd
==============================================================================
The MIT License (MIT)
Copyright (c) 2015 Robin Rowe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

11
NEWS
View file

@ -23,6 +23,17 @@ Breaking Changes
New Functionality New Functionality
----------------- -----------------
- Experimental support added for building and running Zeek on Microsoft Windows
environments. This is considered experimental due to the fact that our
standard testing setup (btest) doesn't run properly on Windows. This will be
fixed in the future. In the meantime we have done some basic testing against
builds done with Visual Studio 2019. Information on how to build on Windows is
available in the Zeek documentation. Note also that Spicy is currently
unsupported and will be fixed in the future.
The Zeek team wants to give a huge thank you to the team at Microsoft for all
of their effort in completing this port.
- New ``analyzer_confirmation_info`` and ``analyzer_violation_info`` - New ``analyzer_confirmation_info`` and ``analyzer_violation_info``
events with accompanying record types ``AnalyzerConfirmationInfo`` events with accompanying record types ``AnalyzerConfirmationInfo``
and ``AnalyzerViolationInfo`` have been added. These supersede and ``AnalyzerViolationInfo`` have been added. These supersede

View file

@ -1 +1 @@
5.2.0-dev.234 5.2.0-dev.307

1
auxil/libunistd Submodule

@ -0,0 +1 @@
Subproject commit 2c290dc3c7c9c706b5c0abbe06158bfb8a2721fe

View file

@ -14,6 +14,7 @@ PATHS=$PATHS:@CMAKE_BINARY_DIR@
PATHS=$PATHS:@CMAKE_BINARY_DIR@/src PATHS=$PATHS:@CMAKE_BINARY_DIR@/src
PATHS=$PATHS:@CMAKE_BINARY_DIR@/src/include PATHS=$PATHS:@CMAKE_BINARY_DIR@/src/include
PATHS=$PATHS:@CMAKE_SOURCE_DIR@/src PATHS=$PATHS:@CMAKE_SOURCE_DIR@/src
PATHS=$PATHS:@CMAKE_SOURCE_DIR@/src/include
PATHS=$PATHS:@CMAKE_SOURCE_DIR@/auxil/broker/include/ PATHS=$PATHS:@CMAKE_SOURCE_DIR@/auxil/broker/include/
echo $PATHS echo $PATHS

30
ci/windows/Dockerfile Normal file
View file

@ -0,0 +1,30 @@
# escape=`
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019
SHELL [ "powershell" ]
RUN Set-ExecutionPolicy Unrestricted -Force
# Install Chocolatey
RUN [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; `
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
# Install prerequisites
RUN choco install -y --no-progress visualstudio2019buildtools --version=16.11.11.0
RUN choco install -y --no-progress visualstudio2019-workload-vctools --version=1.0.0 --package-parameters '--add Microsoft.VisualStudio.Component.VC.ATLMFC'
RUN choco install -y --no-progress conan
RUN choco install -y --no-progress sed
RUN choco install -y --no-progress winflexbison3
RUN choco install -y --no-progress msysgit
RUN choco install -y --no-progress python
RUN choco install -y --no-progress openssl
# Set working environment.
SHELL [ "cmd", "/c" ]
RUN setx /M PATH "%PATH%;C:\\Program Files\\Git\\bin"
RUN setx /M CONAN_SKIP_BROKEN_SYMLINKS_CHECK 1
RUN mkdir C:\build
WORKDIR C:\build
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "-arch=x64", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Unrestricted"]

11
ci/windows/build.cmd Normal file
View file

@ -0,0 +1,11 @@
:: Import the visual studio compiler environment into the one running in the
:: cmd current shell. This path is hard coded to the one on the CI image, but
:: can be adjusted if running builds locally. Unfortunately, the initial path
:: isn't in the environment so we have to hardcode the whole path.
call "c:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
mkdir build
cd build
cmake.exe .. -DCMAKE_BUILD_TYPE=release -DENABLE_ZEEK_UNIT_TESTS=yes -G Ninja
cmake.exe --build .

View file

@ -0,0 +1,8 @@
[requires]
zlib/1.2.11
libpcap/1.10.1
c-ares/1.18.1
[generators]
cmake_find_package
cmake

7
ci/windows/prepare.cmd Normal file
View file

@ -0,0 +1,7 @@
@echo on
echo %ZEEK_CI_CPUS%
wmic cpu get NumberOfCores, NumberOfLogicalProcessors/Format:List
systeminfo
dir C:
choco list --localonly

7
ci/windows/test.cmd Normal file
View file

@ -0,0 +1,7 @@
:: See build.cmd for documentation on this call.
call "c:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
:: We currently don't have any tests to run on Windows, so this is just commented out.
:: We'll expand on this later.
:: cd build
:: ctest -C release || exit \b 1

View file

@ -792,6 +792,17 @@ type ReporterStats: record {
weirds_by_type: table[string] of count; weirds_by_type: table[string] of count;
}; };
## Statistics about how many times each event name is queued.
##
## .. zeek:see:: get_event_handler_call_counts
type EventNameCounter: record {
## Name of the zeek event.
name: string &log;
## Times it was queued, as captured by event hook.
times_queued: count &log;
} &log;
type EventNameStats: vector of EventNameCounter;
## Table type used to map variable names to their memory allocation. ## Table type used to map variable names to their memory allocation.
## ##
## .. todo:: We need this type definition only for declaring builtin functions ## .. todo:: We need this type definition only for declaring builtin functions

View file

@ -1,9 +1,18 @@
include_directories(BEFORE include_directories(BEFORE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include
) )
# Force creation of includes symlink. This can't just be in the src directory
# because MSVC will end up with an include loop.
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory
"${CMAKE_CURRENT_SOURCE_DIR}/include")
execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink
".."
"${CMAKE_CURRENT_SOURCE_DIR}/include/zeek")
# Allows header file inclusion via zeek/ within the build tree # Allows header file inclusion via zeek/ within the build tree
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory
"${CMAKE_CURRENT_BINARY_DIR}/include") "${CMAKE_CURRENT_BINARY_DIR}/include")
@ -31,9 +40,9 @@ configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h)
# - deletes instances of 'extern char.*getenv' in inFile # - deletes instances of 'extern char.*getenv' in inFile
# - writes results to outFile and adds it to list TRANSFORMED_BISON_OUTPUTS # - writes results to outFile and adds it to list TRANSFORMED_BISON_OUTPUTS
macro(REPLACE_YY_PREFIX_TARGET inFile outFile yylexPrefix yyPrefix) macro(REPLACE_YY_PREFIX_TARGET inFile outFile yylexPrefix yyPrefix)
set(args "'/extern char.*getenv/d") set(args "\"/extern char.*getenv/d")
set(args "${args}\;s/yylex/${yylexPrefix}lex/") set(args "${args}\;s/yylex/${yylexPrefix}lex/")
set(args "${args}\;s/yy/${yyPrefix}/g'" < ${inFile} > ${outFile}) set(args "${args}\;s/yy/${yyPrefix}/g\"" < ${inFile} > ${outFile})
add_custom_command(OUTPUT ${outFile} add_custom_command(OUTPUT ${outFile}
COMMAND ${SED_EXE} COMMAND ${SED_EXE}
ARGS ${args} ARGS ${args}
@ -48,6 +57,12 @@ endmacro(REPLACE_YY_PREFIX_TARGET)
set(BISON_FLAGS "--debug") set(BISON_FLAGS "--debug")
if ( MSVC )
set(SIGN_COMPARE_FLAG "/wd4018")
else()
set(SIGN_COMPARE_FLAG "-Wno-sign-compare")
endif()
# BIF parser/scanner # BIF parser/scanner
bison_target(BIFParser builtin-func.y bison_target(BIFParser builtin-func.y
${CMAKE_CURRENT_BINARY_DIR}/bif_parse.cc ${CMAKE_CURRENT_BINARY_DIR}/bif_parse.cc
@ -56,7 +71,7 @@ bison_target(BIFParser builtin-func.y
COMPILE_FLAGS "${BISON_FLAGS}") COMPILE_FLAGS "${BISON_FLAGS}")
flex_target(BIFScanner builtin-func.l ${CMAKE_CURRENT_BINARY_DIR}/bif_lex.cc) flex_target(BIFScanner builtin-func.l ${CMAKE_CURRENT_BINARY_DIR}/bif_lex.cc)
add_flex_bison_dependency(BIFScanner BIFParser) add_flex_bison_dependency(BIFScanner BIFParser)
set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare") set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "${SIGN_COMPARE_FLAG}")
# Rule parser/scanner # Rule parser/scanner
bison_target(RuleParser rule-parse.y bison_target(RuleParser rule-parse.y
@ -72,7 +87,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rup.h
rules_ rules_) rules_ rules_)
flex_target(RuleScanner rule-scan.l ${CMAKE_CURRENT_BINARY_DIR}/rule-scan.cc flex_target(RuleScanner rule-scan.l ${CMAKE_CURRENT_BINARY_DIR}/rule-scan.cc
COMPILE_FLAGS "-Prules_") COMPILE_FLAGS "-Prules_")
set_property(SOURCE rule-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare") set_property(SOURCE rule-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "${SIGN_COMPARE_FLAG}")
# RE parser/scanner # RE parser/scanner
bison_target(REParser re-parse.y bison_target(REParser re-parse.y
@ -86,7 +101,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rep.cc
flex_target(REScanner re-scan.l ${CMAKE_CURRENT_BINARY_DIR}/re-scan.cc flex_target(REScanner re-scan.l ${CMAKE_CURRENT_BINARY_DIR}/re-scan.cc
COMPILE_FLAGS "-Pre_") COMPILE_FLAGS "-Pre_")
add_flex_bison_dependency(REScanner REParser) add_flex_bison_dependency(REScanner REParser)
set_property(SOURCE re-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare") set_property(SOURCE re-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "${SIGN_COMPARE_FLAG}")
# Parser/Scanner # Parser/Scanner
bison_target(Parser parse.y bison_target(Parser parse.y
@ -99,13 +114,15 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/p.cc
zeek yy) zeek yy)
flex_target(Scanner scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.cc flex_target(Scanner scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.cc
COMPILE_FLAGS "-Pzeek") COMPILE_FLAGS "-Pzeek")
set_property(SOURCE scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare") set_property(SOURCE scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "${SIGN_COMPARE_FLAG}")
######################################################################## ########################################################################
## bifcl-dependent targets ## bifcl-dependent targets
include(BifCl) include(BifCl)
set(SUPERVISOR_SRCS supervisor/Supervisor.cc Pipe.cc)
set(BIF_SRCS set(BIF_SRCS
zeek.bif zeek.bif
stats.bif stats.bif
@ -139,9 +156,9 @@ endforeach ()
include(BinPAC) include(BinPAC)
set(BINPAC_AUXSRC set(BINPAC_AUXSRC
${PROJECT_SOURCE_DIR}/src/binpac.pac ${CMAKE_CURRENT_SOURCE_DIR}/binpac.pac
${PROJECT_SOURCE_DIR}/src/zeek.pac ${CMAKE_CURRENT_SOURCE_DIR}/zeek.pac
${PROJECT_SOURCE_DIR}/src/binpac_zeek.h ${CMAKE_CURRENT_SOURCE_DIR}/binpac_zeek.h
) )
binpac_target(binpac-lib.pac) binpac_target(binpac-lib.pac)
@ -163,6 +180,8 @@ gen_zam_target(${GEN_ZAM_SRC})
## Including subdirectories. ## Including subdirectories.
######################################################################## ########################################################################
option(USE_SQLITE "Should Zeek use SQLite?" ON)
set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE) set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE)
set(bro_SUBDIR_DEPS CACHE INTERNAL "subdir dependencies" FORCE) set(bro_SUBDIR_DEPS CACHE INTERNAL "subdir dependencies" FORCE)
set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE) set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE)
@ -258,6 +277,11 @@ set(_gen_zeek_script_cpp ${CMAKE_CURRENT_BINARY_DIR}/../CPP-gen.cc)
add_custom_command(OUTPUT ${_gen_zeek_script_cpp} add_custom_command(OUTPUT ${_gen_zeek_script_cpp}
COMMAND ${CMAKE_COMMAND} -E touch ${_gen_zeek_script_cpp}) COMMAND ${CMAKE_COMMAND} -E touch ${_gen_zeek_script_cpp})
if (!MSVC)
set_source_files_properties(legacy-netvar-init.cc PROPERTIES COMPILE_FLAGS
-Wno-deprecated-declarations)
endif()
set(MAIN_SRCS set(MAIN_SRCS
digest.cc digest.cc
net_util.cc net_util.cc
@ -311,7 +335,6 @@ set(MAIN_SRCS
Options.cc Options.cc
Overflow.cc Overflow.cc
PacketFilter.cc PacketFilter.cc
Pipe.cc
PolicyFile.cc PolicyFile.cc
PrefixTable.cc PrefixTable.cc
PriorityQueue.cc PriorityQueue.cc
@ -346,7 +369,7 @@ set(MAIN_SRCS
ZeekString.cc ZeekString.cc
ZVal.cc ZVal.cc
supervisor/Supervisor.cc ${SUPERVISOR_SRCS}
threading/BasicThread.cc threading/BasicThread.cc
threading/Formatter.cc threading/Formatter.cc
@ -422,7 +445,7 @@ set(THIRD_PARTY_SRCS
3rdparty/modp_numtoa.c 3rdparty/modp_numtoa.c
3rdparty/patricia.c 3rdparty/patricia.c
3rdparty/setsignal.c 3rdparty/setsignal.c
3rdparty/sqlite3.c $<$<BOOL:USE_SQLITE>:3rdparty/sqlite3.c>
3rdparty/strsep.c 3rdparty/strsep.c
) )
@ -465,10 +488,19 @@ elseif (${COMPILER_ARCHITECTURE} STREQUAL "power")
../auxil/highwayhash/highwayhash/hh_vsx.cc ../auxil/highwayhash/highwayhash/hh_vsx.cc
) )
elseif(${COMPILER_ARCHITECTURE} STREQUAL "x86_64") elseif(${COMPILER_ARCHITECTURE} STREQUAL "x86_64")
if (MSVC)
set(_avx_flag /arch:AVX2)
# Using an undocumentd compiler flag: https://stackoverflow.com/questions/64053597/how-do-i-enable-sse4-1-and-sse3-but-not-avx-in-msvc/69328426#69328426
set(_sse_flag /d2archSSE42)
else()
set(_avx_flag -mavx2)
set(_sse_flag -msse4.1)
endif()
set_source_files_properties(../auxil/highwayhash/highwayhash/hh_avx2.cc PROPERTIES COMPILE_FLAGS set_source_files_properties(../auxil/highwayhash/highwayhash/hh_avx2.cc PROPERTIES COMPILE_FLAGS
-mavx2) ${_avx_flag})
set_source_files_properties(../auxil/highwayhash/highwayhash/hh_sse41.cc PROPERTIES COMPILE_FLAGS set_source_files_properties(../auxil/highwayhash/highwayhash/hh_sse41.cc PROPERTIES COMPILE_FLAGS
-msse4.1) ${_sse_flag})
list(APPEND HH_SRCS list(APPEND HH_SRCS
../auxil/highwayhash/highwayhash/hh_avx2.cc ../auxil/highwayhash/highwayhash/hh_avx2.cc
@ -504,6 +536,7 @@ collect_headers(zeek_HEADERS ${zeek_SRCS})
add_library(zeek_objs OBJECT ${zeek_SRCS}) add_library(zeek_objs OBJECT ${zeek_SRCS})
if (ZEEK_STANDALONE)
add_executable(zeek main.cc add_executable(zeek main.cc
$<TARGET_OBJECTS:zeek_objs> $<TARGET_OBJECTS:zeek_objs>
${zeek_HEADERS} ${zeek_HEADERS}
@ -511,16 +544,50 @@ add_executable(zeek main.cc
${bro_PLUGIN_LIBS} ${bro_PLUGIN_LIBS}
) )
target_link_libraries(zeek ${bro_PLUGIN_LINK_LIBS} ${zeekdeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) target_link_libraries(zeek ${bro_PLUGIN_LINK_LIBS} ${zeekdeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
# Export symbols from zeek executable for use by plugins # Export symbols from zeek executable for use by plugins
set_target_properties(zeek PROPERTIES ENABLE_EXPORTS TRUE) set_target_properties(zeek PROPERTIES ENABLE_EXPORTS TRUE)
install(TARGETS zeek DESTINATION bin) if ( MSVC )
set(WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif ()
install(TARGETS zeek RUNTIME DESTINATION bin)
set(BRO_EXE zeek set(BRO_EXE zeek
CACHE STRING "Zeek executable binary" FORCE) CACHE STRING "Zeek executable binary" FORCE)
set(BRO_EXE_PATH ${CMAKE_CURRENT_BINARY_DIR}/zeek set(BRO_EXE_PATH ${CMAKE_CURRENT_BINARY_DIR}/zeek
CACHE STRING "Path to Zeek executable binary" FORCE) CACHE STRING "Path to Zeek executable binary" FORCE)
endif()
if (NOT ZEEK_STANDALONE OR CONAN_EXPORTED)
add_library(libzeek STATIC $<TARGET_OBJECTS:zeek_objs>
${zeek_HEADERS}
${bro_SUBDIR_LIBS}
${bro_PLUGIN_LIBS})
target_link_libraries(libzeek PUBLIC ${zeekdeps}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
${bro_SUBDIR_LIBS}
${bro_PLUGIN_LIBS})
target_include_directories(libzeek PUBLIC
${CMAKE_SOURCE_DIR}/zeek/src
${CMAKE_SOURCE_DIR}/zeek/src/include
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}/zeek/src
${CMAKE_BINARY_DIR}/zeek/src/include)
install(TARGETS libzeek LIBRARY DESTINATION lib)
endif()
if ( NOT WIN32 )
# Install wrapper script for Bro-to-Zeek renaming.
include(InstallSymlink)
InstallSymlink("${CMAKE_INSTALL_PREFIX}/bin/zeek-wrapper" "${CMAKE_INSTALL_PREFIX}/bin/bro")
endif ()
# Target to create all the autogenerated files. # Target to create all the autogenerated files.
add_custom_target(generate_outputs_stage1) add_custom_target(generate_outputs_stage1)
@ -567,7 +634,15 @@ install(CODE "
# Make sure to escape a bunch of special characters in the path before trying to use it as a # Make sure to escape a bunch of special characters in the path before trying to use it as a
# regular expression below. # regular expression below.
string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" escaped_path "${CMAKE_CURRENT_SOURCE_DIR}/zeek") string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" escaped_include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/*")
if (WIN32)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/windows/usr.include/
DESTINATION include/
FILES_MATCHING
PATTERN "*.h"
)
endif()
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION include/zeek DESTINATION include/zeek
@ -576,7 +651,7 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
PATTERN "*.pac" PATTERN "*.pac"
PATTERN "3rdparty/*" EXCLUDE PATTERN "3rdparty/*" EXCLUDE
# The "zeek -> ." symlink isn't needed in the install-tree # The "zeek -> ." symlink isn't needed in the install-tree
REGEX "^${escaped_path}$" EXCLUDE REGEX "${escaped_include_path}$" EXCLUDE
# FILES_MATCHING creates empty directories: # FILES_MATCHING creates empty directories:
# https://gitlab.kitware.com/cmake/cmake/-/issues/17122 # https://gitlab.kitware.com/cmake/cmake/-/issues/17122
@ -592,6 +667,8 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
PATTERN "*.bif.netvar_h" PATTERN "*.bif.netvar_h"
PATTERN "*.bif.h" PATTERN "*.bif.h"
PATTERN "CMakeFiles" EXCLUDE PATTERN "CMakeFiles" EXCLUDE
# The "include/zeek -> .." symlink isn't needed in the install-tree
REGEX "${escaped_include_path}$" EXCLUDE
) )
install(FILES install(FILES
@ -602,7 +679,7 @@ install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/modp_numtoa.h ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/modp_numtoa.h
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/patricia.h ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/patricia.h
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/setsignal.h ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/setsignal.h
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/sqlite3.h $<$<BOOL:USE_SQLITE>:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/sqlite3.h>
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/doctest.h ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/doctest.h
DESTINATION include/zeek/3rdparty DESTINATION include/zeek/3rdparty
) )

View file

@ -296,6 +296,9 @@ TEST_CASE("dns_mapping init addr")
TEST_CASE("dns_mapping save reload") TEST_CASE("dns_mapping save reload")
{ {
// TODO: this test uses fmemopen and mkdtemp, both of which aren't available on
// Windows. We'll have to figure out another way to do this test there.
#ifndef _MSC_VER
IPAddr addr("1.2.3.4"); IPAddr addr("1.2.3.4");
in4_addr in4; in4_addr in4;
addr.CopyIPv4(&in4); addr.CopyIPv4(&in4);
@ -356,6 +359,7 @@ TEST_CASE("dns_mapping save reload")
CHECK(svh->ToStdString() == "testing.home"); CHECK(svh->ToStdString() == "testing.home");
delete[] he.h_name; delete[] he.h_name;
#endif
} }
TEST_CASE("dns_mapping multiple addresses") TEST_CASE("dns_mapping multiple addresses")

View file

@ -540,10 +540,10 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in
* some source of data (either a host file or a DNS server). This indicates that we're * some source of data (either a host file or a DNS server). This indicates that we're
* able to do lookups against c-ares now and should activate the IOSource. * able to do lookups against c-ares now and should activate the IOSource.
*/ */
static void sock_cb(void* data, int s, int read, int write) static void sock_cb(void* data, ares_socket_t s, int read, int write)
{ {
auto mgr = reinterpret_cast<DNS_Mgr*>(data); auto mgr = reinterpret_cast<DNS_Mgr*>(data);
mgr->RegisterSocket(s, read == 1, write == 1); mgr->RegisterSocket((int)s, read == 1, write == 1);
} }
DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) : IOSource(true), mode(arg_mode) DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) : IOSource(true), mode(arg_mode)
@ -1613,6 +1613,8 @@ void TestDNS_Mgr::Process()
TEST_CASE("dns_mgr priming" * doctest::skip(true)) TEST_CASE("dns_mgr priming" * doctest::skip(true))
{ {
// TODO: This test uses mkdtemp, which isn't available on Windows.
#ifndef _MSC_VER
char prefix[] = "/tmp/zeek-unit-test-XXXXXX"; char prefix[] = "/tmp/zeek-unit-test-XXXXXX";
auto tmpdir = mkdtemp(prefix); auto tmpdir = mkdtemp(prefix);
@ -1658,6 +1660,7 @@ TEST_CASE("dns_mgr priming" * doctest::skip(true))
// Clean up cache file and the temp directory // Clean up cache file and the temp directory
unlink(mgr2.CacheFile().c_str()); unlink(mgr2.CacheFile().c_str());
rmdir(tmpdir); rmdir(tmpdir);
#endif
} }
TEST_CASE("dns_mgr alternate server" * doctest::skip(true)) TEST_CASE("dns_mgr alternate server" * doctest::skip(true))

View file

@ -1,6 +1,6 @@
// This invalid entry should always be first // This invalid entry should always be first
cmd: dcInvalid cmd: dcInvalid
names: names: _
resume: false resume: false
help: This function should not be called help: This function should not be called
repeatable: false repeatable: false

View file

@ -13,17 +13,17 @@
#include "zeek/util.h" #include "zeek/util.h"
#define DBG_LOG(stream, args...) \ #define DBG_LOG(stream, ...) \
if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \ if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args) ::zeek::detail::debug_logger.Log(stream, __VA_ARGS__)
#define DBG_LOG_VERBOSE(stream, args...) \ #define DBG_LOG_VERBOSE(stream, ...) \
if ( ::zeek::detail::debug_logger.IsVerbose() && \ if ( ::zeek::detail::debug_logger.IsVerbose() && \
::zeek::detail::debug_logger.IsEnabled(stream) ) \ ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args) ::zeek::detail::debug_logger.Log(stream, __VA_ARGS__)
#define DBG_PUSH(stream) ::zeek::detail::debug_logger.PushIndent(stream) #define DBG_PUSH(stream) ::zeek::detail::debug_logger.PushIndent(stream)
#define DBG_POP(stream) ::zeek::detail::debug_logger.PopIndent(stream) #define DBG_POP(stream) ::zeek::detail::debug_logger.PopIndent(stream)
#define PLUGIN_DBG_LOG(plugin, args...) ::zeek::detail::debug_logger.Log(plugin, args) #define PLUGIN_DBG_LOG(plugin, ...) ::zeek::detail::debug_logger.Log(plugin, __VA_ARGS__)
namespace zeek namespace zeek
{ {
@ -123,9 +123,9 @@ extern DebugLogger debug_logger;
} // namespace zeek } // namespace zeek
#else #else
#define DBG_LOG(args...) #define DBG_LOG(...)
#define DBG_LOG_VERBOSE(args...) #define DBG_LOG_VERBOSE(...)
#define DBG_PUSH(stream) #define DBG_PUSH(stream)
#define DBG_POP(stream) #define DBG_POP(stream)
#define PLUGIN_DBG_LOG(plugin, args...) #define PLUGIN_DBG_LOG(plugin, ...)
#endif #endif

View file

@ -52,6 +52,8 @@ void EventHandler::SetFunc(FuncPtr f)
void EventHandler::Call(Args* vl, bool no_remote) void EventHandler::Call(Args* vl, bool no_remote)
{ {
call_count++;
if ( new_event ) if ( new_event )
NewEvent(vl); NewEvent(vl);

View file

@ -38,19 +38,21 @@ public:
explicit operator bool() const; explicit operator bool() const;
void SetUsed() { used = true; } void SetUsed() { used = true; }
bool Used() { return used; } bool Used() const { return used; }
// Handlers marked as error handlers will not be called recursively to // Handlers marked as error handlers will not be called recursively to
// avoid infinite loops if they trigger a similar error themselves. // avoid infinite loops if they trigger a similar error themselves.
void SetErrorHandler() { error_handler = true; } void SetErrorHandler() { error_handler = true; }
bool ErrorHandler() { return error_handler; } bool ErrorHandler() const { return error_handler; }
void SetEnable(bool arg_enable) { enabled = arg_enable; } void SetEnable(bool arg_enable) { enabled = arg_enable; }
// Flags the event as interesting even if there is no body defined. In // Flags the event as interesting even if there is no body defined. In
// particular, this will then still pass the event on to plugins. // particular, this will then still pass the event on to plugins.
void SetGenerateAlways() { generate_always = true; } void SetGenerateAlways() { generate_always = true; }
bool GenerateAlways() { return generate_always; } bool GenerateAlways() const { return generate_always; }
uint64_t CallCount() const { return call_count; }
private: private:
void NewEvent(zeek::Args* vl); // Raise new_event() meta event. void NewEvent(zeek::Args* vl); // Raise new_event() meta event.
@ -62,6 +64,7 @@ private:
bool enabled; bool enabled;
bool error_handler; // this handler reports error messages. bool error_handler; // this handler reports error messages.
bool generate_always; bool generate_always;
uint64_t call_count = 0;
std::unordered_set<std::string> auto_publish; std::unordered_set<std::string> auto_publish;
}; };

View file

@ -202,8 +202,16 @@ void File::SetBuf(bool arg_buffered)
if ( ! f ) if ( ! f )
return; return;
#ifndef _MSC_VER
if ( setvbuf(f, NULL, arg_buffered ? _IOFBF : _IOLBF, 0) != 0 ) if ( setvbuf(f, NULL, arg_buffered ? _IOFBF : _IOLBF, 0) != 0 )
reporter->Error("setvbuf failed"); reporter->Error("setvbuf failed");
#else
// TODO: this turns off buffering altogether because Windows wants us to pass a valid
// buffer and length if we're going to pass one of the other modes. We need to
// investigate the performance ramifications of this.
if ( setvbuf(f, NULL, _IONBF, 0) != 0 )
reporter->Error("setvbuf failed");
#endif
buffered = arg_buffered; buffered = arg_buffered;
} }

View file

@ -8,10 +8,61 @@
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#ifdef _MSC_VER
#include <winsock2.h>
#define fatalError(...) \
do \
{ \
if ( reporter ) \
reporter->FatalError(__VA_ARGS__); \
else \
{ \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
_exit(1); \
} \
} while ( 0 )
#endif
namespace zeek::detail namespace zeek::detail
{ {
Flare::Flare() : pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK) { } Flare::Flare()
#ifndef _MSC_VER
: pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK)
{
}
#else
{
WSADATA wsaData;
if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0 )
fatalError("WSAStartup failure: %d", WSAGetLastError());
recvfd = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if ( recvfd == (int)INVALID_SOCKET )
fatalError("WSASocket failure: %d", WSAGetLastError());
sendfd = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if ( sendfd == (int)INVALID_SOCKET )
fatalError("WSASocket failure: %d", WSAGetLastError());
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
if ( bind(recvfd, (sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR )
fatalError("bind failure: %d", WSAGetLastError());
int salen = sizeof(sa);
if ( getsockname(recvfd, (sockaddr*)&sa, &salen) == SOCKET_ERROR )
fatalError("getsockname failure: %d", WSAGetLastError());
if ( connect(sendfd, (sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR )
fatalError("connect failure: %d", WSAGetLastError());
}
#endif
[[noreturn]] static void bad_pipe_op(const char* which, bool signal_safe) [[noreturn]] static void bad_pipe_op(const char* which, bool signal_safe)
{ {
@ -36,14 +87,22 @@ void Flare::Fire(bool signal_safe)
for ( ;; ) for ( ;; )
{ {
#ifndef _MSC_VER
int n = write(pipe.WriteFD(), &tmp, 1); int n = write(pipe.WriteFD(), &tmp, 1);
#else
int n = send(sendfd, &tmp, 1, 0);
#endif
if ( n > 0 ) if ( n > 0 )
// Success -- wrote a byte to pipe. // Success -- wrote a byte to pipe.
break; break;
if ( n < 0 ) if ( n < 0 )
{ {
#ifdef _MSC_VER
errno = WSAGetLastError();
bad_pipe_op("send", signal_safe);
#endif
if ( errno == EAGAIN ) if ( errno == EAGAIN )
// Success: pipe is full and just need at least one byte in it. // Success: pipe is full and just need at least one byte in it.
break; break;
@ -66,15 +125,23 @@ int Flare::Extinguish(bool signal_safe)
for ( ;; ) for ( ;; )
{ {
#ifndef _MSC_VER
int n = read(pipe.ReadFD(), &tmp, sizeof(tmp)); int n = read(pipe.ReadFD(), &tmp, sizeof(tmp));
#else
int n = recv(recvfd, tmp, sizeof(tmp), 0);
#endif
if ( n >= 0 ) if ( n >= 0 )
{ {
rval += n; rval += n;
// Pipe may not be empty yet: try again. // Pipe may not be empty yet: try again.
continue; continue;
} }
#ifdef _MSC_VER
if ( WSAGetLastError() == WSAEWOULDBLOCK )
break;
errno = WSAGetLastError();
bad_pipe_op("recv", signal_safe);
#endif
if ( errno == EAGAIN ) if ( errno == EAGAIN )
// Success: pipe is now empty. // Success: pipe is now empty.
break; break;

View file

@ -2,7 +2,9 @@
#pragma once #pragma once
#include "zeek/Pipe.h" #ifndef _MSC_VER
#include "Pipe.h"
#endif
namespace zeek::detail namespace zeek::detail
{ {
@ -22,7 +24,16 @@ public:
* @return a file descriptor that will become ready if the flare has been * @return a file descriptor that will become ready if the flare has been
* Fire()'d and not yet Extinguished()'d. * Fire()'d and not yet Extinguished()'d.
*/ */
int FD() const { return pipe.ReadFD(); } int FD() const
#ifndef _MSC_VER
{
return pipe.ReadFD();
}
#else
{
return recvfd;
}
#endif
/** /**
* Put the object in the "ready" state. * Put the object in the "ready" state.
@ -41,7 +52,11 @@ public:
int Extinguish(bool signal_safe = false); int Extinguish(bool signal_safe = false);
private: private:
#ifndef _MSC_VER
Pipe pipe; Pipe pipe;
#else
int sendfd, recvfd;
#endif
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -345,7 +345,7 @@ void HashKey::Reserve(const char* tag, size_t addl_size, size_t alignment)
void HashKey::Allocate() void HashKey::Allocate()
{ {
if ( key != nullptr and key != reinterpret_cast<char*>(&key_u) ) if ( key != nullptr && key != reinterpret_cast<char*>(&key_u) )
{ {
reporter->InternalWarning("usage error in HashKey::Allocate(): already allocated"); reporter->InternalWarning("usage error in HashKey::Allocate(): already allocated");
return; return;

View file

@ -19,6 +19,7 @@
#pragma once #pragma once
#include <unistd.h>
#include <cstdlib> #include <cstdlib>
#include "zeek/util.h" // for zeek_int_t #include "zeek/util.h" // for zeek_int_t

View file

@ -66,8 +66,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr"); static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr");
rv = make_intrusive<RecordVal>(ip6_hdr_type); rv = make_intrusive<RecordVal>(ip6_hdr_type);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data;
rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20); rv->Assign(0, static_cast<uint32_t>(ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20);
rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff); rv->Assign(1, static_cast<uint32_t>(ntohl(ip6->ip6_flow) & 0x000fffff));
rv->Assign(2, ntohs(ip6->ip6_plen)); rv->Assign(2, ntohs(ip6->ip6_plen));
rv->Assign(3, ip6->ip6_nxt); rv->Assign(3, ip6->ip6_nxt);
rv->Assign(4, ip6->ip6_hlim); rv->Assign(4, ip6->ip6_hlim);
@ -127,7 +127,7 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3); rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3);
rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1); rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1);
rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001)); rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001));
rv->Assign(5, ntohl(frag->ip6f_ident)); rv->Assign(5, static_cast<uint32_t>(ntohl(frag->ip6f_ident)));
} }
break; break;
@ -138,13 +138,13 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt); rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt);
rv->Assign(1, ((ip6_ext*)data)->ip6e_len); rv->Assign(1, ((ip6_ext*)data)->ip6e_len);
rv->Assign(2, ntohs(((uint16_t*)data)[1])); rv->Assign(2, ntohs(((uint16_t*)data)[1]));
rv->Assign(3, ntohl(((uint32_t*)data)[1])); rv->Assign(3, static_cast<uint32_t>(ntohl(((uint32_t*)data)[1])));
if ( Length() >= 12 ) if ( Length() >= 12 )
{ {
// Sequence Number and ICV fields can only be extracted if // Sequence Number and ICV fields can only be extracted if
// Payload Len was non-zero for this header. // Payload Len was non-zero for this header.
rv->Assign(4, ntohl(((uint32_t*)data)[2])); rv->Assign(4, static_cast<uint32_t>(ntohl(((uint32_t*)data)[2])));
uint16_t off = 3 * sizeof(uint32_t); uint16_t off = 3 * sizeof(uint32_t);
rv->Assign(5, new String(data + off, Length() - off, true)); rv->Assign(5, new String(data + off, Length() - off, true));
} }
@ -156,8 +156,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
static auto ip6_esp_type = id::find_type<RecordType>("ip6_esp"); static auto ip6_esp_type = id::find_type<RecordType>("ip6_esp");
rv = make_intrusive<RecordVal>(ip6_esp_type); rv = make_intrusive<RecordVal>(ip6_esp_type);
const uint32_t* esp = (const uint32_t*)data; const uint32_t* esp = (const uint32_t*)data;
rv->Assign(0, ntohl(esp[0])); rv->Assign(0, static_cast<uint32_t>(ntohl(esp[0])));
rv->Assign(1, ntohl(esp[1])); rv->Assign(1, static_cast<uint32_t>(ntohl(esp[1])));
} }
break; break;
@ -401,8 +401,8 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP)); tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP)); tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(2, ntohl(tp->th_seq)); tcp_hdr->Assign(2, static_cast<uint32_t>(ntohl(tp->th_seq)));
tcp_hdr->Assign(3, ntohl(tp->th_ack)); tcp_hdr->Assign(3, static_cast<uint32_t>(ntohl(tp->th_ack)));
tcp_hdr->Assign(4, tcp_hdr_len); tcp_hdr->Assign(4, tcp_hdr_len);
tcp_hdr->Assign(5, data_len); tcp_hdr->Assign(5, data_len);
tcp_hdr->Assign(6, tp->th_x2); tcp_hdr->Assign(6, tp->th_x2);

View file

@ -12,6 +12,8 @@
#ifdef HAVE_NETINET_IP6_H #ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h> #include <netinet/ip6.h>
#else
#include "net_util.h" // for struct ip6_hdr
#endif #endif
#include <vector> #include <vector>

View file

@ -6,6 +6,8 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "Obj.h"
namespace zeek namespace zeek
{ {
@ -25,6 +27,12 @@ struct NewRef
{ {
}; };
/**
* This has to be forward declared and known here in order for us to be able
* cast this in the `Unref` function.
*/
class OpaqueVal;
/** /**
* An intrusive, reference counting smart pointer implementation. Much like * An intrusive, reference counting smart pointer implementation. Much like
* @c std::shared_ptr, this smart pointer models shared ownership of an object * @c std::shared_ptr, this smart pointer models shared ownership of an object
@ -111,8 +119,15 @@ public:
~IntrusivePtr() ~IntrusivePtr()
{ {
if ( ptr_ ) if ( ptr_ )
{
// Specializing `OpaqueVal` as MSVC compiler does not detect it
// inheriting from `zeek::Obj` so we have to do that manually.
if constexpr ( std::is_same_v<T, OpaqueVal> )
Unref(reinterpret_cast<zeek::Obj*>(ptr_));
else
Unref(ptr_); Unref(ptr_);
} }
}
void swap(IntrusivePtr& other) noexcept { std::swap(ptr_, other.ptr_); } void swap(IntrusivePtr& other) noexcept { std::swap(ptr_, other.ptr_); }

View file

@ -61,10 +61,14 @@ Obj::~Obj()
{ {
if ( notify_plugins ) if ( notify_plugins )
{ {
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
PLUGIN_HOOK_VOID(HOOK_BRO_OBJ_DTOR, HookBroObjDtor(this)); PLUGIN_HOOK_VOID(HOOK_BRO_OBJ_DTOR, HookBroObjDtor(this));
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
PLUGIN_HOOK_VOID(HOOK_OBJ_DTOR, HookObjDtor(this)); PLUGIN_HOOK_VOID(HOOK_OBJ_DTOR, HookObjDtor(this));
} }

View file

@ -2,6 +2,10 @@
#pragma once #pragma once
#ifdef _MSC_VER
#include <unistd.h>
#endif
#include <broker/expected.hh> #include <broker/expected.hh>
#if ( OPENSSL_VERSION_NUMBER < 0x30000000L ) || defined(LIBRESSL_VERSION_NUMBER) #if ( OPENSSL_VERSION_NUMBER < 0x30000000L ) || defined(LIBRESSL_VERSION_NUMBER)
#include <openssl/md5.h> #include <openssl/md5.h>

View file

@ -4,17 +4,17 @@
#include "zeek/zeek-config.h" #include "zeek/zeek-config.h"
#include <unistd.h> #if defined(HAVE_GETOPT_H) && ! defined(_MSC_VER)
#ifdef HAVE_GETOPT_H
#include <getopt.h> #include <getopt.h>
#endif #endif
#include <unistd.h>
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <sstream> #include <sstream>
#include "zeek/3rdparty/bsd-getopt-long.h"
#include "zeek/ScriptProfile.h" #include "zeek/ScriptProfile.h"
#include "zeek/logging/writers/ascii/Ascii.h" #include "zeek/logging/writers/ascii/Ascii.h"
#include "zeek/script_opt/ScriptOpt.h" #include "zeek/script_opt/ScriptOpt.h"

View file

@ -117,9 +117,10 @@ bool LoadPolicyFileText(const char* policy_filename,
// ### This code is not necessarily Unicode safe! // ### This code is not necessarily Unicode safe!
// (probably fine with UTF-8) // (probably fine with UTF-8)
pf->filedata = new char[size + 1]; pf->filedata = new char[size + 1];
if ( fread(pf->filedata, size, 1, f) != 1 ) size_t n = fread(pf->filedata, 1, size, f);
if ( ferror(f) )
reporter->InternalError("Failed to fread() file data"); reporter->InternalError("Failed to fread() file data");
pf->filedata[size] = 0; pf->filedata[n] = 0;
fclose(f); fclose(f);
} }

View file

@ -40,10 +40,12 @@ extern "C"
#include "zeek/plugin/Manager.h" #include "zeek/plugin/Manager.h"
#include "zeek/session/Manager.h" #include "zeek/session/Manager.h"
#ifndef _MSC_VER
extern "C" extern "C"
{ {
extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*); extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
} }
#endif
static double last_watchdog_proc_time = 0.0; // value of above during last watchdog static double last_watchdog_proc_time = 0.0; // value of above during last watchdog
extern int signal_val; extern int signal_val;

View file

@ -102,7 +102,7 @@ ScriptProfileMgr::~ScriptProfileMgr()
auto& fp = fs.second; auto& fp = fs.second;
auto n = func->GetBodies().size(); auto n = func->GetBodies().size();
if ( n > 1 ) if ( n > 1 )
fprintf(f, "%s\t%lu-locations\t%s\t%d\t%.06f\t%0.6f\t%" PRIu64 "\t%lld\n", fprintf(f, "%s\t%zu-locations\t%s\t%d\t%.06f\t%0.6f\t%" PRIu64 "\t%lld\n",
fp.Name().c_str(), n, func->GetType()->FlavorString().c_str(), fp.NumCalls(), fp.Name().c_str(), n, func->GetType()->FlavorString().c_str(), fp.NumCalls(),
fp.CPUTime(), 0.0, fp.Memory(), 0LL); fp.CPUTime(), 0.0, fp.Memory(), 0LL);
} }

View file

@ -85,7 +85,7 @@ private:
bool NextStmtIsValid() { return stmt_depths[STMT_FOR] > 0 || stmt_depths[STMT_WHILE] > 0; } bool NextStmtIsValid() { return stmt_depths[STMT_FOR] > 0 || stmt_depths[STMT_WHILE] > 0; }
std::unordered_map<const StmtTag, int> stmt_depths; std::unordered_map<StmtTag, int> stmt_depths;
int hook_depth = 0; int hook_depth = 0;
}; };

View file

@ -386,7 +386,7 @@ bool BinarySerializationFormat::Write(const IPAddr& addr, const char* tag)
for ( int i = 0; i < n; ++i ) for ( int i = 0; i < n; ++i )
{ {
if ( ! Write(ntohl(raw[i]), "addr-part") ) if ( ! Write(static_cast<uint32_t>(ntohl(raw[i])), "addr-part") )
return false; return false;
} }
@ -402,7 +402,7 @@ bool BinarySerializationFormat::Write(const struct in_addr& addr, const char* ta
{ {
const uint32_t* bytes = (uint32_t*)&addr.s_addr; const uint32_t* bytes = (uint32_t*)&addr.s_addr;
if ( ! Write(ntohl(bytes[0]), "addr4") ) if ( ! Write(static_cast<uint32_t>(ntohl(bytes[0])), "addr4") )
return false; return false;
return true; return true;
@ -414,7 +414,7 @@ bool BinarySerializationFormat::Write(const struct in6_addr& addr, const char* t
for ( int i = 0; i < 4; ++i ) for ( int i = 0; i < 4; ++i )
{ {
if ( ! Write(ntohl(bytes[i]), "addr6-part") ) if ( ! Write(static_cast<uint32_t>(ntohl(bytes[i])), "addr6-part") )
return false; return false;
} }

View file

@ -3962,18 +3962,9 @@ ValManager::ValManager()
for ( auto i = 0u; i < PREALLOCATED_INTS; ++i ) for ( auto i = 0u; i < PREALLOCATED_INTS; ++i )
ints[i] = Val::MakeInt(PREALLOCATED_INT_LOWEST + i); ints[i] = Val::MakeInt(PREALLOCATED_INT_LOWEST + i);
for ( auto i = 0u; i < ports.size(); ++i )
{
auto& arr = ports[i];
auto port_type = (TransportProto)i;
for ( auto j = 0u; j < arr.size(); ++j )
arr[j] = IntrusivePtr{AdoptRef{}, new PortVal(PortVal::Mask(j, port_type))};
}
} }
const PortValPtr& ValManager::Port(uint32_t port_num, TransportProto port_type) const const PortValPtr& ValManager::Port(uint32_t port_num, TransportProto port_type)
{ {
if ( port_num >= 65536 ) if ( port_num >= 65536 )
{ {
@ -3981,10 +3972,15 @@ const PortValPtr& ValManager::Port(uint32_t port_num, TransportProto port_type)
port_num = 0; port_num = 0;
} }
return ports[port_type][port_num]; uint32_t port_masked = PortVal::Mask(port_num, port_type);
if ( ports.find(port_masked) == ports.end() )
ports[port_masked] = IntrusivePtr{AdoptRef{},
new PortVal(PortVal::Mask(port_num, port_type))};
return ports[port_masked];
} }
const PortValPtr& ValManager::Port(uint32_t port_num) const const PortValPtr& ValManager::Port(uint32_t port_num)
{ {
auto mask = port_num & PORT_SPACE_MASK; auto mask = port_num & PORT_SPACE_MASK;
port_num &= ~PORT_SPACE_MASK; port_num &= ~PORT_SPACE_MASK;

View file

@ -298,9 +298,15 @@ protected:
class ValManager class ValManager
{ {
public: public:
#ifdef _MSC_VER
static constexpr zeek_uint_t PREALLOCATED_COUNTS = 1;
static constexpr zeek_uint_t PREALLOCATED_INTS = 1;
static constexpr zeek_int_t PREALLOCATED_INT_LOWEST = 0;
#else
static constexpr zeek_uint_t PREALLOCATED_COUNTS = 4096; static constexpr zeek_uint_t PREALLOCATED_COUNTS = 4096;
static constexpr zeek_uint_t PREALLOCATED_INTS = 512; static constexpr zeek_uint_t PREALLOCATED_INTS = 512;
static constexpr zeek_int_t PREALLOCATED_INT_LOWEST = -255; static constexpr zeek_int_t PREALLOCATED_INT_LOWEST = -255;
#endif
static constexpr zeek_int_t PREALLOCATED_INT_HIGHEST = PREALLOCATED_INT_LOWEST + static constexpr zeek_int_t PREALLOCATED_INT_HIGHEST = PREALLOCATED_INT_LOWEST +
PREALLOCATED_INTS - 1; PREALLOCATED_INTS - 1;
@ -327,13 +333,13 @@ public:
inline const StringValPtr& EmptyString() const { return empty_string; } inline const StringValPtr& EmptyString() const { return empty_string; }
// Port number given in host order. // Port number given in host order.
const PortValPtr& Port(uint32_t port_num, TransportProto port_type) const; const PortValPtr& Port(uint32_t port_num, TransportProto port_type);
// Host-order port number already masked with port space protocol mask. // Host-order port number already masked with port space protocol mask.
const PortValPtr& Port(uint32_t port_num) const; const PortValPtr& Port(uint32_t port_num);
private: private:
std::array<std::array<PortValPtr, 65536>, NUM_PORT_SPACES> ports; std::unordered_map<uint32_t, PortValPtr> ports;
std::array<ValPtr, PREALLOCATED_COUNTS> counts; std::array<ValPtr, PREALLOCATED_COUNTS> counts;
std::array<ValPtr, PREALLOCATED_INTS> ints; std::array<ValPtr, PREALLOCATED_INTS> ints;
StringValPtr empty_string; StringValPtr empty_string;
@ -1124,15 +1130,18 @@ public:
AddedField(field); AddedField(field);
} }
void Assign(int field, int new_val) // For int types, we provide both [u]int32_t and [u]int64_t versions for
// convenience, since sometimes the caller has one rather than the other.
void Assign(int field, int32_t new_val)
{
(*record_val)[field] = ZVal(zeek_int_t(new_val));
AddedField(field);
}
void Assign(int field, int64_t new_val)
{ {
(*record_val)[field] = ZVal(zeek_int_t(new_val)); (*record_val)[field] = ZVal(zeek_int_t(new_val));
AddedField(field); AddedField(field);
} }
// For unsigned, we provide both uint32_t and uint64_t versions
// for convenience, since sometimes the caller has one rather
// than the other.
void Assign(int field, uint32_t new_val) void Assign(int field, uint32_t new_val)
{ {
(*record_val)[field] = ZVal(zeek_uint_t(new_val)); (*record_val)[field] = ZVal(zeek_uint_t(new_val));

View file

@ -402,12 +402,12 @@ extern analyzer::Manager* analyzer_mgr;
DBG_LOG(zeek::DBG_ANALYZER, "%s " txt, \ DBG_LOG(zeek::DBG_ANALYZER, "%s " txt, \
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), conn->RespAddr(), \ fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), conn->RespAddr(), \
ntohs(conn->RespPort()))); ntohs(conn->RespPort())));
#define DBG_ANALYZER_ARGS(conn, fmt, args...) \ #define DBG_ANALYZER_ARGS(conn, fmt, ...) \
DBG_LOG(zeek::DBG_ANALYZER, "%s " fmt, \ DBG_LOG(zeek::DBG_ANALYZER, "%s " fmt, \
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), conn->RespAddr(), \ fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), conn->RespAddr(), \
ntohs(conn->RespPort())), \ ntohs(conn->RespPort())), \
##args); ##__VA_ARGS__);
#else #else
#define DBG_ANALYZER(conn, txt) #define DBG_ANALYZER(conn, txt)
#define DBG_ANALYZER_ARGS(conn, fmt, args...) #define DBG_ANALYZER_ARGS(conn, fmt, ...)
#endif #endif

View file

@ -823,8 +823,7 @@ bool DNS_Interpreter::ParseRR_EDNS(detail::DNS_MsgInfo* msg, const u_char*& data
case TYPE_TCP_KA: case TYPE_TCP_KA:
{ {
EDNS_TCP_KEEPALIVE edns_tcp_keepalive{.keepalive_timeout_omitted = true, EDNS_TCP_KEEPALIVE edns_tcp_keepalive{true, 0};
.keepalive_timeout = 0};
if ( option_len == 0 || option_len == 2 ) if ( option_len == 0 || option_len == 2 )
{ {
// 0 bytes is permitted by RFC 7828, showing that the timeout value is // 0 bytes is permitted by RFC 7828, showing that the timeout value is
@ -1736,11 +1735,8 @@ bool DNS_Interpreter::ParseRR_SVCB(detail::DNS_MsgInfo* msg, const u_char*& data
name_end = target_name + 1; name_end = target_name + 1;
} }
SVCB_DATA svcb_data = { SVCB_DATA svcb_data = {svc_priority, make_intrusive<StringVal>(new String(
.svc_priority = svc_priority, target_name, name_end - target_name, true))};
.target_name = make_intrusive<StringVal>(
new String(target_name, name_end - target_name, true)),
};
// TODO: parse svcparams // TODO: parse svcparams
// we consume all the remaining raw data (svc params) but do nothing. // we consume all the remaining raw data (svc params) but do nothing.

View file

@ -3,7 +3,7 @@
module FileExtract; module FileExtract;
%%{ %%{
#include "zeek/zeek/file_analysis/Manager.h" #include "zeek/file_analysis/Manager.h"
#include "zeek/file_analysis/file_analysis.bif.h" #include "zeek/file_analysis/file_analysis.bif.h"
%%} %%}

View file

@ -279,7 +279,7 @@ void X509Common::ParseExtension(X509_EXTENSION* ex, const EventHandlerPtr& h, bo
auto pX509Ext = make_intrusive<RecordVal>(BifType::Record::X509::Extension); auto pX509Ext = make_intrusive<RecordVal>(BifType::Record::X509::Extension);
pX509Ext->Assign(0, name); pX509Ext->Assign(0, name);
if ( short_name and strlen(short_name) > 0 ) if ( short_name && strlen(short_name) > 0 )
pX509Ext->Assign(1, short_name); pX509Ext->Assign(1, short_name);
pX509Ext->Assign(2, oid); pX509Ext->Assign(2, oid);

View file

@ -1 +0,0 @@
../../../analyzer/protocol/ssl/tls-handshake-signed_certificate_timestamp.pac

View file

@ -0,0 +1 @@
%include ../../../analyzer/protocol/ssl/tls-handshake-signed_certificate_timestamp.pac

View file

@ -4,6 +4,10 @@
#include "zeek/fuzzers/FuzzBuffer.h" #include "zeek/fuzzers/FuzzBuffer.h"
#ifdef _MSC_VER
#include <mem.h>
#endif
#include <cstring> #include <cstring>
namespace zeek::detail namespace zeek::detail

View file

@ -1,3 +1,7 @@
#ifdef _MSC_VER
#include <unistd.h>
#endif
extern "C" extern "C"
{ {
#include <pcap.h> #include <pcap.h>

1
src/include/.gitkeep Normal file
View file

@ -0,0 +1 @@

View file

@ -4,4 +4,6 @@ add_subdirectory(benchmark)
add_subdirectory(binary) add_subdirectory(binary)
add_subdirectory(config) add_subdirectory(config)
add_subdirectory(raw) add_subdirectory(raw)
if (USE_SQLITE)
add_subdirectory(sqlite) add_subdirectory(sqlite)
endif()

View file

@ -4,6 +4,11 @@
#include "zeek/zeek-config.h" #include "zeek/zeek-config.h"
// clang-format off
// Include order is required here for a working build on Windows.
#include <unistd.h>
#include <sys/socket.h>
// clang-format on
#include <cstring> #include <cstring>
#include "zeek/util.h" #include "zeek/util.h"

View file

@ -11,6 +11,8 @@
using pkt_timeval = bpf_timeval; using pkt_timeval = bpf_timeval;
#else #else
using pkt_timeval = struct timeval; using pkt_timeval = struct timeval;
#include <sys/socket.h>
#include <sys/time.h>
#endif #endif
#include <pcap.h> // For DLT_ constants #include <pcap.h> // For DLT_ constants

View file

@ -107,7 +107,7 @@ bool PcapDumper::Dump(const Packet* pkt)
return false; return false;
// Reconstitute the pcap_pkthdr. // Reconstitute the pcap_pkthdr.
const struct pcap_pkthdr phdr = {.ts = pkt->ts, .caplen = pkt->cap_len, .len = pkt->len}; const struct pcap_pkthdr phdr = {pkt->ts, pkt->cap_len, pkt->len};
pcap_dump((u_char*)dumper, &phdr, pkt->data); pcap_dump((u_char*)dumper, &phdr, pkt->data);
pcap_dump_flush(dumper); pcap_dump_flush(dumper);

View file

@ -2,6 +2,8 @@
#pragma once #pragma once
#include <unistd.h>
extern "C" extern "C"
{ {
#include <pcap.h> #include <pcap.h>

View file

@ -160,7 +160,9 @@ void PcapSource::OpenLive()
Info(util::fmt("pcap bufsize = %d\n", ((struct pcap*)pd)->bufsize)); Info(util::fmt("pcap bufsize = %d\n", ((struct pcap*)pd)->bufsize));
#endif #endif
#ifndef _MSC_VER
props.selectable_fd = pcap_get_selectable_fd(pd); props.selectable_fd = pcap_get_selectable_fd(pd);
#endif
props.link_type = pcap_datalink(pd); props.link_type = pcap_datalink(pd);
props.is_live = true; props.is_live = true;

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <sys/types.h> // for u_char #include <sys/types.h> // for u_char
#include <unistd.h>
extern "C" extern "C"
{ {

View file

@ -1,4 +1,6 @@
add_subdirectory(ascii) add_subdirectory(ascii)
add_subdirectory(none) add_subdirectory(none)
if (USE_SQLITE)
add_subdirectory(sqlite) add_subdirectory(sqlite)
endif()

View file

@ -88,7 +88,7 @@ struct LeftoverLog
* Return the "path" (logging framework parlance) of the log without the * Return the "path" (logging framework parlance) of the log without the
* directory or file extension. E.g. the "path" of "logs/conn.log" is just "conn". * directory or file extension. E.g. the "path" of "logs/conn.log" is just "conn".
*/ */
std::string Path() const { return zeek::filesystem::path(filename).stem(); } std::string Path() const { return zeek::filesystem::path(filename).stem().string(); }
/** /**
* Deletes the shadow file and returns whether it succeeded. * Deletes the shadow file and returns whether it succeeded.
@ -110,12 +110,13 @@ static std::string prefix_basename_with(const std::string& path, const std::stri
TEST_CASE("writers.ascii prefix_basename_with") TEST_CASE("writers.ascii prefix_basename_with")
{ {
CHECK(prefix_basename_with("", ".shadow.") == ".shadow."); #ifdef _MSC_VER
CHECK(prefix_basename_with("conn.log", ".shadow.") == ".shadow.conn.log"); // TODO: adapt this test to Windows paths
CHECK(prefix_basename_with("/conn.log", ".shadow.") == "/.shadow.conn.log"); #else
CHECK(prefix_basename_with("a/conn.log", ".shadow.") == "a/.shadow.conn.log"); CHECK(prefix_basename_with("a/conn.log", ".shadow.") == "a/.shadow.conn.log");
CHECK(prefix_basename_with("/a/conn.log", ".shadow.") == "/a/.shadow.conn.log"); CHECK(prefix_basename_with("/a/conn.log", ".shadow.") == "/a/.shadow.conn.log");
CHECK(prefix_basename_with("a/b/conn.log", ".shadow.") == "a/b/.shadow.conn.log"); CHECK(prefix_basename_with("a/b/conn.log", ".shadow.") == "a/b/.shadow.conn.log");
#endif
} }
static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname) static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
@ -493,7 +494,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
} }
if ( fname.front() != '/' && ! logdir.empty() ) if ( fname.front() != '/' && ! logdir.empty() )
fname = zeek::filesystem::path(logdir) / fname; fname = (zeek::filesystem::path(logdir) / fname).string();
fname += ext; fname += ext;
@ -773,7 +774,7 @@ static std::vector<LeftoverLog> find_leftover_logs()
if ( BifConst::LogAscii::logdir->Len() > 0 ) if ( BifConst::LogAscii::logdir->Len() > 0 )
logdir = zeek::filesystem::absolute(BifConst::LogAscii::logdir->ToStdString()); logdir = zeek::filesystem::absolute(BifConst::LogAscii::logdir->ToStdString());
auto d = opendir(logdir.c_str()); auto d = opendir(logdir.string().c_str());
struct dirent* dp; struct dirent* dp;
if ( ! d ) if ( ! d )
@ -788,8 +789,8 @@ static std::vector<LeftoverLog> find_leftover_logs()
if ( strncmp(dp->d_name, shadow_file_prefix, prefix_len) != 0 ) if ( strncmp(dp->d_name, shadow_file_prefix, prefix_len) != 0 )
continue; continue;
std::string shadow_fname = logdir / dp->d_name; std::string shadow_fname = (logdir / dp->d_name).string();
std::string log_fname = logdir / (dp->d_name + prefix_len); std::string log_fname = (logdir / (dp->d_name + prefix_len)).string();
if ( util::is_file(log_fname) ) if ( util::is_file(log_fname) )
{ {
@ -909,17 +910,12 @@ string Ascii::Timestamp(double t)
time_t teatime = time_t(t); time_t teatime = time_t(t);
if ( ! teatime ) if ( ! teatime )
{ teatime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
// Use wall clock.
struct timeval tv;
if ( gettimeofday(&tv, 0) < 0 )
Error("gettimeofday failed");
else
teatime = tv.tv_sec;
}
struct tm tmbuf; struct tm tmbuf;
struct tm* tm = localtime_r(&teatime, &tmbuf); struct tm* tm = localtime_r(&teatime, &tmbuf);
if ( tm == nullptr )
Error(util::fmt("localtime_r failed: %s", strerror(errno)));
char tmp[128]; char tmp[128];
const char* const date_fmt = "%Y-%m-%d-%H-%M-%S"; const char* const date_fmt = "%Y-%m-%d-%H-%M-%S";

View file

@ -147,7 +147,7 @@ bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields, const Field* con
tablename = it->second; tablename = it->second;
if ( checkError(sqlite3_open_v2( if ( checkError(sqlite3_open_v2(
fullpath.c_str(), &db, fullpath.string().c_str(), &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL)) ) SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL)) )
return false; return false;

View file

@ -2,13 +2,23 @@
#include "zeek/zeek-config.h" #include "zeek/zeek-config.h"
#include <unistd.h>
#include "zeek/RunState.h" #include "zeek/RunState.h"
#include "zeek/iosource/Manager.h" #include "zeek/iosource/Manager.h"
#include "zeek/supervisor/Supervisor.h" #include "zeek/supervisor/Supervisor.h"
#include "zeek/zeek-setup.h" #include "zeek/zeek-setup.h"
#ifdef _MSC_VER
#include <fcntl.h> // For _O_BINARY.
#endif
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#ifdef _MSC_VER
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
#endif
auto time_start = zeek::util::current_time(true); auto time_start = zeek::util::current_time(true);
auto setup_result = zeek::detail::setup(argc, argv); auto setup_result = zeek::detail::setup(argc, argv);
@ -41,7 +51,6 @@ int main(int argc, char** argv)
zeek::detail::timer_mgr->Add(new zeek::detail::ParentProcessCheckTimer(1, 1)); zeek::detail::timer_mgr->Add(new zeek::detail::ParentProcessCheckTimer(1, 1));
double time_net_start = zeek::util::current_time(true); double time_net_start = zeek::util::current_time(true);
;
uint64_t mem_net_start_total; uint64_t mem_net_start_total;
uint64_t mem_net_start_malloced; uint64_t mem_net_start_malloced;

View file

@ -283,6 +283,7 @@ inline uint64_t htonll(uint64_t i)
#else #else
#ifndef _MSC_VER
inline double ntohd(double d) inline double ntohd(double d)
{ {
assert(sizeof(d) == 8); assert(sizeof(d) == 8);
@ -328,6 +329,7 @@ inline float htonf(float f)
{ {
return ntohf(f); return ntohf(f);
} }
#endif
#ifndef HAVE_BYTEORDER_64 #ifndef HAVE_BYTEORDER_64
inline uint64_t ntohll(uint64_t i) inline uint64_t ntohll(uint64_t i)

View file

@ -94,7 +94,7 @@ bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
auto ah = (const struct arp_pkthdr*)data; auto ah = (const struct arp_pkthdr*)data;
// Check the size. // Check the size.
size_t min_length = (ar_tpa(ah) - (char*)data) + ah->ar_pln; size_t min_length = (ar_tpa(ah) - (caddr_t)data) + ah->ar_pln;
if ( min_length > len ) if ( min_length > len )
{ {
Weird("truncated_ARP", packet); Weird("truncated_ARP", packet);
@ -149,7 +149,7 @@ bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
} }
// Check MAC src address = ARP sender MAC address. // Check MAC src address = ARP sender MAC address.
if ( memcmp(packet->l2_src, ar_sha(ah), ah->ar_hln) != 0 ) if ( memcmp(packet->l2_src, (const char*)ar_sha(ah), ah->ar_hln) != 0 )
{ {
BadARPEvent(ah, "weird-arp-sha"); BadARPEvent(ah, "weird-arp-sha");
return false; return false;
@ -219,9 +219,9 @@ void ARPAnalyzer::BadARPEvent(const struct arp_pkthdr* hdr, const char* fmt, ...
vsnprintf(msg, sizeof(msg), fmt, args); vsnprintf(msg, sizeof(msg), fmt, args);
va_end(args); va_end(args);
event_mgr.Enqueue(bad_arp, ToAddrVal(ar_spa(hdr), hdr->ar_pln), event_mgr.Enqueue(bad_arp, ToAddrVal(reinterpret_cast<const u_char*>(ar_spa(hdr)), hdr->ar_pln),
ToEthAddrStr(reinterpret_cast<const u_char*>(ar_sha(hdr)), hdr->ar_hln), ToEthAddrStr(reinterpret_cast<const u_char*>(ar_sha(hdr)), hdr->ar_hln),
ToAddrVal(ar_tpa(hdr), hdr->ar_pln), ToAddrVal(reinterpret_cast<const u_char*>(ar_tpa(hdr)), hdr->ar_pln),
ToEthAddrStr(reinterpret_cast<const u_char*>(ar_tha(hdr)), hdr->ar_hln), ToEthAddrStr(reinterpret_cast<const u_char*>(ar_tha(hdr)), hdr->ar_hln),
zeek::make_intrusive<zeek::StringVal>(msg)); zeek::make_intrusive<zeek::StringVal>(msg));
} }

View file

@ -62,7 +62,8 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
return false; return false;
} }
ip_hdr = std::make_shared<IP_Hdr>((const struct ip6_hdr*)data, false, len); ip_hdr = std::make_shared<IP_Hdr>((const struct ip6_hdr*)data, false,
static_cast<int>(len));
packet->l3_proto = L3_IPV6; packet->l3_proto = L3_IPV6;
} }
else else

View file

@ -1791,8 +1791,8 @@ int TCPSessionAdapter::ParseTCPOptions(const struct tcphdr* tcp, bool is_orig)
// timestamps // timestamps
if ( length == 10 ) if ( length == 10 )
{ {
auto send = ntohl(*reinterpret_cast<const uint32_t*>(o + 2)); uint32_t send = ntohl(*reinterpret_cast<const uint32_t*>(o + 2));
auto echo = ntohl(*reinterpret_cast<const uint32_t*>(o + 6)); uint32_t echo = ntohl(*reinterpret_cast<const uint32_t*>(o + 6));
option_record->Assign(6, send); option_record->Assign(6, send);
option_record->Assign(7, echo); option_record->Assign(7, echo);
} }
@ -1809,7 +1809,7 @@ int TCPSessionAdapter::ParseTCPOptions(const struct tcphdr* tcp, bool is_orig)
{ {
auto rate = o[2]; auto rate = o[2];
auto ttl_diff = o[3]; auto ttl_diff = o[3];
auto qs_nonce = ntohl(*reinterpret_cast<const uint32_t*>(o + 4)); uint32_t qs_nonce = ntohl(*reinterpret_cast<const uint32_t*>(o + 4));
option_record->Assign(8, rate); option_record->Assign(8, rate);
option_record->Assign(9, ttl_diff); option_record->Assign(9, ttl_diff);
option_record->Assign(10, qs_nonce); option_record->Assign(10, qs_nonce);

View file

@ -3,8 +3,10 @@
#include "zeek/plugin/Manager.h" #include "zeek/plugin/Manager.h"
#include <dirent.h> #include <dirent.h>
#ifndef _MSC_VER
#include <dlfcn.h> #include <dlfcn.h>
#include <glob.h> #include <glob.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <cerrno> #include <cerrno>
#include <climits> // for PATH_MAX #include <climits> // for PATH_MAX
@ -56,13 +58,13 @@ void Manager::SearchDynamicPlugins(const std::string& dir)
if ( dir.empty() ) if ( dir.empty() )
return; return;
if ( dir.find(':') != string::npos ) if ( dir.find(path_list_separator) != string::npos )
{ {
// Split at ":". // Split at ":".
std::stringstream s(dir); std::stringstream s(dir);
std::string d; std::string d;
while ( std::getline(s, d, ':') ) while ( std::getline(s, d, path_list_separator[0]) )
SearchDynamicPlugins(d); SearchDynamicPlugins(d);
return; return;
@ -160,6 +162,10 @@ void Manager::SearchDynamicPlugins(const std::string& dir)
bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found, bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found,
std::vector<std::string>* errors) std::vector<std::string>* errors)
{ {
// Loading dynamic plugins is not currently supported on Windows platform.
#ifdef _MSC_VER
return false;
#else
errors->clear(); // caller should pass it in empty, but just to be sure errors->clear(); // caller should pass it in empty, but just to be sure
dynamic_plugin_map::iterator m = dynamic_plugins.find(util::strtolower(name)); dynamic_plugin_map::iterator m = dynamic_plugins.find(util::strtolower(name));
@ -326,6 +332,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
m->second.clear(); m->second.clear();
return true; return true;
#endif
} }
void Manager::ActivateDynamicPlugin(const std::string& name) void Manager::ActivateDynamicPlugin(const std::string& name)
@ -346,14 +353,21 @@ void Manager::ActivateDynamicPlugins(bool all)
// Activate plugins that were specifically requested. // Activate plugins that were specifically requested.
for ( const auto& x : requested_plugins ) for ( const auto& x : requested_plugins )
{
if ( ! x.empty() )
plugins_to_activate.emplace(x, false); plugins_to_activate.emplace(x, false);
}
// Activate plugins that our environment tells us to. // Activate plugins that our environment tells us to.
vector<string> p; vector<string> p;
std::string plugin_activate = util::zeek_plugin_activate();
if ( ! plugin_activate.empty() )
{
util::tokenize_string(util::zeek_plugin_activate(), ",", &p); util::tokenize_string(util::zeek_plugin_activate(), ",", &p);
for ( const auto& x : p ) for ( const auto& x : p )
plugins_to_activate.emplace(x, true); plugins_to_activate.emplace(x, true);
}
if ( all ) if ( all )
{ {
@ -911,32 +925,48 @@ void Manager::HookBroObjDtor(void* obj) const
if ( HavePluginForHook(META_HOOK_PRE) ) if ( HavePluginForHook(META_HOOK_PRE) )
{ {
args.push_back(HookArgument(obj)); args.push_back(HookArgument(obj));
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
MetaHookPre(HOOK_BRO_OBJ_DTOR, args); MetaHookPre(HOOK_BRO_OBJ_DTOR, args);
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
hook_list* l = hooks[HOOK_BRO_OBJ_DTOR]; hook_list* l = hooks[HOOK_BRO_OBJ_DTOR];
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
if ( l ) if ( l )
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i ) for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
{ {
Plugin* p = (*i).second; Plugin* p = (*i).second;
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
p->HookBroObjDtor(obj); p->HookBroObjDtor(obj);
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
if ( HavePluginForHook(META_HOOK_POST) ) if ( HavePluginForHook(META_HOOK_POST) )
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
MetaHookPost(HOOK_BRO_OBJ_DTOR, args, HookArgument()); MetaHookPost(HOOK_BRO_OBJ_DTOR, args, HookArgument());
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
void Manager::HookObjDtor(void* obj) const void Manager::HookObjDtor(void* obj) const

View file

@ -77,7 +77,7 @@ public:
* This must be called only before InitPluginsPreScript(). * This must be called only before InitPluginsPreScript().
* *
* @param dir The directory to search for plugins. Multiple directories * @param dir The directory to search for plugins. Multiple directories
* can be given by splitting them with ':'. * can be given by separating them with zeek::util::path_list_separator.
*/ */
void SearchDynamicPlugins(const std::string& dir); void SearchDynamicPlugins(const std::string& dir);

View file

@ -383,10 +383,14 @@ void Plugin::RequestEvent(EventHandlerPtr handler)
void Plugin::RequestBroObjDtor(Obj* obj) void Plugin::RequestBroObjDtor(Obj* obj)
{ {
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
plugin_mgr->RequestBroObjDtor(obj, this); plugin_mgr->RequestBroObjDtor(obj, this);
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
void Plugin::RequestObjDtor(Obj* obj) void Plugin::RequestObjDtor(Obj* obj)

View file

@ -25,6 +25,10 @@ struct Field;
namespace zeek namespace zeek
{ {
#ifdef _MSC_VER
#undef VOID
#endif
// Increase this when making incompatible changes to the plugin API. Note // Increase this when making incompatible changes to the plugin API. Note
// that the constant is never used in C code. It's picked up on by CMake. // that the constant is never used in C code. It's picked up on by CMake.
constexpr int PLUGIN_API_VERSION = 7; constexpr int PLUGIN_API_VERSION = 7;
@ -116,17 +120,23 @@ public:
// We force this to inline so that the API version gets hardcoded // We force this to inline so that the API version gets hardcoded
// into the external plugin. (Technically, it's not a "force", just a // into the external plugin. (Technically, it's not a "force", just a
// strong hint.). The attribute seems generally available. // strong hint.). The attribute seems generally available.
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
inline Configuration() __attribute__((always_inline)) inline Configuration() __attribute__((always_inline))
{ {
bro_version = ZEEK_PLUGIN_ZEEK_VERSION; bro_version = ZEEK_PLUGIN_ZEEK_VERSION;
zeek_version = ZEEK_PLUGIN_ZEEK_VERSION; zeek_version = ZEEK_PLUGIN_ZEEK_VERSION;
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
Configuration(Configuration&& c) Configuration(Configuration&& c)
{ {
bro_version = std::move(c.bro_version); bro_version = std::move(c.bro_version);
@ -136,10 +146,14 @@ public:
description = std::move(c.description); description = std::move(c.description);
version = std::move(c.version); version = std::move(c.version);
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
Configuration(const Configuration& c) Configuration(const Configuration& c)
{ {
bro_version = c.bro_version; bro_version = c.bro_version;
@ -149,10 +163,14 @@ public:
description = c.description; description = c.description;
version = c.version; version = c.version;
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
Configuration& operator=(Configuration&& c) Configuration& operator=(Configuration&& c)
{ {
bro_version = std::move(c.bro_version); bro_version = std::move(c.bro_version);
@ -164,10 +182,14 @@ public:
return *this; return *this;
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
Configuration& operator=(const Configuration& c) Configuration& operator=(const Configuration& c)
{ {
bro_version = c.bro_version; bro_version = c.bro_version;
@ -179,12 +201,18 @@ public:
return *this; return *this;
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
~Configuration() { } ~Configuration() { }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
/** /**
* One can assign ZEEK_PLUGIN_ZEEK_VERSION to this to catch * One can assign ZEEK_PLUGIN_ZEEK_VERSION to this to catch

View file

@ -28,7 +28,7 @@ void CPP_IndexedInits<T>::Generate(InitsManager* im, std::vector<EnumValPtr>& iv
{ {
auto& e_type = im->Types(init_vals[0]); auto& e_type = im->Types(init_vals[0]);
int val = init_vals[1]; int val = init_vals[1];
ivec[offset] = make_enum__CPP(e_type, val); ivec[offset] = zeek::detail::make_enum__CPP(e_type, val);
} }
template <class T> template <class T>

View file

@ -384,8 +384,10 @@ const ZAMStmt ZAMCompiler::GenCond(const Expr* e, int& branch_v)
// from "ZAM-Conds.h". It really shouldn't worry about indentation mismatches // from "ZAM-Conds.h". It really shouldn't worry about indentation mismatches
// across included files since those are not indicative of possible // across included files since those are not indicative of possible
// logic errors, but Oh Well. // logic errors, but Oh Well.
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmisleading-indentation" #pragma GCC diagnostic ignored "-Wmisleading-indentation"
#endif
switch ( e->Tag() ) switch ( e->Tag() )
{ {
#include "ZAM-Conds.h" #include "ZAM-Conds.h"
@ -393,7 +395,9 @@ const ZAMStmt ZAMCompiler::GenCond(const Expr* e, int& branch_v)
default: default:
reporter->InternalError("bad expression type in ZAMCompiler::GenCond"); reporter->InternalError("bad expression type in ZAMCompiler::GenCond");
} }
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
// Not reached. // Not reached.
} }

View file

@ -484,3 +484,33 @@ function get_reporter_stats%(%): ReporterStats
return r; return r;
%} %}
## Returns a list of event handlers that were called and the number of times
## each was called.
##
## Returns: A record with event call statistics.
##
function get_event_handler_call_counts%(%): EventNameStats
%{
auto rval = zeek::make_intrusive<zeek::VectorVal>(zeek::id::find_type<VectorType>("EventNameStats"));
const auto& recordType = zeek::id::find_type<RecordType>("EventNameCounter");
int i = 0;
const auto& events = event_registry->UsedHandlers();
for ( const auto& name : events )
{
auto handler = event_registry->Lookup(name);
auto call_count = handler->CallCount();
if ( call_count > 0 )
{
auto eventStatRecord = zeek::make_intrusive<zeek::RecordVal>(recordType);
eventStatRecord->Assign(0, zeek::make_intrusive<zeek::StringVal>(name));
eventStatRecord->Assign(1, zeek::val_mgr->Count(handler->CallCount()));
rval->Assign(i, std::move(eventStatRecord));
i++;
}
}
return rval;
%}

View file

@ -41,7 +41,7 @@ extern "C"
#include "zeek/zeek-affinity.h" #include "zeek/zeek-affinity.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG_STEM(args...) stem->LogDebug(args); #define DBG_STEM(...) stem->LogDebug(__VA_ARGS__);
#else #else
#define DBG_STEM #define DBG_STEM
#endif #endif
@ -987,22 +987,24 @@ std::optional<SupervisedNode> Stem::Poll()
const auto total_fd_count = fixed_fd_count + (nodes.size() * 2); const auto total_fd_count = fixed_fd_count + (nodes.size() * 2);
auto pfds = std::make_unique<pollfd[]>(total_fd_count); auto pfds = std::make_unique<pollfd[]>(total_fd_count);
int pfd_idx = 0; int pfd_idx = 0;
pfds[pfd_idx++] = {pipe->InFD(), POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(pipe->InFD()), POLLIN, 0};
pfds[pfd_idx++] = {signal_flare->FD(), POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(signal_flare->FD()), POLLIN, 0};
for ( const auto& [name, node] : nodes ) for ( const auto& [name, node] : nodes )
{ {
node_pollfd_indices[name] = pfd_idx; node_pollfd_indices[name] = pfd_idx;
if ( node.stdout_pipe.pipe ) if ( node.stdout_pipe.pipe )
pfds[pfd_idx++] = {node.stdout_pipe.pipe->ReadFD(), POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(node.stdout_pipe.pipe->ReadFD()),
POLLIN, 0};
else else
pfds[pfd_idx++] = {-1, POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(-1), POLLIN, 0};
if ( node.stderr_pipe.pipe ) if ( node.stderr_pipe.pipe )
pfds[pfd_idx++] = {node.stderr_pipe.pipe->ReadFD(), POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(node.stderr_pipe.pipe->ReadFD()),
POLLIN, 0};
else else
pfds[pfd_idx++] = {-1, POLLIN, 0}; pfds[pfd_idx++] = {static_cast<decltype(pollfd::fd)>(-1), POLLIN, 0};
} }
// Note: the poll timeout here is for periodically checking if the parent // Note: the poll timeout here is for periodically checking if the parent
@ -1249,7 +1251,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
const auto& affinity_val = node->GetField("cpu_affinity"); const auto& affinity_val = node->GetField("cpu_affinity");
if ( affinity_val ) if ( affinity_val )
rval.cpu_affinity = affinity_val->AsInt(); rval.cpu_affinity = static_cast<int>(affinity_val->AsInt());
const auto& bare_mode_val = node->GetField("bare_mode"); const auto& bare_mode_val = node->GetField("bare_mode");
@ -1277,10 +1279,14 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
for ( auto i = 0u; i < scripts_val->Size(); ++i ) for ( auto i = 0u; i < scripts_val->Size(); ++i )
{ {
auto script = scripts_val->StringValAt(i)->ToStdString(); auto script = scripts_val->StringValAt(i)->ToStdString();
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
rval.scripts.emplace_back(std::move(script)); rval.scripts.emplace_back(std::move(script));
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
auto env_table_val = node->GetField("env")->AsTableVal(); auto env_table_val = node->GetField("env")->AsTableVal();
@ -1364,10 +1370,14 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json)
auto& scripts = j["scripts"]; auto& scripts = j["scripts"];
for ( auto it = scripts.Begin(); it != scripts.End(); ++it ) for ( auto it = scripts.Begin(); it != scripts.End(); ++it )
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
rval.scripts.emplace_back(it->GetString()); rval.scripts.emplace_back(it->GetString());
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
auto& env = j["env"]; auto& env = j["env"];
@ -1447,10 +1457,14 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const
auto st = rt->GetFieldType<VectorType>("scripts"); auto st = rt->GetFieldType<VectorType>("scripts");
auto scripts_val = make_intrusive<VectorVal>(std::move(st)); auto scripts_val = make_intrusive<VectorVal>(std::move(st));
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
for ( const auto& s : scripts ) for ( const auto& s : scripts )
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
scripts_val->Assign(scripts_val->Size(), make_intrusive<StringVal>(s)); scripts_val->Assign(scripts_val->Size(), make_intrusive<StringVal>(s));
rval->AssignField("scripts", std::move(scripts_val)); rval->AssignField("scripts", std::move(scripts_val));
@ -1656,10 +1670,14 @@ void SupervisedNode::Init(Options* options) const
stl.insert(stl.begin(), config.addl_base_scripts.begin(), config.addl_base_scripts.end()); stl.insert(stl.begin(), config.addl_base_scripts.begin(), config.addl_base_scripts.end());
stl.insert(stl.end(), config.addl_user_scripts.begin(), config.addl_user_scripts.end()); stl.insert(stl.end(), config.addl_user_scripts.begin(), config.addl_user_scripts.end());
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
stl.insert(stl.end(), config.scripts.begin(), config.scripts.end()); stl.insert(stl.end(), config.scripts.begin(), config.scripts.end());
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
} }
RecordValPtr Supervisor::Status(std::string_view node_name) RecordValPtr Supervisor::Status(std::string_view node_name)

View file

@ -2,6 +2,8 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <sys/types.h> #include <sys/types.h>
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
@ -143,18 +145,26 @@ public:
*/ */
struct NodeConfig struct NodeConfig
{ {
#ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
// This block exists because the default implementations // This block exists because the default implementations
// themselves trigger deprecation warnings for accessing the // themselves trigger deprecation warnings for accessing the
// "scripts" field. It can go when we remove that deprecation. // "scripts" field. It can go when we remove that deprecation.
NodeConfig() = default; NodeConfig() = default;
#ifndef _MSC_VER
// MSVC throws this error when specifing this constructor:
// error C2580: multiple versions of a defaulted special member functions are not allowed
NodeConfig(NodeConfig&) = default; NodeConfig(NodeConfig&) = default;
#endif
NodeConfig(const NodeConfig&) = default; NodeConfig(const NodeConfig&) = default;
NodeConfig(NodeConfig&&) = default; NodeConfig(NodeConfig&&) = default;
~NodeConfig() = default; ~NodeConfig() = default;
NodeConfig& operator=(const NodeConfig&) = default; NodeConfig& operator=(const NodeConfig&) = default;
#ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif
/** /**
* Create configuration from script-layer record value. * Create configuration from script-layer record value.

View file

@ -13,3 +13,4 @@ bif_target(telemetry.bif)
bro_add_subdir_library(telemetry ${telemetry_SRCS}) bro_add_subdir_library(telemetry ${telemetry_SRCS})
add_dependencies(bro_telemetry generate_outputs) add_dependencies(bro_telemetry generate_outputs)

View file

@ -57,7 +57,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same counter. * @return Whether @c this and @p other refer to the same counter.
*/ */
constexpr bool IsSameAs(IntCounter other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const IntCounter& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::int_counter_hdl*; using Handle = broker::telemetry::int_counter_hdl*;
@ -72,13 +72,13 @@ private:
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
* @note compare their @c value instead to check for equality. * @note compare their @c value instead to check for equality.
*/ */
constexpr bool operator==(IntCounter lhs, IntCounter rhs) noexcept constexpr bool operator==(const IntCounter& lhs, const IntCounter& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates IntCounter /// @relates IntCounter
constexpr bool operator!=(IntCounter lhs, IntCounter rhs) noexcept constexpr bool operator!=(const IntCounter& lhs, const IntCounter& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }
@ -155,7 +155,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same counter. * @return Whether @c this and @p other refer to the same counter.
*/ */
constexpr bool IsSameAs(DblCounter other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const DblCounter& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::dbl_counter_hdl*; using Handle = broker::telemetry::dbl_counter_hdl*;
@ -170,13 +170,13 @@ private:
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
* @note compare their @c value instead to check for equality. * @note compare their @c value instead to check for equality.
*/ */
constexpr bool operator==(DblCounter lhs, DblCounter rhs) noexcept constexpr bool operator==(const DblCounter& lhs, const DblCounter& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates DblCounter /// @relates DblCounter
constexpr bool operator!=(DblCounter lhs, DblCounter rhs) noexcept constexpr bool operator!=(const DblCounter& lhs, const DblCounter& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }

View file

@ -73,7 +73,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same counter. * @return Whether @c this and @p other refer to the same counter.
*/ */
constexpr bool IsSameAs(IntGauge other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const IntGauge& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::int_gauge_hdl*; using Handle = broker::telemetry::int_gauge_hdl*;
@ -88,13 +88,13 @@ private:
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
* @note compare their @c value instead to check for equality. * @note compare their @c value instead to check for equality.
*/ */
constexpr bool operator==(IntGauge lhs, IntGauge rhs) noexcept constexpr bool operator==(const IntGauge& lhs, const IntGauge& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates IntGauge /// @relates IntGauge
constexpr bool operator!=(IntGauge lhs, IntGauge rhs) noexcept constexpr bool operator!=(const IntGauge& lhs, const IntGauge& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }
@ -180,7 +180,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same counter. * @return Whether @c this and @p other refer to the same counter.
*/ */
constexpr bool IsSameAs(DblGauge other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const DblGauge& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::dbl_gauge_hdl*; using Handle = broker::telemetry::dbl_gauge_hdl*;
@ -195,13 +195,13 @@ private:
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
* @note compare their @c value instead to check for equality. * @note compare their @c value instead to check for equality.
*/ */
constexpr bool operator==(DblGauge lhs, DblGauge rhs) noexcept constexpr bool operator==(const DblGauge& lhs, const DblGauge& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates DblGauge /// @relates DblGauge
constexpr bool operator!=(DblGauge lhs, DblGauge rhs) noexcept constexpr bool operator!=(const DblGauge& lhs, const DblGauge& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }

View file

@ -60,7 +60,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same histogram. * @return Whether @c this and @p other refer to the same histogram.
*/ */
constexpr bool IsSameAs(IntHistogram other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const IntHistogram& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::int_histogram_hdl*; using Handle = broker::telemetry::int_histogram_hdl*;
@ -74,13 +74,13 @@ private:
* Checks whether two @ref IntHistogram handles are identical. * Checks whether two @ref IntHistogram handles are identical.
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
*/ */
constexpr bool operator==(IntHistogram lhs, IntHistogram rhs) noexcept constexpr bool operator==(const IntHistogram& lhs, const IntHistogram& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates IntHistogram /// @relates IntHistogram
constexpr bool operator!=(IntHistogram lhs, IntHistogram rhs) noexcept constexpr bool operator!=(const IntHistogram& lhs, const IntHistogram& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }
@ -165,7 +165,7 @@ public:
/** /**
* @return Whether @c this and @p other refer to the same histogram. * @return Whether @c this and @p other refer to the same histogram.
*/ */
constexpr bool IsSameAs(DblHistogram other) const noexcept { return hdl == other.hdl; } constexpr bool IsSameAs(const DblHistogram& other) const noexcept { return hdl == other.hdl; }
private: private:
using Handle = broker::telemetry::dbl_histogram_hdl*; using Handle = broker::telemetry::dbl_histogram_hdl*;
@ -179,13 +179,13 @@ private:
* Checks whether two @ref DblHistogram handles are identical. * Checks whether two @ref DblHistogram handles are identical.
* @return Whether @p lhs and @p rhs refer to the same object. * @return Whether @p lhs and @p rhs refer to the same object.
*/ */
constexpr bool operator==(DblHistogram lhs, DblHistogram rhs) noexcept constexpr bool operator==(const DblHistogram& lhs, const DblHistogram& rhs) noexcept
{ {
return lhs.IsSameAs(rhs); return lhs.IsSameAs(rhs);
} }
/// @relates DblHistogram /// @relates DblHistogram
constexpr bool operator!=(DblHistogram lhs, DblHistogram rhs) noexcept constexpr bool operator!=(const DblHistogram& lhs, const DblHistogram& rhs) noexcept
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }

View file

@ -48,9 +48,10 @@ void BasicThread::SetName(const char* arg_name)
void BasicThread::SetOSName(const char* arg_name) void BasicThread::SetOSName(const char* arg_name)
{ {
static_assert(std::is_same<std::thread::native_handle_type, pthread_t>::value, // Do it only if libc++ supports pthread_t.
"libstdc++ doesn't use pthread_t"); if constexpr ( std::is_same<std::thread::native_handle_type, pthread_t>::value )
util::detail::set_thread_name(arg_name, thread.native_handle()); zeek::util::detail::set_thread_name(arg_name,
reinterpret_cast<pthread_t>(thread.native_handle()));
} }
const char* BasicThread::Fmt(const char* format, ...) const char* BasicThread::Fmt(const char* format, ...)
@ -172,10 +173,9 @@ void BasicThread::Done()
void* BasicThread::launcher(void* arg) void* BasicThread::launcher(void* arg)
{ {
static_assert(std::is_same<std::thread::native_handle_type, pthread_t>::value,
"libstdc++ doesn't use pthread_t");
BasicThread* thread = (BasicThread*)arg; BasicThread* thread = (BasicThread*)arg;
#ifndef _MSC_VER
// Block signals in thread. We handle signals only in the main // Block signals in thread. We handle signals only in the main
// process. // process.
sigset_t mask_set; sigset_t mask_set;
@ -190,6 +190,7 @@ void* BasicThread::launcher(void* arg)
sigdelset(&mask_set, SIGBUS); sigdelset(&mask_set, SIGBUS);
int res = pthread_sigmask(SIG_BLOCK, &mask_set, 0); int res = pthread_sigmask(SIG_BLOCK, &mask_set, 0);
assert(res == 0); assert(res == 0);
#endif
// Run thread's main function. // Run thread's main function.
thread->Run(); thread->Run();

View file

@ -3,6 +3,7 @@
#include "zeek/zeek-config.h" #include "zeek/zeek-config.h"
#include <unistd.h>
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
#include <iosfwd> #include <iosfwd>

View file

@ -40,6 +40,7 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <iostream> #include <iostream>
#include <random>
#include <string> #include <string>
#include <vector> #include <vector>
@ -51,6 +52,7 @@
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/RunState.h" #include "zeek/RunState.h"
#include "zeek/ScannedFile.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/digest.h" #include "zeek/digest.h"
#include "zeek/input.h" #include "zeek/input.h"
@ -67,6 +69,7 @@ static bool can_read(const string& path)
} }
static string zeek_path_value; static string zeek_path_value;
const string zeek_path_list_separator(path_list_separator.begin(), path_list_separator.end());
namespace zeek::util namespace zeek::util
{ {
@ -554,7 +557,7 @@ void add_to_zeek_path(const string& dir)
// Make sure path is initialized. // Make sure path is initialized.
zeek_path(); zeek_path();
zeek_path_value += string(":") + dir; zeek_path_value += zeek_path_list_separator + dir;
} }
FILE* open_package(string& path, const string& mode) FILE* open_package(string& path, const string& mode)
@ -596,7 +599,12 @@ void SafePathOp::CheckValid(const char* op_result, const char* path, bool error_
TEST_CASE("util flatten_script_name") TEST_CASE("util flatten_script_name")
{ {
CHECK(flatten_script_name("script", "some/path") == "some.path.script"); CHECK(flatten_script_name("script", "some/path") == "some.path.script");
#ifndef _MSC_VER
// TODO: this test fails on Windows because the implementation of dirname() in libunistd
// returns a trailing slash on paths, even tho the POSIX implementation doesn't. Commenting
// this out until we can fix that.
CHECK(flatten_script_name("other/path/__load__.zeek", "some/path") == "some.path.other.path"); CHECK(flatten_script_name("other/path/__load__.zeek", "some/path") == "some.path.other.path");
#endif
CHECK(flatten_script_name("path/to/script", "") == "path.to.script"); CHECK(flatten_script_name("path/to/script", "") == "path.to.script");
} }
@ -622,6 +630,9 @@ string flatten_script_name(const string& name, const string& prefix)
TEST_CASE("util normalize_path") TEST_CASE("util normalize_path")
{ {
#ifdef _MSC_VER
// TODO: adapt these tests to Windows
#else
CHECK(normalize_path("/1/2/3") == "/1/2/3"); CHECK(normalize_path("/1/2/3") == "/1/2/3");
CHECK(normalize_path("/1/./2/3") == "/1/2/3"); CHECK(normalize_path("/1/./2/3") == "/1/2/3");
CHECK(normalize_path("/1/2/../3") == "/1/3"); CHECK(normalize_path("/1/2/../3") == "/1/3");
@ -645,10 +656,24 @@ TEST_CASE("util normalize_path")
CHECK(normalize_path("~/../..") == "~/../.."); CHECK(normalize_path("~/../..") == "~/../..");
CHECK(normalize_path("zeek/..") == ""); CHECK(normalize_path("zeek/..") == "");
CHECK(normalize_path("zeek/../..") == ".."); CHECK(normalize_path("zeek/../..") == "..");
#endif
} }
string normalize_path(std::string_view path) string normalize_path(std::string_view path)
{ {
#ifdef _MSC_VER
if ( 0 == path.compare(zeek::detail::ScannedFile::canonical_stdin_path) )
{
return string(path);
}
// "//" interferes with std::weakly_canonical
string stringPath = string(path);
if ( stringPath._Starts_with("//") )
{
stringPath.erase(0, 2);
}
return zeek::filesystem::path(stringPath).lexically_normal().string();
#else
if ( path.find("/.") == std::string_view::npos && path.find("//") == std::string_view::npos ) if ( path.find("/.") == std::string_view::npos && path.find("//") == std::string_view::npos )
{ {
// no need to normalize anything // no need to normalize anything
@ -713,13 +738,14 @@ string normalize_path(std::string_view path)
new_path.erase(new_path.size() - 1); new_path.erase(new_path.size() - 1);
return new_path; return new_path;
#endif
} }
string without_zeekpath_component(std::string_view path) string without_zeekpath_component(std::string_view path)
{ {
string rval = normalize_path(path); string rval = normalize_path(path);
const auto paths = tokenize_string(zeek_path(), ':'); const auto paths = tokenize_string(zeek_path(), path_list_separator[0]);
for ( size_t i = 0; i < paths.size(); ++i ) for ( size_t i = 0; i < paths.size(); ++i )
{ {
@ -746,12 +772,13 @@ std::string get_exe_path(const std::string& invocation)
{ {
if ( invocation.empty() ) if ( invocation.empty() )
return ""; return "";
zeek::filesystem::path invocation_path(invocation);
if ( invocation[0] == '/' || invocation[0] == '~' ) if ( invocation_path.is_absolute() || invocation_path.root_directory() == "~" )
// Absolute path // Absolute path
return invocation; return invocation;
if ( invocation.find('/') != std::string::npos ) if ( invocation_path.is_relative() && invocation_path.has_parent_path() )
{ {
// Relative path // Relative path
char cwd[PATH_MAX]; char cwd[PATH_MAX];
@ -762,7 +789,7 @@ std::string get_exe_path(const std::string& invocation)
exit(1); exit(1);
} }
return std::string(cwd) + "/" + invocation; return (zeek::filesystem::path(cwd) / invocation_path).string();
} }
auto path = getenv("PATH"); auto path = getenv("PATH");
@ -1102,9 +1129,9 @@ TEST_CASE("util streq")
CHECK(streq("abcd", "efgh") == false); CHECK(streq("abcd", "efgh") == false);
} }
int streq(const char* s1, const char* s2) bool streq(const char* s1, const char* s2)
{ {
return ! strcmp(s1, s2); return strcmp(s1, s2) == 0;
} }
bool starts_with(std::string_view s, std::string_view beginning) bool starts_with(std::string_view s, std::string_view beginning)
@ -1316,7 +1343,7 @@ const char* strpbrk_n(size_t len, const char* s, const char* charset)
return nullptr; return nullptr;
} }
#ifndef HAVE_STRCASESTR #if ! defined(HAVE_STRCASESTR) && ! defined(_MSC_VER)
TEST_CASE("util strcasestr") TEST_CASE("util strcasestr")
{ {
@ -1576,7 +1603,7 @@ const char* fmt_bytes(const char* data, int len)
for ( int i = 0; i < len && p - buf < int(sizeof(buf)); ++i ) for ( int i = 0; i < len && p - buf < int(sizeof(buf)); ++i )
{ {
if ( isprint(data[i]) ) if ( isprint((unsigned char)(data[i])) )
*p++ = data[i]; *p++ = data[i];
else else
p += snprintf(p, sizeof(buf) - (p - buf), "\\x%02x", (unsigned char)data[i]); p += snprintf(p, sizeof(buf) - (p - buf), "\\x%02x", (unsigned char)data[i]);
@ -1593,7 +1620,7 @@ const char* fmt_bytes(const char* data, int len)
const char* vfmt(const char* format, va_list al) const char* vfmt(const char* format, va_list al)
{ {
static char* buf = nullptr; static char* buf = nullptr;
static unsigned int buf_len = 1024; static int buf_len = 1024;
if ( ! buf ) if ( ! buf )
buf = (char*)safe_malloc(buf_len); buf = (char*)safe_malloc(buf_len);
@ -1602,17 +1629,16 @@ const char* vfmt(const char* format, va_list al)
va_copy(alc, al); va_copy(alc, al);
int n = vsnprintf(buf, buf_len, format, al); int n = vsnprintf(buf, buf_len, format, al);
if ( (unsigned int)n >= buf_len ) if ( n > 0 && buf_len < n )
{ // Not enough room, grow the buffer. { // Not enough room, grow the buffer.
buf_len = n + 32; buf_len = n + 32;
buf = (char*)safe_realloc(buf, buf_len); buf = (char*)safe_realloc(buf, buf_len);
n = vsnprintf(buf, buf_len, format, alc); n = vsnprintf(buf, buf_len, format, alc);
if ( (unsigned int)n >= buf_len )
reporter->InternalError("confusion reformatting in fmt()");
} }
if ( n < 0 )
reporter->InternalError("confusion reformatting in fmt()");
va_end(alc); va_end(alc);
return buf; return buf;
} }
@ -1756,7 +1782,7 @@ string zeek_prefixes()
for ( const auto& prefix : zeek::detail::zeek_script_prefixes ) for ( const auto& prefix : zeek::detail::zeek_script_prefixes )
{ {
if ( ! rval.empty() ) if ( ! rval.empty() )
rval.append(":"); rval.append(path_list_separator);
rval.append(prefix); rval.append(prefix);
} }
@ -1780,11 +1806,11 @@ FILE* open_file(const string& path, const string& mode)
return rval; return rval;
} }
TEST_CASE("util path ops") TEST_CASE("util path ops"){
{ #ifdef _MSC_VER
SUBCASE("SafeDirname") // TODO: adapt these tests to Windows paths
{ #else
SafeDirname d("/this/is/a/path", false); SUBCASE("SafeDirname"){SafeDirname d("/this/is/a/path", false);
CHECK(d.result == "/this/is/a"); CHECK(d.result == "/this/is/a");
SafeDirname d2("invalid", false); SafeDirname d2("invalid", false);
@ -1804,9 +1830,11 @@ TEST_CASE("util path ops")
CHECK(b2.result == "justafile"); CHECK(b2.result == "justafile");
CHECK(! b2.error); CHECK(! b2.error);
} }
#endif
} }
SafeDirname::SafeDirname(const char* path, bool error_aborts) : SafePathOp() SafeDirname::SafeDirname(const char* path, bool error_aborts)
: SafePathOp()
{ {
DoFunc(path ? path : "", error_aborts); DoFunc(path ? path : "", error_aborts);
} }
@ -1937,8 +1965,10 @@ static string find_file_in_path(const string& filename, const string& path,
if ( filename.empty() ) if ( filename.empty() )
return string(); return string();
zeek::filesystem::path filepath(filename);
// If file name is an absolute path, searching within *path* is pointless. // If file name is an absolute path, searching within *path* is pointless.
if ( filename[0] == '/' ) if ( filepath.is_absolute() )
{ {
if ( can_read(filename) ) if ( can_read(filename) )
return filename; return filename;
@ -1946,7 +1976,7 @@ static string find_file_in_path(const string& filename, const string& path,
return string(); return string();
} }
string abs_path = path + '/' + filename; auto abs_path = (zeek::filesystem::path(path) / filepath).string();
if ( ! opt_ext.empty() ) if ( ! opt_ext.empty() )
{ {
@ -1968,7 +1998,7 @@ static string find_file_in_path(const string& filename, const string& path,
string find_file(const string& filename, const string& path_set, const string& opt_ext) string find_file(const string& filename, const string& path_set, const string& opt_ext)
{ {
vector<string> paths; vector<string> paths;
tokenize_string(path_set, ":", &paths); tokenize_string(path_set, path_list_separator, &paths);
vector<string> ext; vector<string> ext;
if ( ! opt_ext.empty() ) if ( ! opt_ext.empty() )
@ -1988,7 +2018,7 @@ string find_file(const string& filename, const string& path_set, const string& o
string find_script_file(const string& filename, const string& path_set) string find_script_file(const string& filename, const string& path_set)
{ {
vector<string> paths; vector<string> paths;
tokenize_string(path_set, ":", &paths); tokenize_string(path_set, path_list_separator, &paths);
vector<string> ext = {".zeek"}; vector<string> ext = {".zeek"};
@ -2008,9 +2038,15 @@ RETSIGTYPE sig_handler(int signo);
double current_time(bool real) double current_time(bool real)
{ {
struct timeval tv; struct timeval tv;
#ifdef _MSC_VER
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
tv.tv_sec = ms.count() / 1000;
tv.tv_usec = (ms.count() % 1000) * 1000;
#else
if ( gettimeofday(&tv, 0) < 0 ) if ( gettimeofday(&tv, 0) < 0 )
reporter->InternalError("gettimeofday failed in current_time()"); reporter->InternalError("gettimeofday failed in current_time()");
#endif
double t = double(tv.tv_sec) + double(tv.tv_usec) / 1e6; double t = double(tv.tv_sec) + double(tv.tv_usec) / 1e6;
if ( ! run_state::pseudo_realtime || real || ! iosource_mgr || ! iosource_mgr->GetPktSrc() ) if ( ! run_state::pseudo_realtime || real || ! iosource_mgr || ! iosource_mgr->GetPktSrc() )
@ -2251,8 +2287,8 @@ const void* memory_align(const void* ptr, size_t size)
const char* buf = reinterpret_cast<const char*>(ptr); const char* buf = reinterpret_cast<const char*>(ptr);
size_t mask = size - 1; // Assume size is a power of 2. size_t mask = size - 1; // Assume size is a power of 2.
unsigned long l_ptr = reinterpret_cast<unsigned long>(ptr); intptr_t l_ptr = reinterpret_cast<intptr_t>(ptr);
unsigned long offset = l_ptr & mask; ptrdiff_t offset = l_ptr & mask;
if ( offset > 0 ) if ( offset > 0 )
return reinterpret_cast<const void*>(buf - offset + size); return reinterpret_cast<const void*>(buf - offset + size);
@ -2291,7 +2327,7 @@ void* memory_align_and_pad(void* ptr, size_t size)
char* buf = reinterpret_cast<char*>(ptr); char* buf = reinterpret_cast<char*>(ptr);
size_t mask = size - 1; size_t mask = size - 1;
while ( (reinterpret_cast<unsigned long>(buf) & mask) != 0 ) while ( (reinterpret_cast<intptr_t>(buf) & mask) != 0 )
// Not aligned - zero pad. // Not aligned - zero pad.
*buf++ = '\0'; *buf++ = '\0';
@ -2394,6 +2430,9 @@ void get_memory_usage(uint64_t* total, uint64_t* malloced)
// In KB. // In KB.
ret_total = r.ru_maxrss * 1024; ret_total = r.ru_maxrss * 1024;
if ( malloced )
*malloced = r.ru_ixrss * 1024;
#endif #endif
if ( total ) if ( total )
@ -2506,7 +2545,12 @@ static void strerror_r_helper(int result, char* buf, size_t buflen)
void zeek_strerror_r(int zeek_errno, char* buf, size_t buflen) void zeek_strerror_r(int zeek_errno, char* buf, size_t buflen)
{ {
#ifdef _MSC_VER
auto str = "Error number: " + std::to_string(zeek_errno);
auto res = str.data();
#else
auto res = strerror_r(zeek_errno, buf, buflen); auto res = strerror_r(zeek_errno, buf, buflen);
#endif
// GNU vs. XSI flavors make it harder to use strerror_r. // GNU vs. XSI flavors make it harder to use strerror_r.
strerror_r_helper(res, buf, buflen); strerror_r_helper(res, buf, buflen);
} }
@ -2698,6 +2742,9 @@ string json_escape_utf8(const char* val, size_t val_size, bool escape_printable_
TEST_CASE("util filesystem") TEST_CASE("util filesystem")
{ {
#ifdef _MSC_VER
// TODO: adapt these tests to Windows paths
#else
zeek::filesystem::path path1("/a/b"); zeek::filesystem::path path1("/a/b");
CHECK(path1.is_absolute()); CHECK(path1.is_absolute());
CHECK(! path1.is_relative()); CHECK(! path1.is_relative());
@ -2712,6 +2759,7 @@ TEST_CASE("util filesystem")
auto info = zeek::filesystem::space("."); auto info = zeek::filesystem::space(".");
CHECK(info.capacity > 0); CHECK(info.capacity > 0);
#endif
} }
TEST_CASE("util split") TEST_CASE("util split")

View file

@ -15,6 +15,7 @@
#endif #endif
#include <libgen.h> #include <libgen.h>
#include <unistd.h>
#include <array> #include <array>
#include <cinttypes> #include <cinttypes>
#include <cstdarg> #include <cstdarg>
@ -30,27 +31,28 @@
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
#include <sys/time.h> #include <sys/time.h>
#include <ctime> #include <ctime>
#else #elif defined(HAVE_SYS_TIME_H)
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#else #else
#include <ctime> #include <ctime>
#endif #endif
#endif
#ifdef DEBUG #ifdef DEBUG
#include <cassert> #include <cassert>
#define ASSERT(x) assert(x) #define ASSERT(x) assert(x)
#define DEBUG_MSG(x...) fprintf(stderr, x) #define DEBUG_MSG(...) fprintf(stderr, __VA_ARGS__)
#define DEBUG_fputs fputs #define DEBUG_fputs fputs
#else #else
#ifdef MSTCPIP_ASSERT_UNDEFINED
#undef ASSERT
#endif
#define ASSERT(x) #define ASSERT(x)
#define DEBUG_MSG(x...) #define DEBUG_MSG(...)
#define DEBUG_fputs(x...) #define DEBUG_fputs(...)
#endif #endif
@ -60,9 +62,15 @@
extern HeapLeakChecker* heap_checker; extern HeapLeakChecker* heap_checker;
#endif #endif
#include <pthread.h> #include <stdint.h>
extern "C"
{
#include "zeek/3rdparty/modp_numtoa.h"
}
#ifdef HAVE_LINUX #ifdef HAVE_LINUX
#include <pthread.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#endif #endif
@ -70,12 +78,24 @@ extern HeapLeakChecker* heap_checker;
#include <pthread_np.h> #include <pthread_np.h>
#endif #endif
extern "C" #ifdef _MSC_VER
#include <pthread.h>
#include <filesystem>
namespace zeek
{ {
#include "zeek/3rdparty/modp_numtoa.h" namespace filesystem = std::filesystem;
} }
inline constexpr std::string_view path_list_separator = ";";
#else
// Expose ghc::filesystem as zeek::filesystem until we can
// switch to std::filesystem on all platforms.
#include "zeek/3rdparty/ghc/filesystem.hpp" #include "zeek/3rdparty/ghc/filesystem.hpp"
namespace zeek
{
namespace filesystem = ghc::filesystem;
}
inline constexpr std::string_view path_list_separator = ":";
#endif
using zeek_int_t = int64_t; using zeek_int_t = int64_t;
using zeek_uint_t = uint64_t; using zeek_uint_t = uint64_t;
@ -95,10 +115,6 @@ namespace zeek
class ODesc; class ODesc;
class RecordVal; class RecordVal;
// Expose ghc::filesystem as zeek::filesystem until we can
// switch to std::filesystem.
namespace filesystem = ghc::filesystem;
namespace util namespace util
{ {
namespace detail namespace detail
@ -318,7 +334,7 @@ std::vector<std::string>* tokenize_string(std::string_view input, std::string_vi
std::vector<std::string_view> tokenize_string(std::string_view input, const char delim) noexcept; std::vector<std::string_view> tokenize_string(std::string_view input, const char delim) noexcept;
extern char* copy_string(const char* s); extern char* copy_string(const char* s);
extern int streq(const char* s1, const char* s2); extern bool streq(const char* s1, const char* s2);
extern bool starts_with(std::string_view s, std::string_view beginning); extern bool starts_with(std::string_view s, std::string_view beginning);
extern bool ends_with(std::string_view s, std::string_view ending); extern bool ends_with(std::string_view s, std::string_view ending);

View file

@ -1 +0,0 @@
.

View file

@ -16,7 +16,9 @@
#include <list> #include <list>
#include <optional> #include <optional>
#ifdef USE_SQLITE
#include "zeek/3rdparty/sqlite3.h" #include "zeek/3rdparty/sqlite3.h"
#endif
#define DOCTEST_CONFIG_IMPLEMENT #define DOCTEST_CONFIG_IMPLEMENT
@ -200,7 +202,12 @@ std::shared_ptr<zeek::detail::SampleLogger> zeek::detail::sample_logger;
zeek::detail::FragmentManager* zeek::detail::fragment_mgr = nullptr; zeek::detail::FragmentManager* zeek::detail::fragment_mgr = nullptr;
int signal_val = 0; int signal_val = 0;
#ifdef _MSC_VER
char version[] = VERSION;
#else
extern char version[]; extern char version[];
#endif
const char* zeek::detail::command_line_policy = nullptr; const char* zeek::detail::command_line_policy = nullptr;
vector<string> zeek::detail::params; vector<string> zeek::detail::params;
set<string> requested_plugins; set<string> requested_plugins;
@ -636,11 +643,12 @@ SetupResult setup(int argc, char** argv, Options* zopts)
// FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't // FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't
// seed the PRNG. We should do this here (but at least Linux, FreeBSD // seed the PRNG. We should do this here (but at least Linux, FreeBSD
// and Solaris provide /dev/urandom). // and Solaris provide /dev/urandom).
#ifdef USE_SQLITE
int r = sqlite3_initialize(); int r = sqlite3_initialize();
if ( r != SQLITE_OK ) if ( r != SQLITE_OK )
reporter->Error("Failed to initialize sqlite3: %s", sqlite3_errstr(r)); reporter->Error("Failed to initialize sqlite3: %s", sqlite3_errstr(r));
#endif
timer_mgr = new TimerMgr(); timer_mgr = new TimerMgr();
@ -1112,7 +1120,9 @@ int cleanup(bool did_run_loop)
run_state::detail::delete_run(); run_state::detail::delete_run();
terminate_zeek(); terminate_zeek();
#ifdef USE_SQLITE
sqlite3_shutdown(); sqlite3_shutdown();
#endif
do_ssl_deinit(); do_ssl_deinit();

View file

@ -2226,7 +2226,7 @@ function is_local_interface%(ip: addr%) : bool
%{ %{
if ( ip->AsAddr().IsLoopback() ) if ( ip->AsAddr().IsLoopback() )
return zeek::val_mgr->True(); return zeek::val_mgr->True();
#ifndef _MSC_VER
list<zeek::IPAddr> addrs; list<zeek::IPAddr> addrs;
char host[MAXHOSTNAMELEN]; char host[MAXHOSTNAMELEN];
@ -2259,7 +2259,7 @@ function is_local_interface%(ip: addr%) : bool
if ( *it == ip->AsAddr() ) if ( *it == ip->AsAddr() )
return zeek::val_mgr->True(); return zeek::val_mgr->True();
} }
#endif
return zeek::val_mgr->False(); return zeek::val_mgr->False();
%} %}

View file

@ -108,6 +108,9 @@
/* should we declare syslog() and openlog() */ /* should we declare syslog() and openlog() */
#cmakedefine SYSLOG_INT #cmakedefine SYSLOG_INT
/* should we use stub syslog() and openlog() */
#cmakedefine USE_STUB_SYSLOG
/* Define if you have <sys/time.h> */ /* Define if you have <sys/time.h> */
#cmakedefine HAVE_SYS_TIME_H #cmakedefine HAVE_SYS_TIME_H
@ -132,6 +135,9 @@
/* Use the ElasticSearch writer. */ /* Use the ElasticSearch writer. */
#cmakedefine USE_ELASTICSEARCH #cmakedefine USE_ELASTICSEARCH
/* Use the sqlite reader/writer. */
#cmakedefine USE_SQLITE
/* Version number of package */ /* Version number of package */
#define VERSION "@VERSION@" #define VERSION "@VERSION@"
@ -184,6 +190,7 @@
#define DLT_NFLOG @DLT_NFLOG@ #define DLT_NFLOG @DLT_NFLOG@
#endif #endif
#ifndef _MSC_VER
/* IPv6 Next Header values defined by RFC 3542 */ /* IPv6 Next Header values defined by RFC 3542 */
#cmakedefine HAVE_IPPROTO_HOPOPTS #cmakedefine HAVE_IPPROTO_HOPOPTS
#ifndef HAVE_IPPROTO_HOPOPTS #ifndef HAVE_IPPROTO_HOPOPTS
@ -225,7 +232,7 @@
#ifndef HAVE_IPPROTO_DSTOPTS #ifndef HAVE_IPPROTO_DSTOPTS
#define IPPROTO_DSTOPTS 60 #define IPPROTO_DSTOPTS 60
#endif #endif
#endif
/* IPv6 options structure defined by RFC 3542 */ /* IPv6 options structure defined by RFC 3542 */
#cmakedefine HAVE_IP6_OPT #cmakedefine HAVE_IP6_OPT
@ -264,20 +271,19 @@ extern const char* ZEEK_VERSION_FUNCTION();
#endif #endif
#endif #endif
// FreeBSD doesn't support LeakSanitizer
#if defined(ZEEK_ASAN) && !defined(__FreeBSD__) #if defined(ZEEK_ASAN) && !defined(__FreeBSD__)
#include <sanitizer/lsan_interface.h> #include <sanitizer/lsan_interface.h>
#define ZEEK_LSAN_CHECK(x) __lsan_do_leak_check(x) #define ZEEK_LSAN_CHECK(...) __lsan_do_leak_check(__VA_ARGS__)
#define ZEEK_LSAN_ENABLE(x) __lsan_enable(x) #define ZEEK_LSAN_ENABLE(...) __lsan_enable(__VA_ARGS__)
#define ZEEK_LSAN_IGNORE(x) __lsan_ignore_object(x) #define ZEEK_LSAN_IGNORE(...) __lsan_ignore_object(__VA_ARGS__)
#define ZEEK_LSAN_DISABLE(x) __lsan_disable(x) #define ZEEK_LSAN_DISABLE(...) __lsan_disable(__VA_ARGS__)
#define ZEEK_LSAN_DISABLE_SCOPE(x) __lsan::ScopedDisabler x #define ZEEK_LSAN_DISABLE_SCOPE(...) __lsan::ScopedDisabler __VA_ARGS__
#else #else
#define ZEEK_LSAN_CHECK(x) #define ZEEK_LSAN_CHECK(...)
#define ZEEK_LSAN_ENABLE(x) #define ZEEK_LSAN_ENABLE(...)
#define ZEEK_LSAN_IGNORE(x) #define ZEEK_LSAN_IGNORE(...)
#define ZEEK_LSAN_DISABLE(x) #define ZEEK_LSAN_DISABLE(...)
#define ZEEK_LSAN_DISABLE_SCOPE(x) #define ZEEK_LSAN_DISABLE_SCOPE(...)
#endif #endif
// This part is dependent on calling configure with '--sanitizers=thread' // This part is dependent on calling configure with '--sanitizers=thread'

View file

@ -10,4 +10,4 @@
# ZEEKPATH=`./zeek-path-dev` ./src/zeek # ZEEKPATH=`./zeek-path-dev` ./src/zeek
# #
echo .:${PROJECT_SOURCE_DIR}/scripts:${PROJECT_SOURCE_DIR}/scripts/policy:${PROJECT_SOURCE_DIR}/scripts/site:${PROJECT_BINARY_DIR}/scripts:${PROJECT_BINARY_DIR}/scripts/builtin-plugins echo .:${cmake_source_dir}/scripts:${cmake_source_dir}/scripts/policy:${cmake_source_dir}/scripts/site:${cmake_binary_dir}/scripts:${cmake_binary_dir}/scripts/builtin-plugins