mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge branch 'master' into topic/icmp6
Conflicts: policy/bro.init policy/icmp.bro src/Analyzer.cc src/AnalyzerTags.h src/DPM.cc src/ICMP.h src/Sessions.cc src/event.bif src/net_util.cc
This commit is contained in:
commit
ef31099fd7
1250 changed files with 56739 additions and 54904 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
build
|
build
|
||||||
|
tmp
|
||||||
|
|
14
.gitmodules
vendored
14
.gitmodules
vendored
|
@ -1,12 +1,18 @@
|
||||||
[submodule "aux/bro-aux"]
|
[submodule "aux/bro-aux"]
|
||||||
path = aux/bro-aux
|
path = aux/bro-aux
|
||||||
url = git://git.icir.org/bro-aux
|
url = git://git.bro-ids.org/bro-aux
|
||||||
[submodule "aux/binpac"]
|
[submodule "aux/binpac"]
|
||||||
path = aux/binpac
|
path = aux/binpac
|
||||||
url = git://git.icir.org/binpac
|
url = git://git.bro-ids.org/binpac
|
||||||
[submodule "aux/broccoli"]
|
[submodule "aux/broccoli"]
|
||||||
path = aux/broccoli
|
path = aux/broccoli
|
||||||
url = git://git.icir.org/broccoli
|
url = git://git.bro-ids.org/broccoli
|
||||||
[submodule "aux/broctl"]
|
[submodule "aux/broctl"]
|
||||||
path = aux/broctl
|
path = aux/broctl
|
||||||
url = git://git.icir.org/broctl
|
url = git://git.bro-ids.org/broctl
|
||||||
|
[submodule "aux/btest"]
|
||||||
|
path = aux/btest
|
||||||
|
url = git://git.bro-ids.org/btest
|
||||||
|
[submodule "cmake"]
|
||||||
|
path = cmake
|
||||||
|
url = git://git.bro-ids.org/cmake
|
||||||
|
|
200
CMakeLists.txt
200
CMakeLists.txt
|
@ -1,58 +1,36 @@
|
||||||
project(Bro)
|
project(Bro C CXX)
|
||||||
|
|
||||||
########################################################################
|
|
||||||
## CMake Configuration
|
|
||||||
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
||||||
|
include(cmake/CommonCMakeConfig.cmake)
|
||||||
# Prohibit in-source builds.
|
|
||||||
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
|
||||||
message(FATAL_ERROR "In-source builds are not allowed. Please use "
|
|
||||||
"./configure to choose a build directory and "
|
|
||||||
"initialize the build configuration.")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
|
||||||
|
|
||||||
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
|
|
||||||
# uninstall target
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
|
||||||
@ONLY)
|
|
||||||
|
|
||||||
add_custom_target(uninstall COMMAND
|
|
||||||
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Project/Build Configuration
|
## Project/Build Configuration
|
||||||
|
|
||||||
set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
|
set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
|
||||||
if (NOT POLICYDIR)
|
if (NOT BRO_SCRIPT_INSTALL_PATH)
|
||||||
# set the default policy installation path (user did not specify one)
|
# set the default Bro script installation path (user did not specify one)
|
||||||
set(POLICYDIR ${BRO_ROOT_DIR}/share/bro)
|
set(BRO_SCRIPT_INSTALL_PATH ${BRO_ROOT_DIR}/share/bro)
|
||||||
endif ()
|
endif ()
|
||||||
|
set(BRO_SCRIPT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
|
||||||
|
|
||||||
# sanitize the policy install directory into an absolute path
|
# sanitize the Bro script install directory into an absolute path
|
||||||
# (CMake is confused by ~ as a representation of home directory)
|
# (CMake is confused by ~ as a representation of home directory)
|
||||||
get_filename_component(POLICYDIR ${POLICYDIR} ABSOLUTE)
|
get_filename_component(BRO_SCRIPT_INSTALL_PATH ${BRO_SCRIPT_INSTALL_PATH}
|
||||||
|
ABSOLUTE)
|
||||||
|
|
||||||
configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev)
|
configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev)
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.sh
|
||||||
|
"export BROPATH=`${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n"
|
||||||
|
"export PATH=\"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n")
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.csh
|
||||||
|
"setenv BROPATH `${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n"
|
||||||
|
"setenv PATH \"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n")
|
||||||
|
|
||||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
||||||
|
string(REPLACE "." " " version_numbers ${VERSION})
|
||||||
set(EXTRA_COMPILE_FLAGS "-Wall -Wno-unused")
|
separate_arguments(version_numbers)
|
||||||
|
list(GET version_numbers 0 VERSION_MAJOR)
|
||||||
if (ENABLE_DEBUG)
|
list(GET version_numbers 1 VERSION_MINOR)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(VERSION_MAJ_MIN "${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||||
set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DDEBUG")
|
|
||||||
else ()
|
|
||||||
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Compiler flags may already exist in CMake cache (e.g. when specifying
|
|
||||||
# CFLAGS environment variable before running cmake for the the first time)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILE_FLAGS}")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}")
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Dependency Configuration
|
## Dependency Configuration
|
||||||
|
@ -75,8 +53,11 @@ FindRequiredPackage(BISON)
|
||||||
FindRequiredPackage(PCAP)
|
FindRequiredPackage(PCAP)
|
||||||
FindRequiredPackage(OpenSSL)
|
FindRequiredPackage(OpenSSL)
|
||||||
FindRequiredPackage(BIND)
|
FindRequiredPackage(BIND)
|
||||||
|
FindRequiredPackage(LibMagic)
|
||||||
|
FindRequiredPackage(ZLIB)
|
||||||
|
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/binpac/CMakeLists.txt)
|
if (NOT BinPAC_ROOT_DIR AND
|
||||||
|
EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/binpac/CMakeLists.txt)
|
||||||
add_subdirectory(aux/binpac)
|
add_subdirectory(aux/binpac)
|
||||||
endif ()
|
endif ()
|
||||||
FindRequiredPackage(BinPAC)
|
FindRequiredPackage(BinPAC)
|
||||||
|
@ -93,26 +74,12 @@ include_directories(BEFORE
|
||||||
${OpenSSL_INCLUDE_DIR}
|
${OpenSSL_INCLUDE_DIR}
|
||||||
${BIND_INCLUDE_DIR}
|
${BIND_INCLUDE_DIR}
|
||||||
${BinPAC_INCLUDE_DIR}
|
${BinPAC_INCLUDE_DIR}
|
||||||
|
${LibMagic_INCLUDE_DIR}
|
||||||
|
${ZLIB_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Optional Dependencies
|
# Optional Dependencies
|
||||||
|
|
||||||
set(HAVE_LIBMAGIC false)
|
|
||||||
find_package(LibMagic)
|
|
||||||
if (LIBMAGIC_FOUND)
|
|
||||||
set(HAVE_LIBMAGIC true)
|
|
||||||
include_directories(BEFORE ${LibMagic_INCLUDE_DIR})
|
|
||||||
list(APPEND OPTLIBS ${LibMagic_LIBRARY})
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(HAVE_LIBZ false)
|
|
||||||
find_package(ZLIB)
|
|
||||||
if (ZLIB_FOUND)
|
|
||||||
set(HAVE_LIBZ true)
|
|
||||||
include_directories(BEFORE ${ZLIB_INCLUDE_DIR})
|
|
||||||
list(APPEND OPTLIBS ${ZLIB_LIBRARY})
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(USE_GEOIP false)
|
set(USE_GEOIP false)
|
||||||
find_package(LibGeoIP)
|
find_package(LibGeoIP)
|
||||||
if (LIBGEOIP_FOUND)
|
if (LIBGEOIP_FOUND)
|
||||||
|
@ -131,6 +98,16 @@ if (ENABLE_PERFTOOLS)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
set(brodeps
|
||||||
|
${BinPAC_LIBRARY}
|
||||||
|
${PCAP_LIBRARY}
|
||||||
|
${OpenSSL_LIBRARIES}
|
||||||
|
${BIND_LIBRARY}
|
||||||
|
${LibMagic_LIBRARY}
|
||||||
|
${ZLIB_LIBRARY}
|
||||||
|
${OPTLIBS}
|
||||||
|
)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## System Introspection
|
## System Introspection
|
||||||
|
|
||||||
|
@ -155,85 +132,30 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
## Recurse on sub-directories
|
## Recurse on sub-directories
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(policy)
|
add_subdirectory(scripts)
|
||||||
#add_subdirectory(scripts)
|
add_subdirectory(doc)
|
||||||
#add_subdirectory(doc)
|
|
||||||
|
|
||||||
if (INSTALL_BROCCOLI)
|
include(CheckOptionalBuildSources)
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/broccoli/CMakeLists.txt)
|
|
||||||
add_subdirectory(aux/broccoli)
|
|
||||||
else ()
|
|
||||||
message(FATAL_ERROR "Broccoli selected for installation, "
|
|
||||||
"but the source code does not exist in "
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/aux/broccoli")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (INSTALL_BROCTL)
|
CheckOptionalBuildSources(aux/broctl Broctl INSTALL_BROCTL)
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/broctl/CMakeLists.txt)
|
CheckOptionalBuildSources(aux/bro-aux Bro-Aux INSTALL_AUX_TOOLS)
|
||||||
add_subdirectory(aux/broctl)
|
CheckOptionalBuildSources(aux/broccoli Broccoli INSTALL_BROCCOLI)
|
||||||
else ()
|
|
||||||
message(FATAL_ERROR "Broctl selected for installation, "
|
|
||||||
"but the source code does not exist in "
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/aux/broctl")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (INSTALL_AUX_TOOLS)
|
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/bro-aux/CMakeLists.txt)
|
|
||||||
add_subdirectory(aux/bro-aux)
|
|
||||||
else ()
|
|
||||||
message(FATAL_ERROR "Bro auxilliary tools selected for installation, "
|
|
||||||
"but the source code does not exist in "
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/aux/bro-aux")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Packaging Setup
|
## Packaging Setup
|
||||||
|
|
||||||
include(SetPackageVersion)
|
if (INSTALL_BROCTL)
|
||||||
SetPackageVersion(${VERSION})
|
# CPack RPM Generator may not automatically detect this
|
||||||
include(SetPackageGenerators)
|
set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.4.0")
|
||||||
include(SetPackageFileName)
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VENDOR "Lawrence Berkeley National Laboratory")
|
|
||||||
set(CPACK_PACKAGE_CONTACT "info@bro-ids.org")
|
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
|
||||||
"The Bro Network Intrusion Detection System")
|
|
||||||
|
|
||||||
# CPack may enforce file name extensions for certain package generators
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/README.txt
|
|
||||||
COPYONLY)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/COPYING
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt
|
|
||||||
COPYONLY)
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
|
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt)
|
|
||||||
set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
|
|
||||||
set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
|
|
||||||
|
|
||||||
if (APPLE)
|
|
||||||
# /usr prefix is hardcoded for PackageMaker generator, but that
|
|
||||||
# directory may not be ideal for OS X (it's tricky to remove
|
|
||||||
# packages installed there). So instead we rely on CMAKE_INSTALL_PREFIX
|
|
||||||
# and set the following variable to workaround the hardcoded /usr prefix
|
|
||||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
|
|
||||||
set(CPACK_PACKAGE_DEFAULT_LOCATION ${CMAKE_INSTALL_PREFIX})
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|
||||||
# A prefix of /usr would follow Filesystem Hierarchy Standard.
|
|
||||||
# For RPM packaging by CPack, /usr should be a default, but
|
|
||||||
# CMAKE_INSTALL_PREFIX also needs to be set to /usr so that
|
|
||||||
# the default BROPATH is set right at build time
|
|
||||||
set(CPACK_RPM_PACKAGE_LICENSE "BSD")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Ignore the build directory
|
# If this CMake project is a sub-project of another, we will not
|
||||||
set(CPACK_SOURCE_IGNORE_FILES ${CMAKE_BINARY_DIR} ".git")
|
# configure the generic packaging because CPack will fail in the case
|
||||||
|
# that the parent project has already configured packaging
|
||||||
include(CPack)
|
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
|
||||||
|
include(ConfigurePackaging)
|
||||||
|
ConfigurePackaging(${VERSION})
|
||||||
|
endif ()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Build Summary
|
## Build Summary
|
||||||
|
@ -242,21 +164,11 @@ if (CMAKE_BUILD_TYPE)
|
||||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BuildType)
|
string(TOUPPER ${CMAKE_BUILD_TYPE} BuildType)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (INSTALL_BROCTL)
|
|
||||||
if (STANDALONE)
|
|
||||||
set(BROCTL_INSTALL_MODE "standalone")
|
|
||||||
else ()
|
|
||||||
set(BROCTL_INSTALL_MODE "cluster")
|
|
||||||
endif ()
|
|
||||||
else ()
|
|
||||||
set(BROCTL_INSTALL_MODE "false")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
message(
|
message(
|
||||||
"\n====================| Bro Build Summary |====================="
|
"\n====================| Bro Build Summary |====================="
|
||||||
"\n"
|
"\n"
|
||||||
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
|
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
|
||||||
"\nPolicy dir: ${POLICYDIR}"
|
"\nBro Script Path: ${BRO_SCRIPT_INSTALL_PATH}"
|
||||||
"\nDebug mode: ${ENABLE_DEBUG}"
|
"\nDebug mode: ${ENABLE_DEBUG}"
|
||||||
"\n"
|
"\n"
|
||||||
"\nCC: ${CMAKE_C_COMPILER}"
|
"\nCC: ${CMAKE_C_COMPILER}"
|
||||||
|
@ -266,13 +178,13 @@ message(
|
||||||
"\nCPP: ${CMAKE_CXX_COMPILER}"
|
"\nCPP: ${CMAKE_CXX_COMPILER}"
|
||||||
"\n"
|
"\n"
|
||||||
"\nBroccoli: ${INSTALL_BROCCOLI}"
|
"\nBroccoli: ${INSTALL_BROCCOLI}"
|
||||||
"\nBroctl: ${BROCTL_INSTALL_MODE}"
|
"\nBroctl: ${INSTALL_BROCTL}"
|
||||||
"\nAux. Tools: ${INSTALL_AUX_TOOLS}"
|
"\nAux. Tools: ${INSTALL_AUX_TOOLS}"
|
||||||
"\n"
|
"\n"
|
||||||
"\nGeoIP: ${USE_GEOIP}"
|
"\nGeoIP: ${USE_GEOIP}"
|
||||||
"\nlibz: ${HAVE_LIBZ}"
|
|
||||||
"\nlibmagic: ${HAVE_LIBMAGIC}"
|
|
||||||
"\nGoogle perftools: ${USE_PERFTOOLS}"
|
"\nGoogle perftools: ${USE_PERFTOOLS}"
|
||||||
"\n"
|
"\n"
|
||||||
"\n================================================================\n"
|
"\n================================================================\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
include(UserChangedWarning)
|
||||||
|
|
28
COPYING
28
COPYING
|
@ -1,11 +1,12 @@
|
||||||
Copyright (c) 1995-2010, The Regents of the University of California,
|
Copyright (c) 1995-2012, The Regents of the University of California
|
||||||
through Lawrence Berkeley National Laboratory. All rights reserved.
|
through the Lawrence Berkeley National Laboratory and the
|
||||||
|
International Computer Science Institute. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
(1) Redistributions of source code must retain the above copyright notice,
|
(1) Redistributions of source code must retain the above copyright
|
||||||
this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
(2) Redistributions in binary form must reproduce the above copyright
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
@ -29,20 +30,5 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
Note that some files in the Bro distribution carry their own copyright
|
Note that some files in the distribution may carry their own copyright
|
||||||
notices. The above applies to the Bro scripts in policy/ (other than as
|
notices.
|
||||||
noted below) and the source files in src/, other than:
|
|
||||||
|
|
||||||
policy/sigs/p0fsyn.osf
|
|
||||||
src/H3.h
|
|
||||||
src/OSFinger.cc
|
|
||||||
src/OSFinger.h
|
|
||||||
src/bsd-getopt-long.c
|
|
||||||
src/bsd-getopt-long.h
|
|
||||||
src/md5.c
|
|
||||||
src/md5.h
|
|
||||||
src/patricia.c
|
|
||||||
src/patricia.h
|
|
||||||
|
|
||||||
In addition, other components, such as the build system, may have
|
|
||||||
separate copyrights.
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
|
|
||||||
TODO: Needs update. -Robin
|
|
||||||
|
|
||||||
- Make sure BroV6 works.
|
|
||||||
|
|
||||||
- Make sure --enable-int64 builds w/o warnings.
|
|
||||||
|
|
||||||
- Update TODO-For-Next-Release.
|
|
||||||
|
|
||||||
- Build distribution on a system with an up-to-date yacc (MacOS suffices).
|
|
||||||
|
|
||||||
- make distcheck
|
|
||||||
|
|
||||||
- Edit CHANGES to final version.
|
|
||||||
|
|
||||||
- Fix VERSION to final value.
|
|
||||||
|
|
||||||
- Update version info (and perhaps other stuff) in README.
|
|
||||||
|
|
||||||
- Check everything in.
|
|
||||||
|
|
||||||
- Make an SVN branch for the release:
|
|
||||||
|
|
||||||
svn cp svn+ssh://svn.icir.org/bro/trunk \
|
|
||||||
svn+ssh://svn.icir.org/bro/releases/release_1_X
|
|
||||||
|
|
||||||
- scp bro-XXX.tar.gz crd.lbl.gov:/ftp/BROIDS/
|
|
||||||
scp CHANGES crd.lbl.gov:/ftp/BROIDS/bro-change-log.txt
|
|
||||||
|
|
||||||
- Fix symlinks on crd:
|
|
||||||
|
|
||||||
bro-1.X-release.tar.gz
|
|
||||||
bro-1.X-current.tar.gz
|
|
||||||
bro-1.<n>-release.tar.gz
|
|
||||||
|
|
||||||
- Update crd:/www/BROIDS/download.html to reflect new version. This page
|
|
||||||
is generated from trunk/bro-web/download.xml. Edit this file, and also
|
|
||||||
update the (web page) version in build.xml, the copyright year in
|
|
||||||
navigation.xml, and create a news entry in news.xml.
|
|
||||||
|
|
||||||
Type 'ant style' on a machine with 'ant' installed, and copy
|
|
||||||
html/*.html to crd.lbl.gov:/www/BROIDS/ .
|
|
||||||
|
|
||||||
- Send email to bro@bro-ids.org. Look for "release now available" in
|
|
||||||
previous messages as a template.
|
|
119
INSTALL
119
INSTALL
|
@ -2,90 +2,91 @@
|
||||||
Installing Bro
|
Installing Bro
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Bro relies on the following libraries and tools, which need to be installed
|
Bro relies on the following libraries and tools, which need to be installed
|
||||||
before you begin:
|
before you begin:
|
||||||
|
|
||||||
* Libpcap headers and libraries
|
* CMake 2.6 or greater http://www.cmake.org
|
||||||
Network traffic capture library
|
|
||||||
|
|
||||||
* Flex (Fast Lexical Analyzer)
|
* Libpcap (headers and libraries) http://www.tcpdump.org
|
||||||
Flex is already installed on most systems, so with luck you can
|
|
||||||
skip having to install it yourself.
|
|
||||||
|
|
||||||
* Bison (GNU Parser Generator)
|
* OpenSSL (headers and libraries) http://www.openssl.org
|
||||||
This comes with many systems, but if you get errors compiling
|
|
||||||
parse.y, you will need to install it.
|
|
||||||
|
|
||||||
* Perl
|
* SWIG http://www.swig.org
|
||||||
Used only during the Bro build process
|
|
||||||
|
|
||||||
* sed
|
|
||||||
Used only during the Bro build process
|
|
||||||
|
|
||||||
* BIND8 headers and libraries
|
|
||||||
These are usually already installed as well.
|
|
||||||
|
|
||||||
* OpenSSL headers and libraries
|
|
||||||
For analysis of SSL certificates by the HTTP analyzer, and
|
|
||||||
for encrypted Bro-to-Bro communication. These are likely installed,
|
|
||||||
though some platforms may require installation of a 'devel' package
|
|
||||||
for the headers.
|
|
||||||
|
|
||||||
* CMake 2.8 or greater
|
|
||||||
CMake is a cross-platform, open-source build system, typically
|
|
||||||
not installed by default. See http://www.cmake.org for more
|
|
||||||
information regarding CMake and the installation steps below for
|
|
||||||
how to use it to build this distribution. CMake generates native
|
|
||||||
Makefiles that depend on GNU Make by default.
|
|
||||||
|
|
||||||
Bro can also make uses of some optional libraries if they are found at
|
|
||||||
installation time:
|
|
||||||
|
|
||||||
* Libmagic
|
* Libmagic
|
||||||
For identifying file types (e.g., in FTP transfers).
|
|
||||||
|
|
||||||
* LibGeoIP
|
|
||||||
For geo-locating IP addresses.
|
|
||||||
|
|
||||||
* Libz
|
* Libz
|
||||||
For decompressing HTTP bodies by the HTTP analyzer, and for
|
|
||||||
compressed Bro-to-Bro communication.
|
Bro can make uses of some optional libraries if they are found at
|
||||||
|
installation time:
|
||||||
|
|
||||||
|
* LibGeoIP For geo-locating IP addresses.
|
||||||
|
|
||||||
|
Bro also needs the following tools, but on most systems they will
|
||||||
|
already come preinstalled:
|
||||||
|
|
||||||
|
* Bash (For Bro Control).
|
||||||
|
* BIND8 (headers and libraries)
|
||||||
|
* Bison (GNU Parser Generator)
|
||||||
|
* Flex (Fast Lexical Analyzer)
|
||||||
|
* Perl (Used only during the Bro build process)
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
To build and install into /usr/local/bro:
|
To build and install into ``/usr/local/bro``::
|
||||||
|
|
||||||
> ./configure
|
./configure
|
||||||
> cd build
|
make
|
||||||
> make
|
make install
|
||||||
> make install
|
|
||||||
|
|
||||||
This will perform an out-of-source build into a directory called
|
This will first build Bro into a directory inside the distribution
|
||||||
build/, using default build options. It then installs the Bro binary
|
called ``build/``, using default build options. It then installs all
|
||||||
into /usr/local/bro/bin. Depending on the Bro package you
|
required files into ``/usr/local/bro``, including the Bro binary in
|
||||||
downloaded, there may be auxiliary tools and libraries available in
|
``/usr/local/bro/bin/bro``.
|
||||||
the aux/ directory. If so, they will be installed by default as well
|
|
||||||
if not explicitly disabled via configure options.
|
|
||||||
|
|
||||||
You can specify a different installation directory with
|
You can specify a different installation directory with::
|
||||||
|
|
||||||
> ./configure --prefix=<dir>
|
./configure --prefix=<dir>
|
||||||
|
|
||||||
Run "./configure --help" for more options.
|
Note that ``/usr`` and ``/opt/bro`` are the standard prefixes for
|
||||||
|
binary Bro packages to be installed, so those are typically not good
|
||||||
|
choices unless you are creating such a package.
|
||||||
|
|
||||||
|
Run ``./configure --help`` for more options.
|
||||||
|
|
||||||
|
Depending on the Bro package you downloaded, there may be auxiliary
|
||||||
|
tools and libraries available in the ``aux/`` directory. All of them
|
||||||
|
except for ``aux/bro-aux`` will also be built and installed by doing
|
||||||
|
``make install``. To install the programs that come in the
|
||||||
|
``aux/bro-aux`` directory, use ``make install-aux``. There are
|
||||||
|
``--disable-*`` options that can be given to the configure script to
|
||||||
|
turn off unwanted auxiliary projects.
|
||||||
|
|
||||||
|
OpenBSD users, please see our `FAQ
|
||||||
|
<http://www.bro-ids.org/documentation/faq.html>` if you are having
|
||||||
|
problems installing Bro.
|
||||||
|
|
||||||
Running Bro
|
Running Bro
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Bro is a complex program and it takes a bit of time to get familiar
|
Bro is a complex program and it takes a bit of time to get familiar
|
||||||
with it. In the following we give a few simple examples. See the
|
with it. A good place for newcomers to start is the Quickstart Guide
|
||||||
quickstart guide at http://www.bro-ids.org for more information; you
|
at http://www.bro-ids.org/documentation/quickstart.html.
|
||||||
can the source that in doc/quick-start.
|
|
||||||
|
|
||||||
For developers that wish to run Bro after performing "make", but
|
For developers that wish to run Bro directly from the ``build/``
|
||||||
without performing "make install", see build/bro-path-dev for
|
directory (i.e., without performing ``make install``), they will have
|
||||||
an example.
|
to first adjust ``BROPATH`` to look for scripts inside the build
|
||||||
|
directory. Sourcing either ``build/bro-path-dev.sh`` or
|
||||||
|
``build/bro-path-dev.csh`` as appropriate for the current shell
|
||||||
|
accomplishes this and also augments your ``PATH`` so you can use the
|
||||||
|
Bro binary directly::
|
||||||
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
source build/bro-path-dev.sh
|
||||||
|
bro <options>
|
||||||
|
|
60
Makefile
60
Makefile
|
@ -2,27 +2,69 @@
|
||||||
# A simple static wrapper for a number of standard Makefile targets,
|
# A simple static wrapper for a number of standard Makefile targets,
|
||||||
# mostly just forwarding to build/Makefile. This is provided only for
|
# mostly just forwarding to build/Makefile. This is provided only for
|
||||||
# convenience and supports only a subset of what CMake's Makefile
|
# convenience and supports only a subset of what CMake's Makefile
|
||||||
# to offer. For more, execute that one directly.
|
# offers. For more, execute that one directly.
|
||||||
#
|
#
|
||||||
|
|
||||||
BUILD=build
|
BUILD=build
|
||||||
|
REPO=`basename \`git config --get remote.origin.url\``
|
||||||
|
VERSION_FULL=$(REPO)-`cat VERSION`
|
||||||
|
VERSION_MIN=$(REPO)-`cat VERSION`-minimal
|
||||||
|
HAVE_MODULES=git submodule | grep -v cmake >/dev/null
|
||||||
|
|
||||||
all: configured
|
all: configured
|
||||||
( cd $(BUILD) && make )
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
install: configured
|
install: configured all
|
||||||
( cd $(BUILD) && make install )
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
clean: configured
|
install-aux: configured
|
||||||
( cd $(BUILD) && make clean )
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
dist: configured
|
clean: configured docclean
|
||||||
( cd $(BUILD) && make package_source )
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
doc: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
docclean: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
restdoc: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
restclean: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
broxygen: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
broxygenclean: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
dist:
|
||||||
|
@rm -rf $(VERSION_FULL) $(VERSION_FULL).tgz
|
||||||
|
@rm -rf $(VERSION_MIN) $(VERSION_MIN).tgz
|
||||||
|
@mkdir $(VERSION_FULL)
|
||||||
|
@tar --exclude=$(VERSION_FULL)* --exclude=$(VERSION_MIN)* --exclude=.git -cf - . | ( cd $(VERSION_FULL) && tar -xpf - )
|
||||||
|
@( cd $(VERSION_FULL) && cp -R ../.git . && git reset -q --hard HEAD && git clean -xdfq && rm -rf .git )
|
||||||
|
@tar -czf $(VERSION_FULL).tgz $(VERSION_FULL) && echo Package: $(VERSION_FULL).tgz && rm -rf $(VERSION_FULL)
|
||||||
|
@$(HAVE_MODULES) && mkdir $(VERSION_MIN) || exit 0
|
||||||
|
@$(HAVE_MODULES) && tar --exclude=$(VERSION_FULL)* --exclude=$(VERSION_MIN)* --exclude=.git `git submodule | awk '{print "--exclude="$$2}' | grep -v cmake | tr '\n' ' '` -cf - . | ( cd $(VERSION_MIN) && tar -xpf - ) || exit 0
|
||||||
|
@$(HAVE_MODULES) && ( cd $(VERSION_MIN) && cp -R ../.git . && git reset -q --hard HEAD && git clean -xdfq && rm -rf .git ) || exit 0
|
||||||
|
@$(HAVE_MODULES) && tar -czf $(VERSION_MIN).tgz $(VERSION_MIN) && echo Package: $(VERSION_MIN).tgz && rm -rf $(VERSION_MIN) || exit 0
|
||||||
|
|
||||||
|
bindist:
|
||||||
|
@( cd pkg && ( ./make-deb-packages || ./make-mac-packages || \
|
||||||
|
./make-rpm-packages ) )
|
||||||
|
|
||||||
distclean:
|
distclean:
|
||||||
rm -rf $(BUILD)
|
rm -rf $(BUILD)
|
||||||
|
|
||||||
.PHONY : configured
|
test:
|
||||||
|
@(cd testing && make )
|
||||||
|
|
||||||
configured:
|
configured:
|
||||||
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
||||||
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
||||||
|
|
||||||
|
.PHONY : all install clean doc docclean dist bindist distclean configured
|
||||||
|
|
64
NEWS
Normal file
64
NEWS
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
Release Notes
|
||||||
|
=============
|
||||||
|
|
||||||
|
This document summarizes the most important changes in the current Bro
|
||||||
|
release. For a complete list of changes, see the ``CHANGES`` file.
|
||||||
|
|
||||||
|
Bro 2.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
As the version number jump suggests, Bro 2.0 is a major upgrade and
|
||||||
|
lots of things have changed. We have assembled a separate upgrade
|
||||||
|
guide with the most important changes compared to Bro 1.5 at
|
||||||
|
http://www.bro-ids.org/documentation/upgrade.html. You can find
|
||||||
|
the offline version of that document in ``doc/upgrade.rst.``.
|
||||||
|
|
||||||
|
Compared to the earlier 2.0 Beta version, the major changes in the
|
||||||
|
final release are:
|
||||||
|
|
||||||
|
* The default scripts now come with complete reference
|
||||||
|
documentation. See
|
||||||
|
http://www.bro-ids.org/documentation/index.html.
|
||||||
|
|
||||||
|
* libz and libmagic are now required dependencies.
|
||||||
|
|
||||||
|
* Reduced snaplen default from 65535 to old default of 8192. The
|
||||||
|
large value was introducing performance problems on many
|
||||||
|
systems.
|
||||||
|
|
||||||
|
* Replaced the --snaplen/-l command line option with a
|
||||||
|
scripting-layer option called "snaplen". The new option can also
|
||||||
|
be redefined on the command line, e.g. ``bro -i eth0
|
||||||
|
snaplen=65535``.
|
||||||
|
|
||||||
|
* Reintroduced the BRO_LOG_SUFFIX environment variable that the
|
||||||
|
ASCII logger now respects to add a suffix to the log files it
|
||||||
|
creates.
|
||||||
|
|
||||||
|
* The ASCII logs now include further header information, and
|
||||||
|
fields set to an empty value are now logged as ``(empty)`` by
|
||||||
|
default (instead of ``-``, which is already used for fields that
|
||||||
|
are not set at all).
|
||||||
|
|
||||||
|
* Some NOTICES were renamed, and the signatures of some SSL events
|
||||||
|
have changed.
|
||||||
|
|
||||||
|
* bro-cut got some new capabilities:
|
||||||
|
|
||||||
|
- If no field names are given on the command line, we now pass
|
||||||
|
through all fields.
|
||||||
|
|
||||||
|
- New options -u/-U for time output in UTC.
|
||||||
|
|
||||||
|
- New option -F to give output field separator.
|
||||||
|
|
||||||
|
* Broccoli supports more types internally, allowing to send
|
||||||
|
complex records.
|
||||||
|
|
||||||
|
* Many smaller bug fixes, portability improvements, and general
|
||||||
|
polishing across all modules.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
38
README
38
README
|
@ -1,31 +1,21 @@
|
||||||
This is release 1.6 of Bro, a system for detecting network intruders in
|
============================
|
||||||
real-time using passive network monitoring.
|
Bro Network Security Monitor
|
||||||
|
============================
|
||||||
|
|
||||||
Please see the file INSTALL for installation instructions and
|
Bro is a powerful framework for network analysis and security
|
||||||
pointers for getting started. For more documentation, see the
|
monitoring. Please see the INSTALL file for installation instructions
|
||||||
documentation on Bro's home page:
|
and pointers for getting started. NEWS contains release notes for the
|
||||||
|
current version, and CHANGES has the complete history of changes.
|
||||||
|
Please see COPYING for licensing information.
|
||||||
|
|
||||||
http://www.bro-ids.org/docs
|
For more documentation, research publications, and community contact
|
||||||
|
information, please see Bro's home page:
|
||||||
|
|
||||||
The main parts of Bro's documentation are also available in the doc/
|
http://www.bro-ids.org
|
||||||
directory of the distribution. (Please note that the documentation
|
|
||||||
is still a work in progress; there will be more in future releases.)
|
|
||||||
|
|
||||||
Numerous other Bro-related publications, including a paper describing the
|
On behalf of the Bro Development Team,
|
||||||
system, can be found at
|
|
||||||
|
|
||||||
http://www.bro-ids.org/publications.html
|
|
||||||
|
|
||||||
Send comments, etc., to the Bro mailing list, bro@bro-ids.org.
|
|
||||||
However, please note that you must first subscribe to the list in
|
|
||||||
order to be able to post to it.
|
|
||||||
|
|
||||||
- Vern Paxson & Robin Sommer, on behalf of the Bro development team
|
|
||||||
|
|
||||||
|
Vern Paxson & Robin Sommer,
|
||||||
|
International Computer Science Institute &
|
||||||
Lawrence Berkeley National Laboratory
|
Lawrence Berkeley National Laboratory
|
||||||
University of California, Berkeley USA
|
|
||||||
|
|
||||||
ICSI Center for Internet Research (ICIR)
|
|
||||||
International Computer Science Institute
|
|
||||||
Berkeley, CA USA
|
|
||||||
vern@icir.org / robin@icir.org
|
vern@icir.org / robin@icir.org
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.6-dev.3
|
2.0-57
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4e1dad4ee69b85d04af72c0faaff47fddf3240e2
|
Subproject commit 43308aab47a3357ca1885e1b6954154a2744d821
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7b829fbe8d6fa36c33c0c07a8f09cc0d68cd17f1
|
Subproject commit 139cc2e1e049c4e1cc7e95f20866102be1d3d599
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2bf6c82eed841d2a8e7104875717296fe50ca126
|
Subproject commit 930e7c78221929849086a578308e2fdc99ac3fb8
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0d8b64252f00f147f31f5e8c02a6a710699b67d9
|
Subproject commit e908ba686dceb56065bdf569c18dd0f67f662f6b
|
1
aux/btest
Submodule
1
aux/btest
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ee87db37b520b88a55323a9767234c30b801e439
|
|
@ -1,20 +1,19 @@
|
||||||
# After configured by CMake, this file prints the absolute path to policy
|
#!/bin/sh
|
||||||
# files that come with the source distributions of Bro and Broctl as well
|
# After configured by CMake, this file prints the absolute path to Bro scripts
|
||||||
# as policy files that are generated by the BIF compiler at compile time
|
# that come with the source distributions of Bro as well as scripts that are
|
||||||
|
# generated by the BIF compiler at compile time.
|
||||||
#
|
#
|
||||||
# The intended use of this script is to make it easier to run Bro from
|
# The intended use of this script is to make it easier to run Bro from
|
||||||
# the build directory, avoiding the need to install it. This could be
|
# the build directory, avoiding the need to install it. This could be
|
||||||
# done like:
|
# done like:
|
||||||
#
|
#
|
||||||
# BROPATH=`source bro-path-dev` ./src/bro
|
# BROPATH=`./bro-path-dev` ./src/bro
|
||||||
#
|
#
|
||||||
|
|
||||||
broPolicies=${PROJECT_SOURCE_DIR}/policy:${PROJECT_SOURCE_DIR}/policy/sigs:${PROJECT_SOURCE_DIR}/policy/time-machine
|
broPolicies=${BRO_SCRIPT_SOURCE_PATH}:${BRO_SCRIPT_SOURCE_PATH}/policy:${BRO_SCRIPT_SOURCE_PATH}/site
|
||||||
|
|
||||||
broGenPolicies=${CMAKE_BINARY_DIR}/src
|
broGenPolicies=${CMAKE_BINARY_DIR}/src
|
||||||
|
|
||||||
broctlPolicies=${PROJECT_SOURCE_DIR}/aux/broctl/policy:${CMAKE_BINARY_DIR}/aux/broctl/policy/local
|
installedPolicies=${BRO_SCRIPT_INSTALL_PATH}:${BRO_SCRIPT_INSTALL_PATH}/site
|
||||||
|
|
||||||
installedPolicies=${POLICYDIR}:${POLICYDIR}/sigs:${POLICYDIR}/time-machine:${POLICYDIR}/site
|
echo .:$broPolicies:$broGenPolicies
|
||||||
|
|
||||||
echo .:$broPolicies:$broGenPolicies:$broctlPolicies
|
|
||||||
|
|
1
cmake
Submodule
1
cmake
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2cc105577044a2d214124568f3f2496ed2ccbb34
|
|
@ -1,87 +0,0 @@
|
||||||
# Calling this macro with the name of a list variable will modify that
|
|
||||||
# list such that any third party libraries that do not come with a
|
|
||||||
# vanilla Mac OS X system will be replaced by an adjusted library that
|
|
||||||
# has an install_name relative to the location of any executable that
|
|
||||||
# links to it.
|
|
||||||
#
|
|
||||||
# Also, it will schedule the modified libraries for installation in a
|
|
||||||
# 'support_libs' subdirectory of the CMAKE_INSTALL_PREFIX.
|
|
||||||
#
|
|
||||||
# The case of third party libraries depending on other third party
|
|
||||||
# libraries is currently not handled by this macro.
|
|
||||||
#
|
|
||||||
# Ex.
|
|
||||||
#
|
|
||||||
# set(libs /usr/lib/libz.dylib
|
|
||||||
# /usr/lib/libssl.dylib
|
|
||||||
# /usr/local/lib/libmagic.dylib
|
|
||||||
# /usr/local/lib/libGeoIP.dylib
|
|
||||||
# /usr/local/lib/somestaticlib.a)
|
|
||||||
#
|
|
||||||
# include(ChangeMacInstallNames)
|
|
||||||
# ChangeMacInstallNames(libs)
|
|
||||||
#
|
|
||||||
# Should result in ${libs} containing:
|
|
||||||
# /usr/lib/libz.dylib
|
|
||||||
# /usr/lib/libssl.dylib
|
|
||||||
# ${CMAKE_BINARY_DIR}/darwin_support_libs/libmagic.dylib
|
|
||||||
# ${CMAKE_BINARY_DIR}/darwin_support_libs/libGeoIP.dylib
|
|
||||||
# /usr/local/lib/somestaticlib.a
|
|
||||||
#
|
|
||||||
# such that we can now do:
|
|
||||||
#
|
|
||||||
# add_executable(some_exe ${srcs})
|
|
||||||
# target_link_libraries(some_exe ${libs})
|
|
||||||
#
|
|
||||||
# Any binary packages created from such a build should be self-contained
|
|
||||||
# and provide working installs on vanilla OS X systems.
|
|
||||||
|
|
||||||
macro(ChangeMacInstallNames libListVar)
|
|
||||||
if (APPLE)
|
|
||||||
find_program(INSTALL_NAME_TOOL install_name_tool)
|
|
||||||
|
|
||||||
set(MAC_INSTALL_NAME_DEPS)
|
|
||||||
set(SUPPORT_BIN_DIR ${CMAKE_BINARY_DIR}/darwin_support_libs)
|
|
||||||
set(SUPPORT_INSTALL_DIR support_libs)
|
|
||||||
|
|
||||||
file(MAKE_DIRECTORY ${SUPPORT_BIN_DIR})
|
|
||||||
|
|
||||||
foreach (_lib ${${libListVar}})
|
|
||||||
# only care about install_name for shared libraries that are
|
|
||||||
# not shipped in Apple's vanilla OS X installs
|
|
||||||
string(REGEX MATCH ^/usr/lib/* apple_provided_lib ${_lib})
|
|
||||||
string(REGEX MATCH dylib$ is_shared_lib ${_lib})
|
|
||||||
|
|
||||||
if (NOT apple_provided_lib AND is_shared_lib)
|
|
||||||
get_filename_component(_libname ${_lib} NAME)
|
|
||||||
set(_adjustedLib ${SUPPORT_BIN_DIR}/${_libname})
|
|
||||||
set(_tmpLib
|
|
||||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname})
|
|
||||||
|
|
||||||
# make a tempory copy so we can adjust permissions
|
|
||||||
configure_file(${_lib} ${_tmpLib} COPYONLY)
|
|
||||||
|
|
||||||
# copy to build directory with correct write permissions
|
|
||||||
file(COPY ${_tmpLib}
|
|
||||||
DESTINATION ${SUPPORT_BIN_DIR}
|
|
||||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
|
|
||||||
GROUP_READ WORLD_READ)
|
|
||||||
|
|
||||||
# remove the old library from the list provided as macro
|
|
||||||
# argument and add the new library with modified install_name
|
|
||||||
list(REMOVE_ITEM ${libListVar} ${_lib})
|
|
||||||
list(APPEND ${libListVar} ${_adjustedLib})
|
|
||||||
|
|
||||||
# update the install target to install the third party libs
|
|
||||||
# with modified install_name
|
|
||||||
install(FILES ${_adjustedLib}
|
|
||||||
DESTINATION ${SUPPORT_INSTALL_DIR})
|
|
||||||
|
|
||||||
# perform the install_name change
|
|
||||||
execute_process(COMMAND install_name_tool -id
|
|
||||||
@executable_path/../${SUPPORT_INSTALL_DIR}/${_libname}
|
|
||||||
${_adjustedLib})
|
|
||||||
endif ()
|
|
||||||
endforeach ()
|
|
||||||
endif ()
|
|
||||||
endmacro()
|
|
|
@ -1,15 +0,0 @@
|
||||||
include(CheckFunctionExists)
|
|
||||||
|
|
||||||
check_function_exists(getopt_long HAVE_GETOPT_LONG)
|
|
||||||
check_function_exists(mallinfo HAVE_MALLINFO)
|
|
||||||
check_function_exists(strcasestr HAVE_STRCASESTR)
|
|
||||||
check_function_exists(strerror HAVE_STRERROR)
|
|
||||||
check_function_exists(strsep HAVE_STRSEP)
|
|
||||||
check_function_exists(sigset HAVE_SIGSET)
|
|
||||||
|
|
||||||
if (HAVE_SIGSET)
|
|
||||||
set(SIG_FUNC sigset)
|
|
||||||
else ()
|
|
||||||
set(SIG_FUNC signal)
|
|
||||||
check_function_exists(sigaction HAVE_SIGACTION)
|
|
||||||
endif ()
|
|
|
@ -1,28 +0,0 @@
|
||||||
include(CheckIncludeFiles)
|
|
||||||
include(CheckStructHasMember)
|
|
||||||
|
|
||||||
check_include_files(getopt.h HAVE_GETOPT_H)
|
|
||||||
check_include_files(magic.h HAVE_MAGIC_H)
|
|
||||||
check_include_files(memory.h HAVE_MEMORY_H)
|
|
||||||
check_include_files("sys/socket.h;netinet/in.h;net/if.h;netinet/if_ether.h"
|
|
||||||
HAVE_NETINET_IF_ETHER_H)
|
|
||||||
check_include_files("sys/socket.h;netinet/in.h;net/if.h;netinet/ip6.h"
|
|
||||||
HAVE_NETINET_IP6_H)
|
|
||||||
check_include_files("sys/socket.h;net/if.h;net/ethernet.h" HAVE_NET_ETHERNET_H)
|
|
||||||
check_include_files(sys/ethernet.h HAVE_SYS_ETHERNET_H)
|
|
||||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
|
||||||
check_include_files("time.h;sys/time.h" TIME_WITH_SYS_TIME)
|
|
||||||
check_include_files(os-proto.h HAVE_OS_PROTO_H)
|
|
||||||
|
|
||||||
check_struct_has_member(HISTORY_STATE entries "stdio.h;readline/readline.h"
|
|
||||||
HAVE_READLINE_HISTORY_ENTRIES)
|
|
||||||
check_include_files("stdio.h;readline/readline.h" HAVE_READLINE_READLINE_H)
|
|
||||||
check_include_files("stdio.h;readline/history.h" HAVE_READLINE_HISTORY_H)
|
|
||||||
|
|
||||||
if (HAVE_READLINE_READLINE_H AND
|
|
||||||
HAVE_READLINE_HISTORY_H AND
|
|
||||||
HAVE_READLINE_HISTORY_ENTRIES)
|
|
||||||
set(HAVE_READLINE true)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_struct_has_member("struct sockaddr_in" sin_len "netinet/in.h" SIN_LEN)
|
|
|
@ -1,21 +0,0 @@
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
|
|
||||||
# Check whether the namser compatibility header is required
|
|
||||||
# This can be the case on the Darwin platform
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <arpa/nameser.h>
|
|
||||||
int main() { HEADER *hdr; int d = NS_IN6ADDRSZ; return 0; }"
|
|
||||||
have_nameser_header)
|
|
||||||
|
|
||||||
if (NOT have_nameser_header)
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <arpa/nameser.h>
|
|
||||||
#include <arpa/nameser_compat.h>
|
|
||||||
int main() { HEADER *hdr; int d = NS_IN6ADDRSZ; return 0; }"
|
|
||||||
NEED_NAMESER_COMPAT_H)
|
|
||||||
if (NOT NEED_NAMESER_COMPAT_H)
|
|
||||||
message(FATAL_ERROR
|
|
||||||
"Asynchronous DNS support compatibility check failed.")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
|
@ -1,46 +0,0 @@
|
||||||
include(CheckTypeSize)
|
|
||||||
|
|
||||||
check_type_size("long int" SIZEOF_LONG_INT)
|
|
||||||
check_type_size("long long" SIZEOF_LONG_LONG)
|
|
||||||
check_type_size("void *" SIZEOF_VOID_P)
|
|
||||||
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h)
|
|
||||||
|
|
||||||
check_type_size(int32_t INT32_T)
|
|
||||||
if (INT32_T)
|
|
||||||
set(INT32_T int32_t)
|
|
||||||
else()
|
|
||||||
set(INT32_T int)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
check_type_size(u_int32_t U_INT32_T)
|
|
||||||
if (U_INT32_T)
|
|
||||||
set(U_INT32_T u_int32_t)
|
|
||||||
else ()
|
|
||||||
set(INT32_T u_int)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_type_size(u_int16_t U_INT16_T)
|
|
||||||
if (U_INT16_T)
|
|
||||||
set(U_INT16_T u_int16_t)
|
|
||||||
else ()
|
|
||||||
set(INT16_T u_short)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_type_size(u_int8_t U_INT8_T)
|
|
||||||
if (U_INT8_T)
|
|
||||||
set(U_INT8_T u_int8_t)
|
|
||||||
else ()
|
|
||||||
set(INT8_T u_char)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
|
||||||
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
|
|
||||||
check_type_size(socklen_t SOCKLEN_T)
|
|
||||||
if (SOCKLEN_T)
|
|
||||||
set(SOCKLEN_T socklen_t)
|
|
||||||
else ()
|
|
||||||
set(SOCKLEN_T int)
|
|
||||||
endif ()
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
|
|
@ -1,101 +0,0 @@
|
||||||
# - Try to find libpcap include dirs and libraries
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(BIND)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# BIND_ROOT_DIR Set this variable to the root installation of BIND
|
|
||||||
# if the module has problems finding the proper
|
|
||||||
# installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# BIND_FOUND System has BIND, include and library dirs found
|
|
||||||
# BIND_INCLUDE_DIR The BIND include directories.
|
|
||||||
# BIND_LIBRARY The BIND library (if any) required for
|
|
||||||
# ns_inittab and res_mkquery symbols
|
|
||||||
|
|
||||||
find_path(BIND_ROOT_DIR
|
|
||||||
NAMES include/resolv.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(BIND_INCLUDE_DIR
|
|
||||||
NAMES resolv.h
|
|
||||||
HINTS ${BIND_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|
||||||
# the static resolv library is preferred because
|
|
||||||
# on some systems, the ns_initparse symbol is not
|
|
||||||
# exported in the shared library (strangely)
|
|
||||||
# see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=291609
|
|
||||||
set(bind_libs none libresolv.a resolv bind)
|
|
||||||
else ()
|
|
||||||
set(bind_libs none resolv bind)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
|
|
||||||
# Find which library has the res_mkquery and ns_initparse symbols
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${BIND_INCLUDE_DIR})
|
|
||||||
foreach (bindlib ${bind_libs})
|
|
||||||
if (NOT ${bindlib} MATCHES "none")
|
|
||||||
find_library(BIND_LIBRARY
|
|
||||||
NAMES ${bindlib}
|
|
||||||
HINTS ${BIND_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${BIND_LIBRARY})
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <arpa/nameser.h>
|
|
||||||
int main() {
|
|
||||||
ns_initparse(0, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" ns_initparse_works_${bindlib})
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/nameser.h>
|
|
||||||
#include <resolv.h>
|
|
||||||
int main() {
|
|
||||||
int (*p)() = res_mkquery;
|
|
||||||
}
|
|
||||||
" res_mkquery_works_${bindlib})
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
|
|
||||||
if (ns_initparse_works_${bindlib} AND res_mkquery_works_${bindlib})
|
|
||||||
break ()
|
|
||||||
else ()
|
|
||||||
set(BIND_LIBRARY BIND_LIBRARY-NOTFOUND)
|
|
||||||
endif ()
|
|
||||||
endforeach ()
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
|
|
||||||
if (ns_initparse_works_none AND res_mkquery_works_none)
|
|
||||||
# system does not require linking to a BIND library
|
|
||||||
find_package_handle_standard_args(BIND DEFAULT_MSG
|
|
||||||
BIND_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
else ()
|
|
||||||
find_package_handle_standard_args(BIND DEFAULT_MSG
|
|
||||||
BIND_LIBRARY
|
|
||||||
BIND_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
BIND_ROOT_DIR
|
|
||||||
BIND_LIBRARY
|
|
||||||
BIND_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,221 +0,0 @@
|
||||||
# - Find bison executable and provides macros to generate custom build rules
|
|
||||||
# The module defines the following variables:
|
|
||||||
#
|
|
||||||
# BISON_EXECUTABLE - path to the bison program
|
|
||||||
# BISON_VERSION - version of bison
|
|
||||||
# BISON_FOUND - true if the program was found
|
|
||||||
#
|
|
||||||
# If bison is found, the module defines the macros:
|
|
||||||
# BISON_TARGET(<Name> <YaccInput> <CodeOutput> [VERBOSE <file>]
|
|
||||||
# [COMPILE_FLAGS <string>] [HEADER <FILE>])
|
|
||||||
# which will create a custom rule to generate a parser. <YaccInput> is
|
|
||||||
# the path to a yacc file. <CodeOutput> is the name of the source file
|
|
||||||
# generated by bison. A header file containing the token list is also
|
|
||||||
# generated according to bison's -d option by default or if the HEADER
|
|
||||||
# option is used, the argument is passed to bison's --defines option to
|
|
||||||
# specify output file. If COMPILE_FLAGS option is specified, the next
|
|
||||||
# parameter is added in the bison command line. if VERBOSE option is
|
|
||||||
# specified, <file> is created and contains verbose descriptions of the
|
|
||||||
# grammar and parser. The macro defines a set of variables:
|
|
||||||
# BISON_${Name}_DEFINED - true is the macro ran successfully
|
|
||||||
# BISON_${Name}_INPUT - The input source file, an alias for <YaccInput>
|
|
||||||
# BISON_${Name}_OUTPUT_SOURCE - The source file generated by bison
|
|
||||||
# BISON_${Name}_OUTPUT_HEADER - The header file generated by bison
|
|
||||||
# BISON_${Name}_OUTPUTS - The sources files generated by bison
|
|
||||||
# BISON_${Name}_COMPILE_FLAGS - Options used in the bison command line
|
|
||||||
#
|
|
||||||
# ====================================================================
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# find_package(BISON)
|
|
||||||
# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
|
|
||||||
# add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
|
|
||||||
# ====================================================================
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2009 Kitware, Inc.
|
|
||||||
# Copyright 2006 Tristan Carel
|
|
||||||
# Modified 2010 by Jon Siwek, adding HEADER option
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License"):
|
|
||||||
# CMake - Cross Platform Makefile Generator
|
|
||||||
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
|
||||||
# All rights reserved.
|
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
#
|
|
||||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
|
||||||
# nor the names of their contributors may be used to endorse or promote
|
|
||||||
# products derived from this software without specific prior written
|
|
||||||
# permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
|
|
||||||
FIND_PROGRAM(BISON_EXECUTABLE bison DOC "path to the bison executable")
|
|
||||||
MARK_AS_ADVANCED(BISON_EXECUTABLE)
|
|
||||||
|
|
||||||
IF(BISON_EXECUTABLE)
|
|
||||||
|
|
||||||
EXECUTE_PROCESS(COMMAND ${BISON_EXECUTABLE} --version
|
|
||||||
OUTPUT_VARIABLE BISON_version_output
|
|
||||||
ERROR_VARIABLE BISON_version_error
|
|
||||||
RESULT_VARIABLE BISON_version_result
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
IF(NOT ${BISON_version_result} EQUAL 0)
|
|
||||||
MESSAGE(SEND_ERROR "Command \"${BISON_EXECUTABLE} --version\" failed with output:\n${BISON_version_error}")
|
|
||||||
ELSE()
|
|
||||||
STRING(REGEX REPLACE "^bison \\(GNU Bison\\) ([^\n]+)\n.*" "\\1"
|
|
||||||
BISON_VERSION "${BISON_version_output}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# internal macro
|
|
||||||
MACRO(BISON_TARGET_option_verbose Name BisonOutput filename)
|
|
||||||
LIST(APPEND BISON_TARGET_cmdopt "--verbose")
|
|
||||||
GET_FILENAME_COMPONENT(BISON_TARGET_output_path "${BisonOutput}" PATH)
|
|
||||||
GET_FILENAME_COMPONENT(BISON_TARGET_output_name "${BisonOutput}" NAME_WE)
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT ${filename}
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
ARGS -E copy
|
|
||||||
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
|
|
||||||
"${filename}"
|
|
||||||
DEPENDS
|
|
||||||
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
|
|
||||||
COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}"
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
SET(BISON_${Name}_VERBOSE_FILE ${filename})
|
|
||||||
LIST(APPEND BISON_TARGET_extraoutputs
|
|
||||||
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output")
|
|
||||||
ENDMACRO(BISON_TARGET_option_verbose)
|
|
||||||
|
|
||||||
# internal macro
|
|
||||||
MACRO(BISON_TARGET_option_extraopts Options)
|
|
||||||
SET(BISON_TARGET_extraopts "${Options}")
|
|
||||||
SEPARATE_ARGUMENTS(BISON_TARGET_extraopts)
|
|
||||||
LIST(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
|
|
||||||
ENDMACRO(BISON_TARGET_option_extraopts)
|
|
||||||
|
|
||||||
#============================================================
|
|
||||||
# BISON_TARGET (public macro)
|
|
||||||
#============================================================
|
|
||||||
#
|
|
||||||
MACRO(BISON_TARGET Name BisonInput BisonOutput)
|
|
||||||
SET(BISON_TARGET_output_header "")
|
|
||||||
#SET(BISON_TARGET_command_opt "")
|
|
||||||
SET(BISON_TARGET_cmdopt "")
|
|
||||||
SET(BISON_TARGET_outputs "${BisonOutput}")
|
|
||||||
IF(NOT ${ARGC} EQUAL 3 AND
|
|
||||||
NOT ${ARGC} EQUAL 5 AND
|
|
||||||
NOT ${ARGC} EQUAL 7 AND
|
|
||||||
NOT ${ARGC} EQUAL 9)
|
|
||||||
MESSAGE(SEND_ERROR "Usage")
|
|
||||||
ELSE()
|
|
||||||
# Parsing parameters
|
|
||||||
IF(${ARGC} GREATER 5 OR ${ARGC} EQUAL 5)
|
|
||||||
IF("${ARGV3}" STREQUAL "VERBOSE")
|
|
||||||
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV4}")
|
|
||||||
ENDIF()
|
|
||||||
IF("${ARGV3}" STREQUAL "COMPILE_FLAGS")
|
|
||||||
BISON_TARGET_option_extraopts("${ARGV4}")
|
|
||||||
ENDIF()
|
|
||||||
IF("${ARGV3}" STREQUAL "HEADER")
|
|
||||||
set(BISON_TARGET_output_header "${ARGV4}")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(${ARGC} GREATER 7 OR ${ARGC} EQUAL 7)
|
|
||||||
IF("${ARGV5}" STREQUAL "VERBOSE")
|
|
||||||
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV6}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF("${ARGV5}" STREQUAL "COMPILE_FLAGS")
|
|
||||||
BISON_TARGET_option_extraopts("${ARGV6}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF("${ARGV5}" STREQUAL "HEADER")
|
|
||||||
set(BISON_TARGET_output_header "${ARGV6}")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(${ARGC} EQUAL 9)
|
|
||||||
IF("${ARGV7}" STREQUAL "VERBOSE")
|
|
||||||
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV8}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF("${ARGV7}" STREQUAL "COMPILE_FLAGS")
|
|
||||||
BISON_TARGET_option_extraopts("${ARGV8}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF("${ARGV7}" STREQUAL "HEADER")
|
|
||||||
set(BISON_TARGET_output_header "${ARGV8}")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(BISON_TARGET_output_header)
|
|
||||||
# Header's name passed in as argument to be used in --defines option
|
|
||||||
LIST(APPEND BISON_TARGET_cmdopt
|
|
||||||
"--defines=${BISON_TARGET_output_header}")
|
|
||||||
set(BISON_${Name}_OUTPUT_HEADER ${BISON_TARGET_output_header})
|
|
||||||
ELSE()
|
|
||||||
# Header's name generated by bison (see option -d)
|
|
||||||
LIST(APPEND BISON_TARGET_cmdopt "-d")
|
|
||||||
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${ARGV2}")
|
|
||||||
STRING(REPLACE "c" "h" _fileext ${_fileext})
|
|
||||||
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
|
|
||||||
BISON_${Name}_OUTPUT_HEADER "${ARGV2}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
LIST(APPEND BISON_TARGET_outputs "${BISON_${Name}_OUTPUT_HEADER}")
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT ${BISON_TARGET_outputs}
|
|
||||||
${BISON_TARGET_extraoutputs}
|
|
||||||
COMMAND ${BISON_EXECUTABLE}
|
|
||||||
ARGS ${BISON_TARGET_cmdopt} -o ${ARGV2} ${ARGV1}
|
|
||||||
DEPENDS ${ARGV1}
|
|
||||||
COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
# define target variables
|
|
||||||
SET(BISON_${Name}_DEFINED TRUE)
|
|
||||||
SET(BISON_${Name}_INPUT ${ARGV1})
|
|
||||||
SET(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs})
|
|
||||||
SET(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
|
|
||||||
SET(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
|
|
||||||
|
|
||||||
ENDIF(NOT ${ARGC} EQUAL 3 AND
|
|
||||||
NOT ${ARGC} EQUAL 5 AND
|
|
||||||
NOT ${ARGC} EQUAL 7 AND
|
|
||||||
NOT ${ARGC} EQUAL 9)
|
|
||||||
ENDMACRO(BISON_TARGET)
|
|
||||||
#
|
|
||||||
#============================================================
|
|
||||||
|
|
||||||
ENDIF(BISON_EXECUTABLE)
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON DEFAULT_MSG BISON_EXECUTABLE)
|
|
||||||
|
|
||||||
# FindBISON.cmake ends here
|
|
|
@ -1,53 +0,0 @@
|
||||||
# - Try to find BinPAC binary and library
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(BinPAC)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# BinPAC_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# BinPAC if the module has problems finding the
|
|
||||||
# proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# BINPAC_FOUND System has BinPAC binary and library
|
|
||||||
# BinPAC_EXE The binpac executable
|
|
||||||
# BinPAC_LIBRARY The libbinpac.a library
|
|
||||||
# BinPAC_INCLUDE_DIR The binpac headers
|
|
||||||
|
|
||||||
# look for BinPAC in standard locations or user-provided root
|
|
||||||
find_path(BinPAC_ROOT_DIR
|
|
||||||
NAMES include/binpac.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_file(BinPAC_EXE
|
|
||||||
NAMES binpac
|
|
||||||
HINTS ${BinPAC_ROOT_DIR}/bin
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(BinPAC_LIBRARY
|
|
||||||
NAMES libbinpac.a
|
|
||||||
HINTS ${BinPAC_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(BinPAC_INCLUDE_DIR
|
|
||||||
NAMES binpac.h
|
|
||||||
HINTS ${BinPAC_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(BinPAC DEFAULT_MSG
|
|
||||||
BinPAC_EXE
|
|
||||||
BinPAC_LIBRARY
|
|
||||||
BinPAC_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
BinPAC_ROOT_DIR
|
|
||||||
BinPAC_EXE
|
|
||||||
BinPAC_LIBRARY
|
|
||||||
BinPAC_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,179 +0,0 @@
|
||||||
# - Find flex executable and provides a macro to generate custom build rules
|
|
||||||
#
|
|
||||||
# The module defines the following variables:
|
|
||||||
# FLEX_FOUND - true is flex executable is found
|
|
||||||
# FLEX_EXECUTABLE - the path to the flex executable
|
|
||||||
# FLEX_VERSION - the version of flex
|
|
||||||
# FLEX_LIBRARIES - The flex libraries
|
|
||||||
#
|
|
||||||
# The minimum required version of flex can be specified using the
|
|
||||||
# standard syntax, e.g. FIND_PACKAGE(FLEX 2.5.13)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# If flex is found on the system, the module provides the macro:
|
|
||||||
# FLEX_TARGET(Name FlexInput FlexOutput [COMPILE_FLAGS <string>])
|
|
||||||
# which creates a custom command to generate the <FlexOutput> file from
|
|
||||||
# the <FlexInput> file. If COMPILE_FLAGS option is specified, the next
|
|
||||||
# parameter is added to the flex command line. Name is an alias used to
|
|
||||||
# get details of this custom command. Indeed the macro defines the
|
|
||||||
# following variables:
|
|
||||||
# FLEX_${Name}_DEFINED - true is the macro ran successfully
|
|
||||||
# FLEX_${Name}_OUTPUTS - the source file generated by the custom rule, an
|
|
||||||
# alias for FlexOutput
|
|
||||||
# FLEX_${Name}_INPUT - the flex source file, an alias for ${FlexInput}
|
|
||||||
#
|
|
||||||
# Flex scanners oftenly use tokens defined by Bison: the code generated
|
|
||||||
# by Flex depends of the header generated by Bison. This module also
|
|
||||||
# defines a macro:
|
|
||||||
# ADD_FLEX_BISON_DEPENDENCY(FlexTarget BisonTarget)
|
|
||||||
# which adds the required dependency between a scanner and a parser
|
|
||||||
# where <FlexTarget> and <BisonTarget> are the first parameters of
|
|
||||||
# respectively FLEX_TARGET and BISON_TARGET macros.
|
|
||||||
#
|
|
||||||
# ====================================================================
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# find_package(BISON)
|
|
||||||
# find_package(FLEX)
|
|
||||||
#
|
|
||||||
# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
|
|
||||||
# FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BIANRY_DIR}/lexer.cpp)
|
|
||||||
# ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
|
|
||||||
#
|
|
||||||
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
# add_executable(Foo
|
|
||||||
# Foo.cc
|
|
||||||
# ${BISON_MyParser_OUTPUTS}
|
|
||||||
# ${FLEX_MyScanner_OUTPUTS}
|
|
||||||
# )
|
|
||||||
# ====================================================================
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2009 Kitware, Inc.
|
|
||||||
# Copyright 2006 Tristan Carel
|
|
||||||
# Modified 2010 by Jon Siwek, backporting for CMake 2.6 compat
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License"):
|
|
||||||
# CMake - Cross Platform Makefile Generator
|
|
||||||
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
|
||||||
# All rights reserved.
|
|
||||||
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
#
|
|
||||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
|
||||||
# nor the names of their contributors may be used to endorse or promote
|
|
||||||
# products derived from this software without specific prior written
|
|
||||||
# permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
|
|
||||||
FIND_PROGRAM(FLEX_EXECUTABLE flex DOC "path to the flex executable")
|
|
||||||
MARK_AS_ADVANCED(FLEX_EXECUTABLE)
|
|
||||||
|
|
||||||
FIND_LIBRARY(FL_LIBRARY NAMES fl
|
|
||||||
DOC "path to the fl library")
|
|
||||||
MARK_AS_ADVANCED(FL_LIBRARY)
|
|
||||||
SET(FLEX_LIBRARIES ${FL_LIBRARY})
|
|
||||||
|
|
||||||
IF(FLEX_EXECUTABLE)
|
|
||||||
|
|
||||||
EXECUTE_PROCESS(COMMAND ${FLEX_EXECUTABLE} --version
|
|
||||||
OUTPUT_VARIABLE FLEX_version_output
|
|
||||||
ERROR_VARIABLE FLEX_version_error
|
|
||||||
RESULT_VARIABLE FLEX_version_result
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
IF(NOT ${FLEX_version_result} EQUAL 0)
|
|
||||||
IF(FLEX_FIND_REQUIRED)
|
|
||||||
MESSAGE(SEND_ERROR "Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE("Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available")
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
STRING(REGEX REPLACE "^flex (.*)$" "\\1"
|
|
||||||
FLEX_VERSION "${FLEX_version_output}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#============================================================
|
|
||||||
# FLEX_TARGET (public macro)
|
|
||||||
#============================================================
|
|
||||||
#
|
|
||||||
MACRO(FLEX_TARGET Name Input Output)
|
|
||||||
SET(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]")
|
|
||||||
IF(${ARGC} GREATER 3)
|
|
||||||
IF(${ARGC} EQUAL 5)
|
|
||||||
IF("${ARGV3}" STREQUAL "COMPILE_FLAGS")
|
|
||||||
SET(FLEX_EXECUTABLE_opts "${ARGV4}")
|
|
||||||
SEPARATE_ARGUMENTS(FLEX_EXECUTABLE_opts)
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(SEND_ERROR ${FLEX_TARGET_usage})
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(SEND_ERROR ${FLEX_TARGET_usage})
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT ${Output}
|
|
||||||
COMMAND ${FLEX_EXECUTABLE}
|
|
||||||
ARGS ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
|
|
||||||
DEPENDS ${Input}
|
|
||||||
COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
SET(FLEX_${Name}_DEFINED TRUE)
|
|
||||||
SET(FLEX_${Name}_OUTPUTS ${Output})
|
|
||||||
SET(FLEX_${Name}_INPUT ${Input})
|
|
||||||
SET(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
|
|
||||||
ENDMACRO(FLEX_TARGET)
|
|
||||||
#============================================================
|
|
||||||
|
|
||||||
|
|
||||||
#============================================================
|
|
||||||
# ADD_FLEX_BISON_DEPENDENCY (public macro)
|
|
||||||
#============================================================
|
|
||||||
#
|
|
||||||
MACRO(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)
|
|
||||||
|
|
||||||
IF(NOT FLEX_${FlexTarget}_OUTPUTS)
|
|
||||||
MESSAGE(SEND_ERROR "Flex target `${FlexTarget}' does not exists.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(NOT BISON_${BisonTarget}_OUTPUT_HEADER)
|
|
||||||
MESSAGE(SEND_ERROR "Bison target `${BisonTarget}' does not exists.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(${FLEX_${FlexTarget}_OUTPUTS}
|
|
||||||
PROPERTIES OBJECT_DEPENDS ${BISON_${BisonTarget}_OUTPUT_HEADER})
|
|
||||||
ENDMACRO(ADD_FLEX_BISON_DEPENDENCY)
|
|
||||||
#============================================================
|
|
||||||
|
|
||||||
ENDIF(FLEX_EXECUTABLE)
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLEX FLEX_EXECUTABLE
|
|
||||||
FLEX_VERSION)
|
|
||||||
|
|
||||||
# FindFLEX.cmake ends here
|
|
|
@ -1,44 +0,0 @@
|
||||||
# - Try to find GooglePerftools headers and libraries
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(GooglePerftools)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# GooglePerftools_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# GooglePerftools if the module has problems finding
|
|
||||||
# the proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# GOOGLEPERFTOOLS_FOUND System has GooglePerftools libs/headers
|
|
||||||
# GooglePerftools_LIBRARIES The GooglePerftools libraries
|
|
||||||
# GooglePerftools_INCLUDE_DIR The location of GooglePerftools headers
|
|
||||||
|
|
||||||
find_path(GooglePerftools_ROOT_DIR
|
|
||||||
NAMES include/google/heap-profiler.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(GooglePerftools_LIBRARIES
|
|
||||||
NAMES tcmalloc
|
|
||||||
HINTS ${GooglePerftools_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(GooglePerftools_INCLUDE_DIR
|
|
||||||
NAMES google/heap-profiler.h
|
|
||||||
HINTS ${GooglePerftools_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(GooglePerftools DEFAULT_MSG
|
|
||||||
GooglePerftools_LIBRARIES
|
|
||||||
GooglePerftools_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
GooglePerftools_ROOT_DIR
|
|
||||||
GooglePerftools_LIBRARIES
|
|
||||||
GooglePerftools_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,44 +0,0 @@
|
||||||
# - Try to find GeoIP headers and libraries
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(LibGeoIP)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# LibGeoIP_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# libGeoIP if the module has problems finding the
|
|
||||||
# proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# LIBGEOIP_FOUND System has GeoIP libraries and headers
|
|
||||||
# LibGeoIP_LIBRARY The GeoIP library
|
|
||||||
# LibGeoIP_INCLUDE_DIR The location of GeoIP headers
|
|
||||||
|
|
||||||
find_path(LibGeoIP_ROOT_DIR
|
|
||||||
NAMES include/GeoIPCity.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LibGeoIP_LIBRARY
|
|
||||||
NAMES GeoIP
|
|
||||||
HINTS ${LibGeoIP_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(LibGeoIP_INCLUDE_DIR
|
|
||||||
NAMES GeoIPCity.h
|
|
||||||
HINTS ${LibGeoIP_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(LibGeoIP DEFAULT_MSG
|
|
||||||
LibGeoIP_LIBRARY
|
|
||||||
LibGeoIP_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
LibGeoIP_ROOT_DIR
|
|
||||||
LibGeoIP_LIBRARY
|
|
||||||
LibGeoIP_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,44 +0,0 @@
|
||||||
# - Try to find libmagic header and library
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(LibMagic)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# LibMagic_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# libmagic if the module has problems finding the
|
|
||||||
# proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# LIBMAGIC_FOUND System has libmagic and magic.h
|
|
||||||
# LibMagic_LIBRARY The libmagic library
|
|
||||||
# LibMagic_INCLUDE_DIR The location of magic.h
|
|
||||||
|
|
||||||
find_path(LibMagic_ROOT_DIR
|
|
||||||
NAMES include/magic.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LibMagic_LIBRARY
|
|
||||||
NAMES magic
|
|
||||||
HINTS ${LibMagic_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(LibMagic_INCLUDE_DIR
|
|
||||||
NAMES magic.h
|
|
||||||
HINTS ${LibMagic_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(LibMagic DEFAULT_MSG
|
|
||||||
LibMagic_LIBRARY
|
|
||||||
LibMagic_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
LibMagic_ROOT_DIR
|
|
||||||
LibMagic_LIBRARY
|
|
||||||
LibMagic_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,56 +0,0 @@
|
||||||
# - Try to find openssl include dirs and libraries
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(OpenSSL)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# OpenSSL_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# openssl if the module has problems finding the
|
|
||||||
# proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# OPENSSL_FOUND System has openssl, include and library dirs found
|
|
||||||
# OpenSSL_INCLUDE_DIR The openssl include directories.
|
|
||||||
# OpenSSL_LIBRARIES The openssl libraries.
|
|
||||||
# OpenSSL_CYRPTO_LIBRARY The openssl crypto library.
|
|
||||||
# OpenSSL_SSL_LIBRARY The openssl ssl library.
|
|
||||||
|
|
||||||
find_path(OpenSSL_ROOT_DIR
|
|
||||||
NAMES include/openssl/ssl.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(OpenSSL_INCLUDE_DIR
|
|
||||||
NAMES openssl/ssl.h
|
|
||||||
HINTS ${OpenSSL_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(OpenSSL_SSL_LIBRARY
|
|
||||||
NAMES ssl ssleay32 ssleay32MD
|
|
||||||
HINTS ${OpenSSL_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(OpenSSL_CRYPTO_LIBRARY
|
|
||||||
NAMES crypto
|
|
||||||
HINTS ${OpenSSL_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
set(OpenSSL_LIBRARIES ${OpenSSL_SSL_LIBRARY} ${OpenSSL_CRYPTO_LIBRARY}
|
|
||||||
CACHE STRING "OpenSSL SSL and crypto libraries" FORCE)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(OpenSSL DEFAULT_MSG
|
|
||||||
OpenSSL_LIBRARIES
|
|
||||||
OpenSSL_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
OpenSSL_ROOT_DIR
|
|
||||||
OpenSSL_INCLUDE_DIR
|
|
||||||
OpenSSL_LIBRARIES
|
|
||||||
OpenSSL_CRYPTO_LIBRARY
|
|
||||||
OpenSSL_SSL_LIBRARY
|
|
||||||
)
|
|
|
@ -1,44 +0,0 @@
|
||||||
# - Try to find libpcap include dirs and libraries
|
|
||||||
#
|
|
||||||
# Usage of this module as follows:
|
|
||||||
#
|
|
||||||
# find_package(PCAP)
|
|
||||||
#
|
|
||||||
# Variables used by this module, they can change the default behaviour and need
|
|
||||||
# to be set before calling find_package:
|
|
||||||
#
|
|
||||||
# PCAP_ROOT_DIR Set this variable to the root installation of
|
|
||||||
# libpcap if the module has problems finding the
|
|
||||||
# proper installation path.
|
|
||||||
#
|
|
||||||
# Variables defined by this module:
|
|
||||||
#
|
|
||||||
# PCAP_FOUND System has libpcap, include and library dirs found
|
|
||||||
# PCAP_INCLUDE_DIR The libpcap include directories.
|
|
||||||
# PCAP_LIBRARY The libpcap library.
|
|
||||||
|
|
||||||
find_path(PCAP_ROOT_DIR
|
|
||||||
NAMES include/pcap.h
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(PCAP_INCLUDE_DIR
|
|
||||||
NAMES pcap.h
|
|
||||||
HINTS ${PCAP_ROOT_DIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(PCAP_LIBRARY
|
|
||||||
NAMES pcap
|
|
||||||
HINTS ${PCAP_ROOT_DIR}/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(PCAP DEFAULT_MSG
|
|
||||||
PCAP_LIBRARY
|
|
||||||
PCAP_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
PCAP_ROOT_DIR
|
|
||||||
PCAP_INCLUDE_DIR
|
|
||||||
PCAP_LIBRARY
|
|
||||||
)
|
|
|
@ -1,44 +0,0 @@
|
||||||
# A wrapper macro around the standard CMake find_package macro that
|
|
||||||
# facilitates displaying better error messages by default, or even
|
|
||||||
# accepting custom error messages on a per package basis.
|
|
||||||
#
|
|
||||||
# If a package is not found, then the MISSING_PREREQS variable gets
|
|
||||||
# set to true and either a default or custom error message appended
|
|
||||||
# to MISSING_PREREQ_DESCS.
|
|
||||||
#
|
|
||||||
# The caller can use these variables to display a list of any missing
|
|
||||||
# packages and abort the build/configuration if there were any.
|
|
||||||
#
|
|
||||||
# Use as follows:
|
|
||||||
#
|
|
||||||
# include(FindRequiredPackage)
|
|
||||||
# FindRequiredPackage(Perl)
|
|
||||||
# FindRequiredPackage(FLEX "You need to install flex (Fast Lexical Analyzer)")
|
|
||||||
#
|
|
||||||
# if (MISSING_PREREQS)
|
|
||||||
# foreach (prereq ${MISSING_PREREQ_DESCS})
|
|
||||||
# message(SEND_ERROR ${prereq})
|
|
||||||
# endforeach ()
|
|
||||||
# message(FATAL_ERROR "Configuration aborted due to missing prerequisites")
|
|
||||||
# endif ()
|
|
||||||
|
|
||||||
macro(FindRequiredPackage packageName)
|
|
||||||
find_package(${packageName})
|
|
||||||
string(TOUPPER ${packageName} canonPackageName)
|
|
||||||
if (NOT ${canonPackageName}_FOUND)
|
|
||||||
set(MISSING_PREREQS true)
|
|
||||||
|
|
||||||
set(customDesc)
|
|
||||||
foreach (descArg ${ARGN})
|
|
||||||
set(customDesc "${customDesc} ${descArg}")
|
|
||||||
endforeach ()
|
|
||||||
|
|
||||||
if (customDesc)
|
|
||||||
# append the custom error message that was provided as an argument
|
|
||||||
list(APPEND MISSING_PREREQ_DESCS ${customDesc})
|
|
||||||
else ()
|
|
||||||
list(APPEND MISSING_PREREQ_DESCS
|
|
||||||
" Could not find prerequisite package '${packageName}'")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
endmacro(FindRequiredPackage)
|
|
|
@ -1,34 +0,0 @@
|
||||||
include(CheckCXXSourceCompiles)
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
|
|
||||||
# This autoconf variable is obsolete; it's portable to assume C89 and signal
|
|
||||||
# handlers returning void
|
|
||||||
set(RETSIGTYPE "void")
|
|
||||||
set(RETSIGVAL "")
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
extern int socket(int, int, int);
|
|
||||||
extern int connect(int, const struct sockaddr *, int);
|
|
||||||
extern int send(int, const void *, int, int);
|
|
||||||
extern int recvfrom(int, void *, int, int, struct sockaddr *, int *);
|
|
||||||
int main() { return 0; }
|
|
||||||
" DO_SOCK_DECL)
|
|
||||||
if (DO_SOCK_DECL)
|
|
||||||
message(STATUS "socket() and friends need explicit declaration")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
extern \"C\" {
|
|
||||||
int openlog(const char* ident, int logopt, int facility);
|
|
||||||
int syslog(int priority, const char* message_fmt, ...);
|
|
||||||
int closelog();
|
|
||||||
}
|
|
||||||
int main() { return 0; }
|
|
||||||
" SYSLOG_INT)
|
|
||||||
if (SYSLOG_INT)
|
|
||||||
message(STATUS "syslog prototypes need declaration")
|
|
||||||
endif ()
|
|
|
@ -1,66 +0,0 @@
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
|
||||||
# alternate malloc is faster for FreeBSD, but needs more testing
|
|
||||||
# need to add way to set this from the command line
|
|
||||||
set(USE_NMALLOC true)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
|
||||||
set(USE_NMALLOC true)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|
||||||
set(HAVE_LINUX true)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Solaris")
|
|
||||||
set(SOCKET_LIBS nsl socket)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "osf")
|
|
||||||
# Workaround ip_hl vs. ip_vhl problem in netinet/ip.h
|
|
||||||
add_definitions(-D__STDC__=2)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "irix")
|
|
||||||
list(APPEND CMAKE_C_FLAGS -xansi -signed -g3)
|
|
||||||
list(APPEND CMAKE_CXX_FLAGS -xansi -signed -g3)
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "ultrix")
|
|
||||||
list(APPEND CMAKE_C_FLAGS -std1 -g3)
|
|
||||||
list(APPEND CMAKE_CXX_FLAGS -std1 -g3)
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <sys/types.h>
|
|
||||||
int main() {
|
|
||||||
void c(const struct a *);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" have_ultrix_const)
|
|
||||||
if (NOT have_ultrix_const)
|
|
||||||
set(NEED_ULTRIX_CONST_HACK true)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "hpux" OR
|
|
||||||
${CMAKE_SYSTEM_NAME} MATCHES "HP-UX")
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS -Aa)
|
|
||||||
set(CMAKE_REQUIRED_DEFINITIONS -D_HPUX_SOURCE)
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <sys/types.h>
|
|
||||||
int main() {
|
|
||||||
int frob(int, char *);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" have_ansi_prototypes)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS)
|
|
||||||
set(CMAKE_REQUIRED_DEFINITIONS)
|
|
||||||
|
|
||||||
if (have_ansi_prototypes)
|
|
||||||
add_definitions(-D_HPUX_SOURCE)
|
|
||||||
list(APPEND CMAKE_C_FLAGS -Aa)
|
|
||||||
list(APPEND CMAKE_CXX_FLAGS -Aa)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT have_ansi_prototypes)
|
|
||||||
message(FATAL_ERROR "Can't get HPUX compiler to handle ANSI prototypes")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
include(CheckCXXSourceCompiles)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OpenSSL_LIBRARIES})
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR})
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
int main() { return 0; }
|
|
||||||
" including_ssl_h_works)
|
|
||||||
|
|
||||||
if (NOT including_ssl_h_works)
|
|
||||||
# On Red Hat we may need to include Kerberos header.
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR} /usr/kerberos/include)
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <krb5.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
int main() { return 0; }
|
|
||||||
" NEED_KRB5_H)
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR})
|
|
||||||
if (NOT NEED_KRB5_H)
|
|
||||||
message(FATAL_ERROR
|
|
||||||
"OpenSSL test failure. See CmakeError.log for details.")
|
|
||||||
else ()
|
|
||||||
message(STATUS "OpenSSL requires Kerberos header")
|
|
||||||
include_directories("/usr/kerberos/include")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# check for OPENSSL_add_all_algorithms_conf function
|
|
||||||
# and thus OpenSSL >= v0.9.7
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
int main() {
|
|
||||||
OPENSSL_add_all_algorithms_conf();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" openssl_greater_than_0_9_7)
|
|
||||||
|
|
||||||
if (NOT openssl_greater_than_0_9_7)
|
|
||||||
message(FATAL_ERROR "OpenSSL >= v0.9.7 required")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <openssl/x509.h>
|
|
||||||
int main() {
|
|
||||||
const unsigned char** cpp = 0;
|
|
||||||
X509** x =0;
|
|
||||||
d2i_X509(x, cpp, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" OPENSSL_D2I_X509_USES_CONST_CHAR)
|
|
||||||
|
|
||||||
if (NOT OPENSSL_D2I_X509_USES_CONST_CHAR)
|
|
||||||
# double check that it compiles without const
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <openssl/x509.h>
|
|
||||||
int main() {
|
|
||||||
unsigned char** cpp = 0;
|
|
||||||
X509** x =0;
|
|
||||||
d2i_X509(x, cpp, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" OPENSSL_D2I_X509_USES_CHAR)
|
|
||||||
if (NOT OPENSSL_D2I_X509_USES_CHAR)
|
|
||||||
message(FATAL_ERROR
|
|
||||||
"Can't determine if openssl_d2i_x509() takes const char parameter")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES)
|
|
|
@ -1,63 +0,0 @@
|
||||||
include(CheckFunctionExists)
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
include(CheckIncludeFiles)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${LIBPCAP_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
|
||||||
|
|
||||||
check_include_files(pcap-int.h HAVE_PCAP_INT_H)
|
|
||||||
|
|
||||||
check_function_exists(pcap_freecode HAVE_LIBPCAP_PCAP_FREECODE)
|
|
||||||
if (NOT HAVE_LIBPCAP_PCAP_FREECODE)
|
|
||||||
set(DONT_HAVE_LIBPCAP_PCAP_FREECODE true)
|
|
||||||
message(STATUS "No implementation for pcap_freecode()")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <pcap.h>
|
|
||||||
int main () {
|
|
||||||
int snaplen;
|
|
||||||
int linktype;
|
|
||||||
struct bpf_program fp;
|
|
||||||
int optimize;
|
|
||||||
bpf_u_int32 netmask;
|
|
||||||
char str[10];
|
|
||||||
char error[1024];
|
|
||||||
snaplen = 50;
|
|
||||||
linktype = DLT_EN10MB;
|
|
||||||
optimize = 1;
|
|
||||||
netmask = 0L;
|
|
||||||
str[0] = 'i'; str[1] = 'p'; str[2] = '\\\\0';
|
|
||||||
(void)pcap_compile_nopcap(
|
|
||||||
snaplen, linktype, &fp, str, optimize, netmask, &error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER)
|
|
||||||
if (NOT LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER)
|
|
||||||
# double check
|
|
||||||
check_c_source_compiles("
|
|
||||||
#include <pcap.h>
|
|
||||||
int main () {
|
|
||||||
int snaplen;
|
|
||||||
int linktype;
|
|
||||||
struct bpf_program fp;
|
|
||||||
int optimize;
|
|
||||||
bpf_u_int32 netmask;
|
|
||||||
char str[10];
|
|
||||||
snaplen = 50;
|
|
||||||
linktype = DLT_EN10MB;
|
|
||||||
optimize = 1;
|
|
||||||
netmask = 0L;
|
|
||||||
str[0] = 'i'; str[1] = 'p'; str[2] = '\\\\0';
|
|
||||||
(void)pcap_compile_nopcap(snaplen, linktype, &fp, str, optimize, netmask);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" LIBPCAP_PCAP_COMPILE_NOPCAP_NO_ERROR_PARAMETER)
|
|
||||||
if (NOT LIBPCAP_PCAP_COMPILE_NOPCAP_NO_ERROR_PARAMETER)
|
|
||||||
message(FATAL_ERROR
|
|
||||||
"Can't determine if pcap_compile_nopcap takes an error parameter")
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES)
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Sets CPACK_PACKAGE_FILE name in the following format:
|
|
||||||
#
|
|
||||||
# <project_name>-<version>-<OS/platform>-<arch>
|
|
||||||
#
|
|
||||||
# The version must already be set in the VERSION variable
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}")
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CMAKE_SYSTEM_NAME}")
|
|
||||||
if (APPLE)
|
|
||||||
# Only Intel-based Macs are supported. CMAKE_SYSTEM_PROCESSOR may
|
|
||||||
# return the confusing 'i386' if running a 32-bit kernel, but chances
|
|
||||||
# are the binary is x86_64 (or more generally 'Intel') compatible.
|
|
||||||
set(arch "Intel")
|
|
||||||
else ()
|
|
||||||
set (arch ${CMAKE_SYSTEM_PROCESSOR})
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${arch}")
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Sets the list of desired package types to be created by the make
|
|
||||||
# package target. A .tar.gz is always made, and depending on the
|
|
||||||
# operating system, more are added:
|
|
||||||
#
|
|
||||||
# Darwin - PackageMaker
|
|
||||||
# Linux - RPM if the platform has rpmbuild installed
|
|
||||||
# DEB is ommitted because CPack does not give enough
|
|
||||||
# control over how the package is created and lacks support
|
|
||||||
# for automatic dependency detection.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# CPACK_GENERATOR is set by this module
|
|
||||||
|
|
||||||
set(CPACK_GENERATOR TGZ)
|
|
||||||
set(CPACK_SOURCE_GENERATOR TGZ)
|
|
||||||
if (APPLE)
|
|
||||||
list(APPEND CPACK_GENERATOR PackageMaker)
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|
||||||
find_program(RPMBUILD_EXE rpmbuild)
|
|
||||||
if (RPMBUILD_EXE)
|
|
||||||
set(CPACK_GENERATOR ${CPACK_GENERATOR} RPM)
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Sets CPack version variables by splitting the first macro argument
|
|
||||||
# using "." as a delimiter. If the length of the split list is
|
|
||||||
# greater than 2, all remaining elements are tacked on to the patch
|
|
||||||
# level version.
|
|
||||||
|
|
||||||
macro(SetPackageVersion _version)
|
|
||||||
string(REPLACE "." " " version_numbers ${_version})
|
|
||||||
separate_arguments(version_numbers)
|
|
||||||
|
|
||||||
list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MAJOR)
|
|
||||||
list(REMOVE_AT version_numbers 0)
|
|
||||||
list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MINOR)
|
|
||||||
list(REMOVE_AT version_numbers 0)
|
|
||||||
list(LENGTH version_numbers version_length)
|
|
||||||
|
|
||||||
while (version_length GREATER 0)
|
|
||||||
list(GET version_numbers 0 patch_level)
|
|
||||||
if (CPACK_PACKAGE_VERSION_PATCH)
|
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH
|
|
||||||
"${CPACK_PACKAGE_VERSION_PATCH}.${patch_level}")
|
|
||||||
else ()
|
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${patch_level})
|
|
||||||
endif ()
|
|
||||||
list(REMOVE_AT version_numbers 0)
|
|
||||||
list(LENGTH version_numbers version_length)
|
|
||||||
endwhile ()
|
|
||||||
endmacro(SetPackageVersion)
|
|
|
@ -1,35 +0,0 @@
|
||||||
function(uninstall_manifest manifestPath)
|
|
||||||
file(READ "${manifestPath}" files)
|
|
||||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
|
||||||
foreach (file ${files})
|
|
||||||
set(fileName $ENV{DESTDIR}${file})
|
|
||||||
|
|
||||||
if (EXISTS "${fileName}" OR IS_SYMLINK "${fileName}")
|
|
||||||
message(STATUS "Uninstalling: ${fileName}")
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "@CMAKE_COMMAND@" -E remove "${fileName}"
|
|
||||||
OUTPUT_VARIABLE rm_out
|
|
||||||
RESULT_VARIABLE rm_retval
|
|
||||||
)
|
|
||||||
|
|
||||||
if (NOT ${rm_retval} EQUAL 0)
|
|
||||||
message(FATAL_ERROR "Problem when removing: ${fileName}")
|
|
||||||
endif ()
|
|
||||||
else ()
|
|
||||||
message(STATUS "Does not exist: ${fileName}")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
endforeach ()
|
|
||||||
endfunction(uninstall_manifest)
|
|
||||||
|
|
||||||
file(GLOB install_manifests @CMAKE_CURRENT_BINARY_DIR@/install_manifest*.txt)
|
|
||||||
|
|
||||||
if (install_manifests)
|
|
||||||
foreach (manifest ${install_manifests})
|
|
||||||
uninstall_manifest(${manifest})
|
|
||||||
endforeach ()
|
|
||||||
else ()
|
|
||||||
message(FATAL_ERROR "Cannot find any install manifests in: "
|
|
||||||
"\"@CMAKE_CURRENT_BINARY_DIR@/install_manifest*.txt\"")
|
|
||||||
endif ()
|
|
40
config.h.in
40
config.h.in
|
@ -14,18 +14,9 @@
|
||||||
/* Define if you have the `getopt_long' function. */
|
/* Define if you have the `getopt_long' function. */
|
||||||
#cmakedefine HAVE_GETOPT_LONG
|
#cmakedefine HAVE_GETOPT_LONG
|
||||||
|
|
||||||
/* Define if you have the `magic' library (-lmagic). */
|
|
||||||
#cmakedefine HAVE_LIBMAGIC
|
|
||||||
|
|
||||||
/* Define if you have the `z' library (-lz). */
|
|
||||||
#cmakedefine HAVE_LIBZ
|
|
||||||
|
|
||||||
/* We are on a Linux system */
|
/* We are on a Linux system */
|
||||||
#cmakedefine HAVE_LINUX
|
#cmakedefine HAVE_LINUX
|
||||||
|
|
||||||
/* Define if you have the <magic.h> header file. */
|
|
||||||
#cmakedefine HAVE_MAGIC_H
|
|
||||||
|
|
||||||
/* Define if you have the `mallinfo' function. */
|
/* Define if you have the `mallinfo' function. */
|
||||||
#cmakedefine HAVE_MALLINFO
|
#cmakedefine HAVE_MALLINFO
|
||||||
|
|
||||||
|
@ -41,8 +32,8 @@
|
||||||
/* Define if you have the <net/ethernet.h> header file. */
|
/* Define if you have the <net/ethernet.h> header file. */
|
||||||
#cmakedefine HAVE_NET_ETHERNET_H
|
#cmakedefine HAVE_NET_ETHERNET_H
|
||||||
|
|
||||||
/* We are on a OpenBSD system */
|
/* Define if you have the <net/ethertypes.h> header file. */
|
||||||
#cmakedefine HAVE_OPENBSD
|
#cmakedefine HAVE_NET_ETHERTYPES_H
|
||||||
|
|
||||||
/* have os-proto.h */
|
/* have os-proto.h */
|
||||||
#cmakedefine HAVE_OS_PROTO_H
|
#cmakedefine HAVE_OS_PROTO_H
|
||||||
|
@ -114,6 +105,12 @@
|
||||||
/* GeoIP geographic lookup functionality */
|
/* GeoIP geographic lookup functionality */
|
||||||
#cmakedefine USE_GEOIP
|
#cmakedefine USE_GEOIP
|
||||||
|
|
||||||
|
/* Whether the found GeoIP API supports IPv6 Country Edition */
|
||||||
|
#cmakedefine HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||||
|
|
||||||
|
/* Whether the found GeoIP API supports IPv6 City Edition */
|
||||||
|
#cmakedefine HAVE_GEOIP_CITY_EDITION_REV0_V6
|
||||||
|
|
||||||
/* Use Google's perftools */
|
/* Use Google's perftools */
|
||||||
#cmakedefine USE_PERFTOOLS
|
#cmakedefine USE_PERFTOOLS
|
||||||
|
|
||||||
|
@ -130,19 +127,28 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define int32_t */
|
/* Define int32_t */
|
||||||
#define int32_t @INT32_T@
|
#cmakedefine int32_t @int32_t@
|
||||||
|
|
||||||
/* use sigset() instead of signal() */
|
/* use sigset() instead of signal() */
|
||||||
#define signal @SIG_FUNC@
|
#ifdef HAVE_SIGSET
|
||||||
|
#define signal sigset
|
||||||
|
#endif
|
||||||
|
|
||||||
/* define to int if socklen_t not available */
|
/* define to int if socklen_t not available */
|
||||||
#define socklen_t @SOCKLEN_T@
|
#cmakedefine socklen_t @socklen_t@
|
||||||
|
|
||||||
/* Define u_int16_t */
|
/* Define u_int16_t */
|
||||||
#define u_int16_t @U_INT16_T@
|
#cmakedefine u_int16_t @u_int16_t@
|
||||||
|
|
||||||
/* Define u_int32_t */
|
/* Define u_int32_t */
|
||||||
#define u_int32_t @U_INT32_T@
|
#cmakedefine u_int32_t @u_int32_t@
|
||||||
|
|
||||||
/* Define u_int8_t */
|
/* Define u_int8_t */
|
||||||
#define u_int8_t @U_INT8_T@
|
#cmakedefine u_int8_t @u_int8_t@
|
||||||
|
|
||||||
|
/* OpenBSD's bpf.h may not declare this data link type, but it's supposed to be
|
||||||
|
used consistently for the same purpose on all platforms. */
|
||||||
|
#cmakedefine HAVE_DLT_PPP_SERIAL
|
||||||
|
#ifndef HAVE_DLT_PPP_SERIAL
|
||||||
|
#define DLT_PPP_SERIAL @DLT_PPP_SERIAL@
|
||||||
|
#endif
|
||||||
|
|
123
configure
vendored
123
configure
vendored
|
@ -2,6 +2,8 @@
|
||||||
# Convenience wrapper for easily viewing/setting options that
|
# Convenience wrapper for easily viewing/setting options that
|
||||||
# the project's CMake scripts will recognize
|
# the project's CMake scripts will recognize
|
||||||
|
|
||||||
|
command="$0 $*"
|
||||||
|
|
||||||
# check for `cmake` command
|
# check for `cmake` command
|
||||||
type cmake > /dev/null 2>&1 || {
|
type cmake > /dev/null 2>&1 || {
|
||||||
echo "\
|
echo "\
|
||||||
|
@ -20,29 +22,48 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
Installation Directories:
|
Installation Directories:
|
||||||
--prefix=PREFIX installation directory [/usr/local/bro]
|
--prefix=PREFIX installation directory [/usr/local/bro]
|
||||||
--policydir=PATH policy file installation directory
|
--scriptdir=PATH root installation directory for Bro scripts
|
||||||
[PREFIX/share/bro]
|
[PREFIX/share/bro]
|
||||||
|
|
||||||
Optional Features:
|
Optional Features:
|
||||||
--enable-debug compile in debugging mode
|
--enable-debug compile in debugging mode
|
||||||
--enable-brov6 enable IPv6 processing
|
--enable-brov6 enable IPv6 processing
|
||||||
--enable-perftools use Google's perftools
|
--enable-perftools use Google's perftools
|
||||||
--enable-cluster install Broctl configured for cluster operation
|
|
||||||
(overridden by --disable-broctl)
|
|
||||||
--disable-broccoli don't build or install the Broccoli library
|
--disable-broccoli don't build or install the Broccoli library
|
||||||
--disable-broctl don't install Broctl
|
--disable-broctl don't install Broctl
|
||||||
--disable-auxtools don't build or install auxilliary tools
|
--disable-auxtools don't build or install auxilliary tools
|
||||||
|
--disable-python don't try to build python bindings for broccoli
|
||||||
|
--disable-ruby don't try to build ruby bindings for broccoli
|
||||||
|
|
||||||
Required Packages in Non-Standard Locations:
|
Required Packages in Non-Standard Locations:
|
||||||
--with-openssl=PATH path to OpenSSL install root
|
--with-openssl=PATH path to OpenSSL install root
|
||||||
--with-bind=PATH path to BIND install root
|
--with-bind=PATH path to BIND install root
|
||||||
--with-pcap=PATH path to libpcap install root
|
--with-pcap=PATH path to libpcap install root
|
||||||
--with-binpac=PATH path to BinPAC install root
|
--with-binpac=PATH path to BinPAC install root
|
||||||
|
--with-flex=PATH path to flex executable
|
||||||
|
--with-bison=PATH path to bison executable
|
||||||
|
--with-perl=PATH path to perl executable
|
||||||
|
|
||||||
Optional Packages in Non-Standard Locations:
|
Optional Packages in Non-Standard Locations:
|
||||||
--with-libmagic=PATH path to libmagic install root
|
--with-libmagic=PATH path to libmagic install root
|
||||||
--with-geoip=PATH path to the libGeoIP install root
|
--with-geoip=PATH path to the libGeoIP install root
|
||||||
--with-perftools=PATH path to Google Perftools install root
|
--with-perftools=PATH path to Google Perftools install root
|
||||||
|
--with-python=PATH path to Python interpreter
|
||||||
|
--with-python-lib=PATH path to libpython
|
||||||
|
--with-python-inc=PATH path to Python headers
|
||||||
|
--with-ruby=PATH path to ruby interpreter
|
||||||
|
--with-ruby-lib=PATH path to ruby library
|
||||||
|
--with-ruby-inc=PATH path to ruby headers
|
||||||
|
--with-swig=PATH path to SWIG executable
|
||||||
|
|
||||||
|
Packaging Options (for developers):
|
||||||
|
--binary-package toggle special logic for binary packaging
|
||||||
|
--ignore-dirs=PATHS paths to ignore when creating source package
|
||||||
|
(semicolon delimited and quoted when multiple)
|
||||||
|
--pkg-name-prefix=NAME use the given name as the package prefix instead
|
||||||
|
of the default CMake project name
|
||||||
|
--osx-sysroot=PATH path to the OS X SDK to compile against
|
||||||
|
--osx-min-version=VER minimum OS X version (the deployment target)
|
||||||
|
|
||||||
Influential Environment Variables (only on first invocation
|
Influential Environment Variables (only on first invocation
|
||||||
per build directory):
|
per build directory):
|
||||||
|
@ -69,7 +90,7 @@ CMakeCacheEntries=""
|
||||||
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local/bro
|
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local/bro
|
||||||
append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro
|
append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro
|
||||||
append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl
|
append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl
|
||||||
append_cache_entry POLICYDIR STRING /usr/local/bro/share/bro
|
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING /usr/local/bro/share/bro
|
||||||
append_cache_entry ENABLE_DEBUG BOOL false
|
append_cache_entry ENABLE_DEBUG BOOL false
|
||||||
append_cache_entry BROv6 BOOL false
|
append_cache_entry BROv6 BOOL false
|
||||||
append_cache_entry ENABLE_PERFTOOLS BOOL false
|
append_cache_entry ENABLE_PERFTOOLS BOOL false
|
||||||
|
@ -78,7 +99,7 @@ append_cache_entry BUILD_SHARED_LIBS BOOL true
|
||||||
append_cache_entry INSTALL_AUX_TOOLS BOOL true
|
append_cache_entry INSTALL_AUX_TOOLS BOOL true
|
||||||
append_cache_entry INSTALL_BROCCOLI BOOL true
|
append_cache_entry INSTALL_BROCCOLI BOOL true
|
||||||
append_cache_entry INSTALL_BROCTL BOOL true
|
append_cache_entry INSTALL_BROCTL BOOL true
|
||||||
append_cache_entry STANDALONE BOOL true
|
append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING
|
||||||
|
|
||||||
# parse arguments
|
# parse arguments
|
||||||
while [ $# -ne 0 ]; do
|
while [ $# -ne 0 ]; do
|
||||||
|
@ -102,13 +123,13 @@ while [ $# -ne 0 ]; do
|
||||||
append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg
|
append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg
|
||||||
append_cache_entry BRO_ROOT_DIR PATH $optarg
|
append_cache_entry BRO_ROOT_DIR PATH $optarg
|
||||||
append_cache_entry PY_MOD_INSTALL_DIR PATH $optarg/lib/broctl
|
append_cache_entry PY_MOD_INSTALL_DIR PATH $optarg/lib/broctl
|
||||||
if [ "$user_set_policydir" != "true" ]; then
|
if [ "$user_set_scriptdir" != "true" ]; then
|
||||||
append_cache_entry POLICYDIR STRING $optarg/share/bro
|
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $optarg/share/bro
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
--policydir=*)
|
--scriptdir=*)
|
||||||
append_cache_entry POLICYDIR STRING $optarg
|
append_cache_entry BRO_SCRIPT_INSTALL_PATH STRING $optarg
|
||||||
user_set_policydir="true"
|
user_set_scriptdir="true"
|
||||||
;;
|
;;
|
||||||
--enable-debug)
|
--enable-debug)
|
||||||
append_cache_entry ENABLE_DEBUG BOOL true
|
append_cache_entry ENABLE_DEBUG BOOL true
|
||||||
|
@ -124,16 +145,16 @@ while [ $# -ne 0 ]; do
|
||||||
;;
|
;;
|
||||||
--disable-broctl)
|
--disable-broctl)
|
||||||
append_cache_entry INSTALL_BROCTL BOOL false
|
append_cache_entry INSTALL_BROCTL BOOL false
|
||||||
user_disabled_broctl="true"
|
|
||||||
;;
|
|
||||||
--enable-cluster)
|
|
||||||
if [ "$user_disabled_broctl" != "true" ]; then
|
|
||||||
append_cache_entry STANDALONE BOOL false
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
--disable-auxtools)
|
--disable-auxtools)
|
||||||
append_cache_entry INSTALL_AUX_TOOLS BOOL false
|
append_cache_entry INSTALL_AUX_TOOLS BOOL false
|
||||||
;;
|
;;
|
||||||
|
--disable-python)
|
||||||
|
append_cache_entry DISABLE_PYTHON_BINDINGS BOOL true
|
||||||
|
;;
|
||||||
|
--disable-ruby)
|
||||||
|
append_cache_entry DISABLE_RUBY_BINDINGS BOOL true
|
||||||
|
;;
|
||||||
--with-openssl=*)
|
--with-openssl=*)
|
||||||
append_cache_entry OpenSSL_ROOT_DIR PATH $optarg
|
append_cache_entry OpenSSL_ROOT_DIR PATH $optarg
|
||||||
;;
|
;;
|
||||||
|
@ -146,6 +167,15 @@ while [ $# -ne 0 ]; do
|
||||||
--with-binpac=*)
|
--with-binpac=*)
|
||||||
append_cache_entry BinPAC_ROOT_DIR PATH $optarg
|
append_cache_entry BinPAC_ROOT_DIR PATH $optarg
|
||||||
;;
|
;;
|
||||||
|
--with-flex=*)
|
||||||
|
append_cache_entry FLEX_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-bison=*)
|
||||||
|
append_cache_entry BISON_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-perl=*)
|
||||||
|
append_cache_entry PERL_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
--with-libmagic=*)
|
--with-libmagic=*)
|
||||||
append_cache_entry LibMagic_ROOT_DIR PATH $optarg
|
append_cache_entry LibMagic_ROOT_DIR PATH $optarg
|
||||||
;;
|
;;
|
||||||
|
@ -153,8 +183,47 @@ while [ $# -ne 0 ]; do
|
||||||
append_cache_entry LibGeoIP_ROOT_DIR PATH $optarg
|
append_cache_entry LibGeoIP_ROOT_DIR PATH $optarg
|
||||||
;;
|
;;
|
||||||
--with-perftools=*)
|
--with-perftools=*)
|
||||||
|
append_cache_entry ENABLE_PERFTOOLS BOOL true
|
||||||
append_cache_entry GooglePerftools_ROOT_DIR PATH $optarg
|
append_cache_entry GooglePerftools_ROOT_DIR PATH $optarg
|
||||||
;;
|
;;
|
||||||
|
--with-python=*)
|
||||||
|
append_cache_entry PYTHON_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-python-lib=*)
|
||||||
|
append_cache_entry PYTHON_LIBRARY PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-python-inc=*)
|
||||||
|
append_cache_entry PYTHON_INCLUDE_DIR PATH $optarg
|
||||||
|
append_cache_entry PYTHON_INCLUDE_PATH PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-ruby=*)
|
||||||
|
append_cache_entry RUBY_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-ruby-lib=*)
|
||||||
|
append_cache_entry RUBY_LIBRARY PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-ruby-inc=*)
|
||||||
|
append_cache_entry RUBY_INCLUDE_DIRS PATH $optarg
|
||||||
|
append_cache_entry RUBY_INCLUDE_PATH PATH $optarg
|
||||||
|
;;
|
||||||
|
--with-swig=*)
|
||||||
|
append_cache_entry SWIG_EXECUTABLE PATH $optarg
|
||||||
|
;;
|
||||||
|
--binary-package)
|
||||||
|
append_cache_entry BINARY_PACKAGING_MODE BOOL true
|
||||||
|
;;
|
||||||
|
--ignore-dirs=*)
|
||||||
|
append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING $optarg
|
||||||
|
;;
|
||||||
|
--pkg-name-prefix=*)
|
||||||
|
append_cache_entry PACKAGE_NAME_PREFIX STRING $optarg
|
||||||
|
;;
|
||||||
|
--osx-sysroot=*)
|
||||||
|
append_cache_entry CMAKE_OSX_SYSROOT PATH $optarg
|
||||||
|
;;
|
||||||
|
--osx-min-version=*)
|
||||||
|
append_cache_entry CMAKE_OSX_DEPLOYMENT_TARGET STRING $optarg
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid option '$1'. Try $0 --help to see available options."
|
echo "Invalid option '$1'. Try $0 --help to see available options."
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -166,21 +235,9 @@ done
|
||||||
if [ -d $builddir ]; then
|
if [ -d $builddir ]; then
|
||||||
# If build directory exists, check if it has a CMake cache
|
# If build directory exists, check if it has a CMake cache
|
||||||
if [ -f $builddir/CMakeCache.txt ]; then
|
if [ -f $builddir/CMakeCache.txt ]; then
|
||||||
# If the Cmake cache exists, then check that it thinks
|
# If the CMake cache exists, delete it so that this configuration
|
||||||
# the source tree exists where it's currently located
|
# is not tainted by a previous one
|
||||||
cmakehomedir=`grep CMAKE_HOME_DIRECTORY $builddir/CMakeCache.txt | \
|
rm -f $builddir/CMakeCache.txt
|
||||||
sed 's/CMAKE_HOME_DIRECTORY:INTERNAL=//g'`
|
|
||||||
if [ "$cmakehomedir" != "$sourcedir" ]; then
|
|
||||||
# The source tree moved since the build was last configured
|
|
||||||
echo "\
|
|
||||||
The source tree has been moved from:
|
|
||||||
$cmakehomedir
|
|
||||||
to:
|
|
||||||
$sourcedir
|
|
||||||
To reconfigure in the new source directory, please delete:
|
|
||||||
$builddir/CMakeCache.txt" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Create build directory
|
# Create build directory
|
||||||
|
@ -196,3 +253,7 @@ if [ -n "$CMakeGenerator" ]; then
|
||||||
else
|
else
|
||||||
cmake $CMakeCacheEntries $sourcedir
|
cmake $CMakeCacheEntries $sourcedir
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "# This is the command used to configure this build" > config.status
|
||||||
|
echo $command >> config.status
|
||||||
|
chmod u+x config.status
|
||||||
|
|
2
doc/.gitignore
vendored
Normal file
2
doc/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
html
|
||||||
|
*.pyc
|
1
doc/CHANGES
Symbolic link
1
doc/CHANGES
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../CHANGES
|
75
doc/CMakeLists.txt
Normal file
75
doc/CMakeLists.txt
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
set(BIF_SRC_DIR ${PROJECT_SOURCE_DIR}/src)
|
||||||
|
set(RST_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/rest_output)
|
||||||
|
set(DOC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/out)
|
||||||
|
set(DOC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
set(DOC_SOURCE_WORKDIR ${CMAKE_CURRENT_BINARY_DIR}/sphinx-sources)
|
||||||
|
|
||||||
|
set(MASTER_POLICY_INDEX ${CMAKE_CURRENT_BINARY_DIR}/scripts/policy_index)
|
||||||
|
set(MASTER_PACKAGE_INDEX ${CMAKE_CURRENT_BINARY_DIR}/scripts/pkg_index)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE DOC_SOURCES FOLLOW_SYMLINKS "*")
|
||||||
|
|
||||||
|
# configure the Sphinx config file (expand variables CMake might know about)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/conf.py
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
add_subdirectory(scripts)
|
||||||
|
|
||||||
|
# The "broxygen" target generates reST documentation for any outdated bro
|
||||||
|
# scripts and then uses Sphinx to generate HTML documentation from the reST
|
||||||
|
add_custom_target(broxygen
|
||||||
|
# copy the template documentation to the build directory
|
||||||
|
# to give as input for sphinx
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
|
${DOC_SOURCE_DIR}
|
||||||
|
${DOC_SOURCE_WORKDIR}
|
||||||
|
# copy generated policy script documentation into the
|
||||||
|
# working copy of the template documentation
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
|
${RST_OUTPUT_DIR}
|
||||||
|
${DOC_SOURCE_WORKDIR}/scripts
|
||||||
|
# append to the master index of all policy scripts
|
||||||
|
COMMAND cat ${MASTER_POLICY_INDEX} >>
|
||||||
|
${DOC_SOURCE_WORKDIR}/scripts/index.rst
|
||||||
|
# append to the master index of all policy packages
|
||||||
|
COMMAND cat ${MASTER_PACKAGE_INDEX} >>
|
||||||
|
${DOC_SOURCE_WORKDIR}/scripts/packages.rst
|
||||||
|
# construct a reST file for each group
|
||||||
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/group_index_generator.py
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/scripts/group_list
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/scripts
|
||||||
|
${DOC_SOURCE_WORKDIR}/scripts
|
||||||
|
# tell sphinx to generate html
|
||||||
|
COMMAND sphinx-build
|
||||||
|
-b html
|
||||||
|
-c ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
-d ${DOC_OUTPUT_DIR}/doctrees
|
||||||
|
${DOC_SOURCE_WORKDIR}
|
||||||
|
${DOC_OUTPUT_DIR}/html
|
||||||
|
# create symlink to the html output directory for convenience
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E create_symlink
|
||||||
|
${DOC_OUTPUT_DIR}/html
|
||||||
|
${CMAKE_BINARY_DIR}/html
|
||||||
|
# copy Broccoli API reference into output dir if it exists
|
||||||
|
COMMAND test -d ${CMAKE_BINARY_DIR}/aux/broccoli/doc/html && ( rm -rf ${CMAKE_BINARY_DIR}/html/broccoli-api && cp -r ${CMAKE_BINARY_DIR}/aux/broccoli/doc/html ${CMAKE_BINARY_DIR}/html/broccoli-api ) || true
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMENT "[Sphinx] Generating HTML policy script docs"
|
||||||
|
# SOURCES just adds stuff to IDE projects as a convenience
|
||||||
|
SOURCES ${DOC_SOURCES})
|
||||||
|
|
||||||
|
# The "sphinxclean" target removes just the Sphinx input/output directories
|
||||||
|
# from the build directory.
|
||||||
|
add_custom_target(broxygenclean
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||||
|
${DOC_SOURCE_WORKDIR}
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||||
|
${DOC_OUTPUT_DIR}
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
|
add_dependencies(broxygen broxygenclean restdoc)
|
||||||
|
|
||||||
|
add_custom_target(doc)
|
||||||
|
add_custom_target(docclean)
|
||||||
|
add_dependencies(doc broxygen)
|
||||||
|
add_dependencies(docclean broxygenclean restclean)
|
1
doc/INSTALL.rst
Symbolic link
1
doc/INSTALL.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../INSTALL
|
46
doc/README
46
doc/README
|
@ -1 +1,47 @@
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
=============
|
||||||
|
|
||||||
|
This directory contains Bro documentation in reStructuredText format
|
||||||
|
(see http://docutils.sourceforge.net/rst.html).
|
||||||
|
|
||||||
|
It is the root of a Sphinx source tree and can be modified to add more
|
||||||
|
common/general documentation, style sheets, JavaScript, etc. The Sphinx
|
||||||
|
config file is produced from ``conf.py.in``, and can be edited to change
|
||||||
|
various Sphinx options.
|
||||||
|
|
||||||
|
There is also a custom Sphinx domain implemented in ``source/ext/bro.py``
|
||||||
|
which adds some reST directives and roles that aid in generating useful
|
||||||
|
index entries and cross-references. Other extensions can be added in
|
||||||
|
a similar fashion.
|
||||||
|
|
||||||
|
Either the ``make doc`` or ``make broxygen`` targets in the top-level
|
||||||
|
Makefile can be used to locally render the reST files into HTML.
|
||||||
|
Those targets depend on:
|
||||||
|
|
||||||
|
* Python interpreter >= 2.5
|
||||||
|
* `Sphinx <http://sphinx.pocoo.org/>`_ >= 1.0.1
|
||||||
|
|
||||||
|
After completion, HTML documentation is symlinked in ``build/html``.
|
||||||
|
|
||||||
|
There's also ``make docclean`` and ``make broxygenclean`` targets to
|
||||||
|
clean the resulting documentation.
|
||||||
|
|
||||||
|
Notes for Writing Documentation
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
* If you want to refer to a document that's part of the
|
||||||
|
distribution, it currently needs to be copied or otherwise symlinked
|
||||||
|
somewhere in to this Sphinx source tree. Then, it can be referenced
|
||||||
|
in a toc tree or with the :doc: role. Use the :download: role to
|
||||||
|
refer to static files that will not undergo sphinx rendering.
|
||||||
|
|
||||||
|
* If you want to refer to a page on the Bro web site, use an HTTP URL.
|
||||||
|
|
||||||
|
Guidelines
|
||||||
|
----------
|
||||||
|
|
||||||
TODO.
|
TODO.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
1
doc/_static/960.css
vendored
Normal file
1
doc/_static/960.css
vendored
Normal file
File diff suppressed because one or more lines are too long
513
doc/_static/basic.css
vendored
Normal file
513
doc/_static/basic.css
vendored
Normal file
|
@ -0,0 +1,513 @@
|
||||||
|
/*
|
||||||
|
* basic.css
|
||||||
|
* ~~~~~~~~~
|
||||||
|
*
|
||||||
|
* Sphinx stylesheet -- basic theme.
|
||||||
|
*
|
||||||
|
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
|
||||||
|
* :license: BSD, see LICENSE for details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -- main layout ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.clearer {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- relbar ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.related {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.related h3 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.related ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0 10px;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.related li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.related li.right {
|
||||||
|
float: right;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- sidebar --------------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.sphinxsidebarwrapper {
|
||||||
|
padding: 10px 5px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar {
|
||||||
|
float: left;
|
||||||
|
width: 230px;
|
||||||
|
margin-left: -100%;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar ul ul,
|
||||||
|
div.sphinxsidebar ul.want-points {
|
||||||
|
margin-left: 20px;
|
||||||
|
list-style: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar ul ul {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar form {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar input {
|
||||||
|
border: 1px solid #98dbcc;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar input[type="text"] {
|
||||||
|
width: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar input[type="submit"] {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- search page ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
ul.search {
|
||||||
|
margin: 10px 0 0 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.search li {
|
||||||
|
padding: 5px 0 5px 20px;
|
||||||
|
background-image: url(file.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.search li a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.search li div.context {
|
||||||
|
color: #888;
|
||||||
|
margin: 2px 0 0 30px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.keywordmatches li.goodmatch a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- index page ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
table.contentstable {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.contentstable p.biglink {
|
||||||
|
line-height: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.biglink {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.linkdescr {
|
||||||
|
font-style: italic;
|
||||||
|
padding-top: 5px;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- general index --------------------------------------------------------- */
|
||||||
|
|
||||||
|
table.indextable {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.indextable td {
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.indextable dl, table.indextable dd {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.indextable tr.pcap {
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.indextable tr.cap {
|
||||||
|
margin-top: 10px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.toggler {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-top: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.modindex-jumpbox {
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
margin: 1em 0 1em 0;
|
||||||
|
padding: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.genindex-jumpbox {
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
margin: 1em 0 1em 0;
|
||||||
|
padding: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- general body styles --------------------------------------------------- */
|
||||||
|
|
||||||
|
a.headerlink {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.body p.caption {
|
||||||
|
text-align: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.body td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-list ul {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.rubric {
|
||||||
|
margin-top: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.align-left, .figure.align-left, object.align-left {
|
||||||
|
clear: left;
|
||||||
|
float: left;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.align-right, .figure.align-right, object.align-right {
|
||||||
|
clear: right;
|
||||||
|
float: right;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.align-center, .figure.align-center, object.align-center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- sidebars -------------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.sidebar {
|
||||||
|
margin: 0 0 0.5em 1em;
|
||||||
|
border: 1px solid #ddb;
|
||||||
|
padding: 7px 7px 0 7px;
|
||||||
|
background-color: #ffe;
|
||||||
|
width: 40%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.sidebar-title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- topics ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.topic {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 7px 7px 0 7px;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.topic-title {
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- admonitions ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
div.admonition {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition dl {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.admonition-title {
|
||||||
|
margin: 0px 10px 5px 0px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.body p.centered {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- tables ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
table.field-list td, table.field-list th {
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.footnote td, table.footnote th {
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.citation {
|
||||||
|
border-left: solid 1px gray;
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.citation td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- other body styles ----------------------------------------------------- */
|
||||||
|
|
||||||
|
ol.arabic {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.loweralpha {
|
||||||
|
list-style: lower-alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.upperalpha {
|
||||||
|
list-style: upper-alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.lowerroman {
|
||||||
|
list-style: lower-roman;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.upperroman {
|
||||||
|
list-style: upper-roman;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd p {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd ul, dd table {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt:target, .highlighted {
|
||||||
|
background-color: #fbe54e;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl.glossary dt {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-list ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-list p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refcount {
|
||||||
|
color: #060;
|
||||||
|
}
|
||||||
|
|
||||||
|
.optional {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionmodified {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-message {
|
||||||
|
background-color: #fda;
|
||||||
|
padding: 5px;
|
||||||
|
border: 3px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote:target {
|
||||||
|
background-color: #ffa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-block {
|
||||||
|
display: block;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-block .line-block {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guilabel, .menuselection {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accelerator {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classifier {
|
||||||
|
font-style: oblique;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr, acronym {
|
||||||
|
border-bottom: dotted 1px;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- code displays --------------------------------------------------------- */
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
||||||
|
}
|
||||||
|
|
||||||
|
td.linenos pre {
|
||||||
|
padding: 5px 0px;
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.highlighttable {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.highlighttable td {
|
||||||
|
padding: 0 0.5em 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.descname {
|
||||||
|
background-color: transparent;
|
||||||
|
font-weight: bold;
|
||||||
|
# font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.descclassname {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.xref, a tt {
|
||||||
|
background-color: transparent;
|
||||||
|
# font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewcode-link {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewcode-back {
|
||||||
|
float: right;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.viewcode-block:target {
|
||||||
|
margin: -1px -10px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- math display ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
img.math {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.body div.math p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.eqno {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- printout stylesheet --------------------------------------------------- */
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
div.document,
|
||||||
|
div.documentwrapper,
|
||||||
|
div.bodywrapper {
|
||||||
|
margin: 0 !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar,
|
||||||
|
div.related,
|
||||||
|
div.footer,
|
||||||
|
#top-link {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
160
doc/_static/broxygen-extra.css
vendored
Normal file
160
doc/_static/broxygen-extra.css
vendored
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
|
||||||
|
a.toc-backref {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6,
|
||||||
|
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
||||||
|
padding:0 0 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height:32px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 3px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-family: Palatino,'Palatino Linotype',Georgia,serif;;
|
||||||
|
color: #000;
|
||||||
|
border-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.field-name
|
||||||
|
{
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 50px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
border-color: #aaa;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.section h3 {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 0¡px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.widgettitle {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size:18px;
|
||||||
|
font-style: normal;
|
||||||
|
margin-bottom: 0em;
|
||||||
|
margin-top: 40px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size:16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size:15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-backref {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul {
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl.namespace {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl dt {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.docutils tbody {
|
||||||
|
margin: 1em 1em 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.docutils td {
|
||||||
|
padding: 5pt 5pt 5pt 5pt;
|
||||||
|
font-size: 14px;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl pre {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.docutils th {
|
||||||
|
padding: 5pt 5pt 5pt 5pt;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.docutils tr:first-child td {
|
||||||
|
#border-top: 1px solid #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download {
|
||||||
|
font-family:"Courier New", Courier, mono;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt:target, .highlighted {
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.last {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
padding: 1em 1em 1em 1em;
|
||||||
|
background: #fffff0;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.docutils {
|
||||||
|
background: #fffff0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl table.docutils {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.docutils dl {
|
||||||
|
border: 1px dashed #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
437
doc/_static/broxygen.css
vendored
Normal file
437
doc/_static/broxygen.css
vendored
Normal file
|
@ -0,0 +1,437 @@
|
||||||
|
/* Automatically generated. Do not edit. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#bro-main, #bro-standalone-main {
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
position:relative;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bro-main {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bro-standalone-main {
|
||||||
|
margin-bottom: 0em;
|
||||||
|
padding-left: 50px;
|
||||||
|
padding-right: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bro-outer {
|
||||||
|
color: #333;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bro-title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height:32px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 3px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-family: Palatino,'Palatino Linotype',Georgia,serif;;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opening:first-letter {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opening {
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
text-align: right;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.git-info-version {
|
||||||
|
position: relative;
|
||||||
|
height: 2em;
|
||||||
|
top: -1em;
|
||||||
|
color: #ccc;
|
||||||
|
float: left;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.git-info-date {
|
||||||
|
position: relative;
|
||||||
|
height: 2em;
|
||||||
|
top: -1em;
|
||||||
|
color: #ccc;
|
||||||
|
float: right;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family:Arial, Helvetica, sans-serif;
|
||||||
|
font-size:15px;
|
||||||
|
line-height:22px;
|
||||||
|
color: #333;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6,
|
||||||
|
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
||||||
|
padding:0 0 20px 0;
|
||||||
|
font-weight:bold;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.section h3, div.section h4, div.section h5, div.section h6 {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2 {
|
||||||
|
font-size:27px;
|
||||||
|
letter-spacing:-1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 1em;
|
||||||
|
font-size:18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size:16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size:15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding:0 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background:none;
|
||||||
|
height:1px;
|
||||||
|
line-height:1px;
|
||||||
|
border:0;
|
||||||
|
margin:0 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
margin:0 20px 20px 0;
|
||||||
|
padding-left:40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.simple, ol.simple {
|
||||||
|
margin:0 0px 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin:0 0 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong, dfn {
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
em, dfn {
|
||||||
|
font-style:italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup, sub {
|
||||||
|
line-height:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space:pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code, tt {
|
||||||
|
font-family:"Courier New", Courier, mono;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin:0 0 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size:75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link,
|
||||||
|
a:visited,
|
||||||
|
a:active
|
||||||
|
{
|
||||||
|
color: #2a85a7;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover
|
||||||
|
{
|
||||||
|
color:#c24444;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6,
|
||||||
|
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a
|
||||||
|
{
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-bottom:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
color: #333;
|
||||||
|
background: #FFFAE2;
|
||||||
|
padding: 7px 5px 3px 5px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2 {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
border-color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
-moz-box-shadow:0 0 6px #ddd;
|
||||||
|
-webkit-box-shadow:0 0 6px #ddd;
|
||||||
|
box-shadow:0 0 6px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, dd, li {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#footer .widget_links ul a,
|
||||||
|
#footer .widget_links ol a
|
||||||
|
{
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer .widget_links ul a:hover,
|
||||||
|
#footer .widget_links ol a:hover
|
||||||
|
{
|
||||||
|
color:#c24444;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#footer .widget li {
|
||||||
|
padding-bottom:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer .widget_links li {
|
||||||
|
padding-bottom:1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer .widget li:last-child {
|
||||||
|
padding-bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer .widgettitle {
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
margin:0 0 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget, .widgettitle {
|
||||||
|
font-size:12px;
|
||||||
|
line-height:18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widgettitle {
|
||||||
|
font-weight:bold;
|
||||||
|
text-transform:uppercase;
|
||||||
|
padding:0 0 10px 0;
|
||||||
|
margin:0 0 20px 0;
|
||||||
|
line-height:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget UL, .widget OL {
|
||||||
|
list-style-type:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget p {
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget li {
|
||||||
|
padding-bottom:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget a {
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bro-main .widgettitle,
|
||||||
|
{
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.widget img.left {
|
||||||
|
padding:5px 10px 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget img.right {
|
||||||
|
padding:5px 0 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ads .widgettitle {
|
||||||
|
margin-right:16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widgettitle {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widgettitle {
|
||||||
|
border-bottom:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.sidebar-toc ul li {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
text-align: left;
|
||||||
|
list-style-type: square;
|
||||||
|
list-style-position: inside;
|
||||||
|
padding-left: 1em;
|
||||||
|
text-indent: -1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toc ul li li {
|
||||||
|
margin-left: 1em;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toc ul li li a {
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents {
|
||||||
|
padding: 10px;
|
||||||
|
background: #FFFAE2;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0px 0px 5px 0px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents li {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul ul li {
|
||||||
|
margin-left: 0px;
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-top: 0em;
|
||||||
|
font-size: 90%;
|
||||||
|
list-style-type: square;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul ul ul li {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul ul ul ul li {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul li {
|
||||||
|
padding-top: 1em;
|
||||||
|
list-style-type: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents ul {
|
||||||
|
margin-left: 0px;
|
||||||
|
padding-left: 2em;
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note, .warning, .error {
|
||||||
|
margin-left: 2em;
|
||||||
|
margin-right: 2em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
padding: 0.5em 1em 0.5em 1em;
|
||||||
|
overflow: auto;
|
||||||
|
border-left: solid 3px #aaa;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admonition p {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admonition-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
padding-bottom: 0em;
|
||||||
|
margin-bottom: .5em;
|
||||||
|
margin-top: 0em;
|
||||||
|
}
|
BIN
doc/_static/logo-bro.png
vendored
Normal file
BIN
doc/_static/logo-bro.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
58
doc/_static/pygments.css
vendored
Normal file
58
doc/_static/pygments.css
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
.hll { background-color: #ffffcc }
|
||||||
|
.c { color: #aaaaaa; font-style: italic } /* Comment */
|
||||||
|
.err { color: #F00000; background-color: #F0A0A0 } /* Error */
|
||||||
|
.k { color: #0000aa } /* Keyword */
|
||||||
|
.cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */
|
||||||
|
.cp { color: #4c8317 } /* Comment.Preproc */
|
||||||
|
.c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */
|
||||||
|
.cs { color: #0000aa; font-style: italic } /* Comment.Special */
|
||||||
|
.gd { color: #aa0000 } /* Generic.Deleted */
|
||||||
|
.ge { font-style: italic } /* Generic.Emph */
|
||||||
|
.gr { color: #aa0000 } /* Generic.Error */
|
||||||
|
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||||
|
.gi { color: #00aa00 } /* Generic.Inserted */
|
||||||
|
.go { color: #888888 } /* Generic.Output */
|
||||||
|
.gp { color: #555555 } /* Generic.Prompt */
|
||||||
|
.gs { font-weight: bold } /* Generic.Strong */
|
||||||
|
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||||
|
.gt { color: #aa0000 } /* Generic.Traceback */
|
||||||
|
.kc { color: #0000aa } /* Keyword.Constant */
|
||||||
|
.kd { color: #0000aa } /* Keyword.Declaration */
|
||||||
|
.kn { color: #0000aa } /* Keyword.Namespace */
|
||||||
|
.kp { color: #0000aa } /* Keyword.Pseudo */
|
||||||
|
.kr { color: #0000aa } /* Keyword.Reserved */
|
||||||
|
.kt { color: #00aaaa } /* Keyword.Type */
|
||||||
|
.m { color: #009999 } /* Literal.Number */
|
||||||
|
.s { color: #aa5500 } /* Literal.String */
|
||||||
|
.na { color: #1e90ff } /* Name.Attribute */
|
||||||
|
.nb { color: #00aaaa } /* Name.Builtin */
|
||||||
|
.nc { color: #00aa00; text-decoration: underline } /* Name.Class */
|
||||||
|
.no { color: #aa0000 } /* Name.Constant */
|
||||||
|
.nd { color: #888888 } /* Name.Decorator */
|
||||||
|
.ni { color: #800000; font-weight: bold } /* Name.Entity */
|
||||||
|
.nf { color: #00aa00 } /* Name.Function */
|
||||||
|
.nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */
|
||||||
|
.nt { color: #1e90ff; font-weight: bold } /* Name.Tag */
|
||||||
|
.nv { color: #aa0000 } /* Name.Variable */
|
||||||
|
.ow { color: #0000aa } /* Operator.Word */
|
||||||
|
.w { color: #bbbbbb } /* Text.Whitespace */
|
||||||
|
.mf { color: #009999 } /* Literal.Number.Float */
|
||||||
|
.mh { color: #009999 } /* Literal.Number.Hex */
|
||||||
|
.mi { color: #009999 } /* Literal.Number.Integer */
|
||||||
|
.mo { color: #009999 } /* Literal.Number.Oct */
|
||||||
|
.sb { color: #aa5500 } /* Literal.String.Backtick */
|
||||||
|
.sc { color: #aa5500 } /* Literal.String.Char */
|
||||||
|
.sd { color: #aa5500 } /* Literal.String.Doc */
|
||||||
|
.s2 { color: #aa5500 } /* Literal.String.Double */
|
||||||
|
.se { color: #aa5500 } /* Literal.String.Escape */
|
||||||
|
.sh { color: #aa5500 } /* Literal.String.Heredoc */
|
||||||
|
.si { color: #aa5500 } /* Literal.String.Interpol */
|
||||||
|
.sx { color: #aa5500 } /* Literal.String.Other */
|
||||||
|
.sr { color: #009999 } /* Literal.String.Regex */
|
||||||
|
.s1 { color: #aa5500 } /* Literal.String.Single */
|
||||||
|
.ss { color: #0000aa } /* Literal.String.Symbol */
|
||||||
|
.bp { color: #00aaaa } /* Name.Builtin.Pseudo */
|
||||||
|
.vc { color: #aa0000 } /* Name.Variable.Class */
|
||||||
|
.vg { color: #aa0000 } /* Name.Variable.Global */
|
||||||
|
.vi { color: #aa0000 } /* Name.Variable.Instance */
|
||||||
|
.il { color: #009999 } /* Literal.Number.Integer.Long */
|
113
doc/_templates/layout.html
vendored
Normal file
113
doc/_templates/layout.html
vendored
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
{% extends "!layout.html" %}
|
||||||
|
|
||||||
|
{% block extrahead %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/broxygen.css', 1) }}"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/960.css', 1) }}"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/pygments.css', 1) }}"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/broxygen-extra.css', 1) }}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="{{ pathto('_static/broxygen-extra.js', 1) }}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<iframe src="http://www.bro-ids.org/frames/header-no-logo.html" width="100%" height="100px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0">
|
||||||
|
</iframe>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block relbar2 %}{% endblock %}
|
||||||
|
{% block relbar1 %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div id="bro-main" class="clearfix">
|
||||||
|
<div class="container_12">
|
||||||
|
|
||||||
|
<div class="grid_9">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ relbar() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="body">
|
||||||
|
{% block body %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div class="grid_3 omega">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img id="logo" src="{{pathto('_static/logo-bro.png', 1)}}" alt="Logo" />
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
<div class="widget sidebar-toc">
|
||||||
|
<h3 class="widgettitle">
|
||||||
|
Table of Contents
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<!-- <ul id="sidebar-toc"></ul> -->
|
||||||
|
<ul>{{toc}}</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if next %}
|
||||||
|
<div class="widget">
|
||||||
|
<h3 class="widgettitle">
|
||||||
|
Next Page
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<a href="{{ next.link|e }}">{{ next.title }}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if prev %}
|
||||||
|
<div class="widget">
|
||||||
|
<h3 class="widgettitle">
|
||||||
|
Previous Page
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<a href="{{ prev.link|e }}">{{ prev.title }}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- if pagename != "search" %}
|
||||||
|
<div id="searchbox" style="display: none" class="widget">
|
||||||
|
<h3 class="widgettitle">{{ _('Search') }}</h3>
|
||||||
|
<form class="search" action="{{ pathto('search') }}" method="get">
|
||||||
|
<input type="text" name="q" />
|
||||||
|
<input type="submit" value="{{ _('Search') }}" />
|
||||||
|
<input type="hidden" name="check_keywords" value="yes" />
|
||||||
|
<input type="hidden" name="area" value="default" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container_12">
|
||||||
|
<div class="grid_12 alpha omega">
|
||||||
|
<div class="center">
|
||||||
|
<small>
|
||||||
|
Copyright {{ copyright }}.
|
||||||
|
Last updated on {{ last_updated }}.
|
||||||
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}
|
||||||
|
<iframe src="http://www.bro-ids.org/frames/footer.html" width="100%" height="420px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0">
|
||||||
|
</iframe>
|
||||||
|
{% endblock %}
|
62
doc/bin/group_index_generator.py
Executable file
62
doc/bin/group_index_generator.py
Executable file
|
@ -0,0 +1,62 @@
|
||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
# This script automatically generates a reST documents that lists
|
||||||
|
# a collection of Bro scripts that are "grouped" together.
|
||||||
|
# The summary text (##! comments) of the script is embedded in the list
|
||||||
|
#
|
||||||
|
# 1st argument is the file containing list of groups
|
||||||
|
# 2nd argument is the directory containing ${group}_files lists of
|
||||||
|
# scripts that belong to the group and ${group}_doc_names lists of
|
||||||
|
# document names that can be supplied to a reST :doc: role
|
||||||
|
# 3rd argument is a directory in which write a ${group}.rst file (will
|
||||||
|
# append to existing file) that contains reST style references to
|
||||||
|
# script docs along with summary text contained in original script
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
|
||||||
|
group_list = sys.argv[1]
|
||||||
|
file_manifest_dir = sys.argv[2]
|
||||||
|
output_dir = sys.argv[3]
|
||||||
|
|
||||||
|
with open(group_list, 'r') as f_group_list:
|
||||||
|
for group in f_group_list.read().splitlines():
|
||||||
|
#print group
|
||||||
|
file_manifest = os.path.join(file_manifest_dir, group + "_files")
|
||||||
|
doc_manifest = os.path.join(file_manifest_dir, group + "_doc_names")
|
||||||
|
src_files = []
|
||||||
|
doc_names = []
|
||||||
|
|
||||||
|
with open(file_manifest, 'r') as f_file_manifest:
|
||||||
|
src_files = f_file_manifest.read().splitlines()
|
||||||
|
|
||||||
|
with open(doc_manifest, 'r') as f_doc_manifest:
|
||||||
|
doc_names = f_doc_manifest.read().splitlines()
|
||||||
|
|
||||||
|
for i in range(len(src_files)):
|
||||||
|
src_file = src_files[i]
|
||||||
|
#print "\t" + src_file
|
||||||
|
summary_comments = []
|
||||||
|
with open(src_file, 'r') as f_src_file:
|
||||||
|
for line in f_src_file:
|
||||||
|
sum_pos = string.find(line, "##!")
|
||||||
|
if sum_pos != -1:
|
||||||
|
summary_comments.append(line[(sum_pos+3):])
|
||||||
|
#print summary_comments
|
||||||
|
group_file = os.path.join(output_dir, group + ".rst")
|
||||||
|
if not os.path.exists(group_file):
|
||||||
|
if not os.path.exists(os.path.dirname(group_file)):
|
||||||
|
os.makedirs(os.path.dirname(group_file))
|
||||||
|
with open(group_file, 'w') as f_group_file:
|
||||||
|
f_group_file.write(":orphan:\n\n")
|
||||||
|
title = "Package Index: %s\n" % os.path.dirname(group)
|
||||||
|
f_group_file.write(title);
|
||||||
|
for n in range(len(title)):
|
||||||
|
f_group_file.write("=")
|
||||||
|
f_group_file.write("\n");
|
||||||
|
|
||||||
|
with open(group_file, 'a') as f_group_file:
|
||||||
|
f_group_file.write("\n:doc:`/scripts/%s`\n" % doc_names[i])
|
||||||
|
for line in summary_comments:
|
||||||
|
f_group_file.write(" " + line)
|
84
doc/cluster.rst
Normal file
84
doc/cluster.rst
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
Bro Cluster
|
||||||
|
===========
|
||||||
|
|
||||||
|
Intro
|
||||||
|
------
|
||||||
|
|
||||||
|
Bro is not multithreaded, so once the limitations of a single processor core are reached, the only option currently is to spread the workload across many cores or even many physical computers. The cluster deployment scenario for Bro is the current solution to build these larger systems. The accompanying tools and scripts provide the structure to easily manage many Bro processes examining packets and doing correlation activities but acting as a singular, cohesive entity.
|
||||||
|
|
||||||
|
Architecture
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The figure below illustrates the main components of a Bro cluster.
|
||||||
|
|
||||||
|
.. image:: images/deployment.png
|
||||||
|
|
||||||
|
Tap
|
||||||
|
***
|
||||||
|
This is a mechanism that splits the packet stream in order to make a copy
|
||||||
|
available for inspection. Examples include the monitoring port on a switch and
|
||||||
|
an optical splitter for fiber networks.
|
||||||
|
|
||||||
|
Frontend
|
||||||
|
********
|
||||||
|
This is a discrete hardware device or on-host technique that will split your traffic into many streams or flows. The Bro binary does not do this job. There are numerous ways to accomplish this task, some of which are described below in `Frontend Options`_.
|
||||||
|
|
||||||
|
Manager
|
||||||
|
*******
|
||||||
|
This is a Bro process which has two primary jobs. It receives log messages and notices from the rest of the nodes in the cluster using the Bro communications protocol. The result is that you will end up with single logs for each log instead of many discrete logs that you have to later combine in some manner with post processing. The manager also takes the opportunity to de-duplicate notices and it has the ability to do so since it’s acting as the choke point for notices and how notices might be processed into actions such as emailing, paging, or blocking.
|
||||||
|
|
||||||
|
The manager process is started first by BroControl and it only opens it’s designated port and waits for connections, it doesn’t initiate any connections to the rest of the cluster. Once the workers are started and connect to the manager, logs and notices will start arriving to the manager process from the workers.
|
||||||
|
|
||||||
|
Proxy
|
||||||
|
*****
|
||||||
|
This is a Bro process which manages synchronized state. Variables can be synchronized across connected Bro processes automatically in Bro and proxies will help the workers by alleviating the need for all of the workers to connect directly to each other.
|
||||||
|
|
||||||
|
Examples of synchronized state from the scripts that ship with Bro are things such as the full list of “known” hosts and services which are hosts or services which have been detected as performing full TCP handshakes or an analyzed protocol has been found on the connection. If worker A detects host 1.2.3.4 as an active host, it would be beneficial for worker B to know that as well so worker A shares that information as an insertion to a set <link to set documentation would be good here> which travels to the cluster’s proxy and the proxy then sends that same set insertion to worker B. The result is that worker A and worker B have shared knowledge about host and services that are active on the network being monitored.
|
||||||
|
|
||||||
|
The proxy model extends to having multiple proxies as well if necessary for performance reasons, it only adds one additional step for the Bro processes. Each proxy connects to another proxy in a ring and the workers are shared between them as evenly as possible. When a proxy receives some new bit of state, it will share that with it’s proxy which is then shared around the ring of proxies and down to all of the workers. From a practical standpoint, there are no rules of thumb established yet for the number of proxies necessary for the number of workers they are serving. Best is to start with a single proxy and add more if communication performance problems are found.
|
||||||
|
|
||||||
|
Bro processes acting as proxies don’t tend to be extremely intense to CPU or memory and users frequently run proxy processes on the same physical host as the manager.
|
||||||
|
|
||||||
|
Worker
|
||||||
|
******
|
||||||
|
This is the Bro process that sniffs network traffic and does protocol analysis on the reassembled traffic streams. Most of the work of an active cluster takes place on the workers and as such, the workers typically represent the bulk of the Bro processes that are running in a cluster. The fastest memory and CPU core speed you can afford is best here since all of the protocol parsing and most analysis will take place here. There are no particular requirements for the disks in workers since almost all logging is done remotely to the manager and very little is normally written to disk.
|
||||||
|
|
||||||
|
The rule of thumb we have followed recently is to allocate approximately 1 core for every 80Mbps of traffic that is being analyzed, however this estimate could be extremely traffic mix specific. It has generally worked for mixed traffic with many users and servers. For example, if your traffic peaks around 2Gbps (combined) and you want to handle traffic at peak load, you may want to have 26 cores available (2048 / 80 == 25.6). If the 80Mbps estimate works for your traffic, this could be handled by 3 physical hosts dedicated to being workers with each one containing dual 6-core processors.
|
||||||
|
|
||||||
|
Once a flow based load balancer is put into place this model is extremely easy to scale as well so it’s recommended that you guess at the amount of hardware you will need to fully analyze your traffic. If it turns out that you need more, it’s relatively easy to increase the size of the cluster in most cases.
|
||||||
|
|
||||||
|
Frontend Options
|
||||||
|
----------------
|
||||||
|
|
||||||
|
There are many options for setting up a frontend flow distributor and in many cases it may even be beneficial to do multiple stages of flow distribution on the network and on the host.
|
||||||
|
|
||||||
|
Discrete hardware flow balancers
|
||||||
|
********************************
|
||||||
|
|
||||||
|
cPacket
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
If you are monitoring one or more 10G physical interfaces, the recommended solution is to use either a cFlow or cVu device from cPacket because they are currently being used very successfully at a number of sites. These devices will perform layer-2 load balancing by rewriting the destination ethernet MAC address to cause each packet associated with a particular flow to have the same destination MAC. The packets can then be passed directly to a monitoring host where each worker has a BPF filter to limit its visibility to only that stream of flows or onward to a commodity switch to split the traffic out to multiple 1G interfaces for the workers. This can ultimately greatly reduce costs since workers can use relatively inexpensive 1G interfaces.
|
||||||
|
|
||||||
|
OpenFlow Switches
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
We are currently exploring the use of OpenFlow based switches to do flow based load balancing directly on the switch which can greatly reduce frontend costs for many users. This document will be updated when we have more information.
|
||||||
|
|
||||||
|
On host flow balancing
|
||||||
|
**********************
|
||||||
|
|
||||||
|
PF_RING
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
The PF_RING software for Linux has a “clustering” feature which will do flow based load balancing across a number of processes that are sniffing the same interface. This will allow you to easily take advantage of multiple cores in a single physical host because Bro’s main event loop is single threaded and can’t natively utilize all of the cores. More information about Bro with PF_RING can be found here: (someone want to write a quick Bro/PF_RING tutorial to link to here? document installing kernel module, libpcap wrapper, building Bro with the --with-pcap configure option)
|
||||||
|
|
||||||
|
Netmap
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
FreeBSD has an in-progress project named Netmap which will enable flow based load balancing as well. When it becomes viable for real world use, this document will be updated.
|
||||||
|
|
||||||
|
Click! Software Router
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Click! can be used for flow based load balancing with a simple configuration. (link to an example for the config). This solution is not recommended on Linux due to Bro’s PF_RING support and only as a last resort on other operating systems since it causes a lot of overhead due to context switching back and forth between kernel and userland several times per packet.
|
1
doc/components/binpac/README.rst
Symbolic link
1
doc/components/binpac/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/binpac/README
|
1
doc/components/bro-aux/README.rst
Symbolic link
1
doc/components/bro-aux/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/bro-aux/README
|
1
doc/components/broccoli-python/README.rst
Symbolic link
1
doc/components/broccoli-python/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broccoli/bindings/broccoli-python/README
|
1
doc/components/broccoli-ruby/README.rst
Symbolic link
1
doc/components/broccoli-ruby/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broccoli/bindings/broccoli-ruby/README
|
1
doc/components/broccoli/README.rst
Symbolic link
1
doc/components/broccoli/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broccoli/README
|
1
doc/components/broccoli/broccoli-manual.rst
Symbolic link
1
doc/components/broccoli/broccoli-manual.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broccoli/doc/broccoli-manual.rst
|
1
doc/components/broctl/README.rst
Symbolic link
1
doc/components/broctl/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broctl/doc/broctl.rst
|
1
doc/components/btest/README.rst
Symbolic link
1
doc/components/btest/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/btest/README
|
1
doc/components/capstats/README.rst
Symbolic link
1
doc/components/capstats/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broctl/aux/capstats/README
|
1
doc/components/pysubnettree/README.rst
Symbolic link
1
doc/components/pysubnettree/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broctl/aux/pysubnettree/README
|
1
doc/components/trace-summary/README.rst
Symbolic link
1
doc/components/trace-summary/README.rst
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../aux/broctl/aux/trace-summary/README
|
222
doc/conf.py.in
Normal file
222
doc/conf.py.in
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Bro documentation build configuration file, created by sphinx-quickstart
|
||||||
|
#
|
||||||
|
# This file is execfile()d with the current directory set to its containing dir.
|
||||||
|
#
|
||||||
|
# Note that not all possible configuration values are present in this
|
||||||
|
# autogenerated file.
|
||||||
|
#
|
||||||
|
# All configuration values have a default; values that are commented out
|
||||||
|
# serve to show the default.
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
sys.path.insert(0, os.path.abspath('sphinx-sources/ext'))
|
||||||
|
|
||||||
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
|
#needs_sphinx = '1.0'
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
|
extensions = ['bro', 'rst_directive', 'sphinx.ext.todo', 'adapt-toc']
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['sphinx-sources/_templates', 'sphinx-sources/_static']
|
||||||
|
|
||||||
|
# The suffix of source filenames.
|
||||||
|
source_suffix = '.rst'
|
||||||
|
|
||||||
|
# The encoding of source files.
|
||||||
|
#source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
|
# The master toctree document.
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
# General information about the project.
|
||||||
|
project = u'Bro'
|
||||||
|
copyright = u'2012, The Bro Project'
|
||||||
|
|
||||||
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
# built documents.
|
||||||
|
#
|
||||||
|
# The short X.Y version.
|
||||||
|
version = '@VERSION_MAJ_MIN@'
|
||||||
|
# The full version, including alpha/beta/rc tags.
|
||||||
|
release = '@VERSION@'
|
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
# for a list of supported languages.
|
||||||
|
#language = None
|
||||||
|
|
||||||
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
|
# non-false value, then it is used:
|
||||||
|
#today = ''
|
||||||
|
# Else, today_fmt is used as the format for a strftime call.
|
||||||
|
today_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
exclude_patterns = []
|
||||||
|
|
||||||
|
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||||
|
#default_role = None
|
||||||
|
|
||||||
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
|
#add_function_parentheses = True
|
||||||
|
|
||||||
|
# If true, the current module name will be prepended to all description
|
||||||
|
# unit titles (such as .. function::).
|
||||||
|
#add_module_names = True
|
||||||
|
|
||||||
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
|
# output. They are ignored by default.
|
||||||
|
show_authors = True
|
||||||
|
|
||||||
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
# A list of ignored prefixes for module index sorting.
|
||||||
|
#modindex_common_prefix = []
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output ---------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
html_theme = 'basic'
|
||||||
|
|
||||||
|
html_last_updated_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
|
# further. For a list of options available for each theme, see the
|
||||||
|
# documentation.
|
||||||
|
html_theme_options = { }
|
||||||
|
|
||||||
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
|
#html_theme_path = []
|
||||||
|
|
||||||
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
|
# "<project> v<release> Documentation".
|
||||||
|
#html_title = None
|
||||||
|
|
||||||
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||||
|
#html_short_title = None
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
|
# of the sidebar.
|
||||||
|
#html_logo = None
|
||||||
|
|
||||||
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
|
# pixels large.
|
||||||
|
#html_favicon = None
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['sphinx-sources/_static']
|
||||||
|
|
||||||
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
|
# using the given strftime format.
|
||||||
|
#html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
|
||||||
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
|
# typographically correct entities.
|
||||||
|
#html_use_smartypants = True
|
||||||
|
|
||||||
|
# Custom sidebar templates, maps document names to template names.
|
||||||
|
html_sidebars = {
|
||||||
|
'**': ['localtoc.html', 'sourcelink.html', 'searchbox.html'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
|
# template names.
|
||||||
|
#html_additional_pages = {}
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#html_domain_indices = True
|
||||||
|
|
||||||
|
# If false, no index is generated.
|
||||||
|
#html_use_index = True
|
||||||
|
|
||||||
|
# If true, the index is split into individual pages for each letter.
|
||||||
|
#html_split_index = False
|
||||||
|
|
||||||
|
# If true, links to the reST sources are added to the pages.
|
||||||
|
#html_show_sourcelink = True
|
||||||
|
|
||||||
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_sphinx = True
|
||||||
|
|
||||||
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_copyright = True
|
||||||
|
|
||||||
|
# If true, an OpenSearch description file will be output, and all pages will
|
||||||
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
|
# base URL from which the finished HTML is served.
|
||||||
|
#html_use_opensearch = ''
|
||||||
|
|
||||||
|
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||||
|
#html_file_suffix = None
|
||||||
|
|
||||||
|
# Output file base name for HTML help builder.
|
||||||
|
htmlhelp_basename = 'Broxygen'
|
||||||
|
|
||||||
|
html_add_permalinks = None
|
||||||
|
|
||||||
|
# -- Options for LaTeX output --------------------------------------------------
|
||||||
|
|
||||||
|
# The paper size ('letter' or 'a4').
|
||||||
|
#latex_paper_size = 'letter'
|
||||||
|
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
|
#latex_font_size = '10pt'
|
||||||
|
|
||||||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
|
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||||
|
latex_documents = [
|
||||||
|
('index', 'Bro.tex', u'Bro Documentation',
|
||||||
|
u'The Bro Project', 'manual'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
# the title page.
|
||||||
|
#latex_logo = None
|
||||||
|
|
||||||
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
|
# not chapters.
|
||||||
|
#latex_use_parts = False
|
||||||
|
|
||||||
|
# If true, show page references after internal links.
|
||||||
|
#latex_show_pagerefs = False
|
||||||
|
|
||||||
|
# If true, show URL addresses after external links.
|
||||||
|
#latex_show_urls = False
|
||||||
|
|
||||||
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#latex_preamble = ''
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#latex_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#latex_domain_indices = True
|
||||||
|
|
||||||
|
# -- Options for manual page output --------------------------------------------
|
||||||
|
|
||||||
|
# One entry per manual page. List of tuples
|
||||||
|
# (source start file, name, description, authors, manual section).
|
||||||
|
man_pages = [
|
||||||
|
('index', 'bro', u'Bro Documentation',
|
||||||
|
[u'The Bro Project'], 1)
|
||||||
|
]
|
||||||
|
|
||||||
|
# -- Options for todo plugin --------------------------------------------
|
||||||
|
todo_include_todos=True
|
29
doc/ext/adapt-toc.py
Normal file
29
doc/ext/adapt-toc.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Removes the first TOC level, which is just the page title.
|
||||||
|
def process_html_toc(app, pagename, templatename, context, doctree):
|
||||||
|
|
||||||
|
if not "toc" in context:
|
||||||
|
return
|
||||||
|
|
||||||
|
toc = context["toc"]
|
||||||
|
|
||||||
|
lines = toc.strip().split("\n")
|
||||||
|
lines = lines[2:-2]
|
||||||
|
|
||||||
|
toc = "\n".join(lines)
|
||||||
|
toc = "<ul>" + toc
|
||||||
|
|
||||||
|
context["toc"] = toc
|
||||||
|
|
||||||
|
# print >>sys.stderr, pagename
|
||||||
|
# print >>sys.stderr, context["toc"]
|
||||||
|
# print >>sys.stderr, "-----"
|
||||||
|
# print >>sys.stderr, toc
|
||||||
|
# print >>sys.stderr, "===="
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.connect('html-page-context', process_html_toc)
|
||||||
|
|
266
doc/ext/bro.py
Normal file
266
doc/ext/bro.py
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
"""
|
||||||
|
The Bro domain for Sphinx.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setup(Sphinx):
|
||||||
|
Sphinx.add_domain(BroDomain)
|
||||||
|
Sphinx.add_node(see)
|
||||||
|
Sphinx.add_directive_to_domain('bro', 'see', SeeDirective)
|
||||||
|
Sphinx.connect('doctree-resolved', process_see_nodes)
|
||||||
|
|
||||||
|
from sphinx import addnodes
|
||||||
|
from sphinx.domains import Domain, ObjType, Index
|
||||||
|
from sphinx.locale import l_, _
|
||||||
|
from sphinx.directives import ObjectDescription
|
||||||
|
from sphinx.roles import XRefRole
|
||||||
|
from sphinx.util.nodes import make_refnode
|
||||||
|
import string
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst import Directive
|
||||||
|
from docutils.parsers.rst import directives
|
||||||
|
from docutils.parsers.rst.roles import set_classes
|
||||||
|
|
||||||
|
class see(nodes.General, nodes.Element):
|
||||||
|
refs = []
|
||||||
|
|
||||||
|
class SeeDirective(Directive):
|
||||||
|
has_content = True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
n = see('')
|
||||||
|
n.refs = string.split(string.join(self.content))
|
||||||
|
return [n]
|
||||||
|
|
||||||
|
def process_see_nodes(app, doctree, fromdocname):
|
||||||
|
for node in doctree.traverse(see):
|
||||||
|
content = []
|
||||||
|
para = nodes.paragraph()
|
||||||
|
para += nodes.Text("See also:", "See also:")
|
||||||
|
for name in node.refs:
|
||||||
|
join_str = " "
|
||||||
|
if name != node.refs[0]:
|
||||||
|
join_str = ", "
|
||||||
|
link_txt = join_str + name;
|
||||||
|
|
||||||
|
if name not in app.env.domaindata['bro']['idtypes']:
|
||||||
|
# Just create the text and issue warning
|
||||||
|
app.env.warn(fromdocname,
|
||||||
|
'unknown target for ".. bro:see:: %s"' % (name))
|
||||||
|
para += nodes.Text(link_txt, link_txt)
|
||||||
|
else:
|
||||||
|
# Create a reference
|
||||||
|
typ = app.env.domaindata['bro']['idtypes'][name]
|
||||||
|
todocname = app.env.domaindata['bro']['objects'][(typ, name)]
|
||||||
|
|
||||||
|
newnode = nodes.reference('', '')
|
||||||
|
innernode = nodes.literal(_(name), _(name))
|
||||||
|
newnode['refdocname'] = todocname
|
||||||
|
newnode['refuri'] = app.builder.get_relative_uri(
|
||||||
|
fromdocname, todocname)
|
||||||
|
newnode['refuri'] += '#' + typ + '-' + name
|
||||||
|
newnode.append(innernode)
|
||||||
|
para += nodes.Text(join_str, join_str)
|
||||||
|
para += newnode
|
||||||
|
|
||||||
|
content.append(para)
|
||||||
|
node.replace_self(content)
|
||||||
|
|
||||||
|
class BroGeneric(ObjectDescription):
|
||||||
|
def update_type_map(self, idname):
|
||||||
|
if 'idtypes' not in self.env.domaindata['bro']:
|
||||||
|
self.env.domaindata['bro']['idtypes'] = {}
|
||||||
|
self.env.domaindata['bro']['idtypes'][idname] = self.objtype
|
||||||
|
|
||||||
|
def add_target_and_index(self, name, sig, signode):
|
||||||
|
targetname = self.objtype + '-' + name
|
||||||
|
if targetname not in self.state.document.ids:
|
||||||
|
signode['names'].append(targetname)
|
||||||
|
signode['ids'].append(targetname)
|
||||||
|
signode['first'] = (not self.names)
|
||||||
|
self.state.document.note_explicit_target(signode)
|
||||||
|
|
||||||
|
objects = self.env.domaindata['bro']['objects']
|
||||||
|
key = (self.objtype, name)
|
||||||
|
if key in objects:
|
||||||
|
self.env.warn(self.env.docname,
|
||||||
|
'duplicate description of %s %s, ' %
|
||||||
|
(self.objtype, name) +
|
||||||
|
'other instance in ' +
|
||||||
|
self.env.doc2path(objects[key]),
|
||||||
|
self.lineno)
|
||||||
|
objects[key] = self.env.docname
|
||||||
|
self.update_type_map(name)
|
||||||
|
|
||||||
|
indextext = self.get_index_text(self.objtype, name)
|
||||||
|
if indextext:
|
||||||
|
self.indexnode['entries'].append(('single', indextext,
|
||||||
|
targetname, targetname))
|
||||||
|
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
return _('%s (%s)') % (name, self.objtype)
|
||||||
|
|
||||||
|
def handle_signature(self, sig, signode):
|
||||||
|
signode += addnodes.desc_name("", sig)
|
||||||
|
return sig
|
||||||
|
|
||||||
|
class BroNamespace(BroGeneric):
|
||||||
|
def add_target_and_index(self, name, sig, signode):
|
||||||
|
targetname = self.objtype + '-' + name
|
||||||
|
if targetname not in self.state.document.ids:
|
||||||
|
signode['names'].append(targetname)
|
||||||
|
signode['ids'].append(targetname)
|
||||||
|
signode['first'] = (not self.names)
|
||||||
|
self.state.document.note_explicit_target(signode)
|
||||||
|
|
||||||
|
objects = self.env.domaindata['bro']['objects']
|
||||||
|
key = (self.objtype, name)
|
||||||
|
objects[key] = self.env.docname
|
||||||
|
self.update_type_map(name)
|
||||||
|
|
||||||
|
indextext = self.get_index_text(self.objtype, name)
|
||||||
|
self.indexnode['entries'].append(('single', indextext,
|
||||||
|
targetname, targetname))
|
||||||
|
self.indexnode['entries'].append(('single',
|
||||||
|
"namespaces; %s" % (sig),
|
||||||
|
targetname, targetname))
|
||||||
|
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
return _('%s (namespace); %s') % (name, self.env.docname)
|
||||||
|
|
||||||
|
def handle_signature(self, sig, signode):
|
||||||
|
signode += addnodes.desc_name("", sig)
|
||||||
|
return sig
|
||||||
|
|
||||||
|
class BroEnum(BroGeneric):
|
||||||
|
def add_target_and_index(self, name, sig, signode):
|
||||||
|
targetname = self.objtype + '-' + name
|
||||||
|
if targetname not in self.state.document.ids:
|
||||||
|
signode['names'].append(targetname)
|
||||||
|
signode['ids'].append(targetname)
|
||||||
|
signode['first'] = (not self.names)
|
||||||
|
self.state.document.note_explicit_target(signode)
|
||||||
|
|
||||||
|
objects = self.env.domaindata['bro']['objects']
|
||||||
|
key = (self.objtype, name)
|
||||||
|
objects[key] = self.env.docname
|
||||||
|
self.update_type_map(name)
|
||||||
|
|
||||||
|
indextext = self.get_index_text(self.objtype, name)
|
||||||
|
#self.indexnode['entries'].append(('single', indextext,
|
||||||
|
# targetname, targetname))
|
||||||
|
m = sig.split()
|
||||||
|
if m[1] == "Notice::Type":
|
||||||
|
if 'notices' not in self.env.domaindata['bro']:
|
||||||
|
self.env.domaindata['bro']['notices'] = []
|
||||||
|
self.env.domaindata['bro']['notices'].append(
|
||||||
|
(m[0], self.env.docname, targetname))
|
||||||
|
self.indexnode['entries'].append(('single',
|
||||||
|
"%s (enum values); %s" % (m[1], m[0]),
|
||||||
|
targetname, targetname))
|
||||||
|
|
||||||
|
def handle_signature(self, sig, signode):
|
||||||
|
m = sig.split()
|
||||||
|
name = m[0]
|
||||||
|
signode += addnodes.desc_name("", name)
|
||||||
|
return name
|
||||||
|
|
||||||
|
class BroIdentifier(BroGeneric):
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
return name
|
||||||
|
|
||||||
|
class BroAttribute(BroGeneric):
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
return _('%s (attribute)') % (name)
|
||||||
|
|
||||||
|
class BroNotices(Index):
|
||||||
|
"""
|
||||||
|
Index subclass to provide the Bro notices index.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = 'noticeindex'
|
||||||
|
localname = l_('Bro Notice Index')
|
||||||
|
shortname = l_('notices')
|
||||||
|
|
||||||
|
def generate(self, docnames=None):
|
||||||
|
content = {}
|
||||||
|
for n in self.domain.env.domaindata['bro']['notices']:
|
||||||
|
modname = n[0].split("::")[0]
|
||||||
|
entries = content.setdefault(modname, [])
|
||||||
|
entries.append([n[0], 0, n[1], n[2], '', '', ''])
|
||||||
|
|
||||||
|
content = sorted(content.iteritems())
|
||||||
|
|
||||||
|
return content, False
|
||||||
|
|
||||||
|
class BroDomain(Domain):
|
||||||
|
"""Bro domain."""
|
||||||
|
name = 'bro'
|
||||||
|
label = 'Bro'
|
||||||
|
|
||||||
|
object_types = {
|
||||||
|
'type': ObjType(l_('type'), 'type'),
|
||||||
|
'namespace': ObjType(l_('namespace'), 'namespace'),
|
||||||
|
'id': ObjType(l_('id'), 'id'),
|
||||||
|
'enum': ObjType(l_('enum'), 'enum'),
|
||||||
|
'attr': ObjType(l_('attr'), 'attr'),
|
||||||
|
}
|
||||||
|
|
||||||
|
directives = {
|
||||||
|
'type': BroGeneric,
|
||||||
|
'namespace': BroNamespace,
|
||||||
|
'id': BroIdentifier,
|
||||||
|
'enum': BroEnum,
|
||||||
|
'attr': BroAttribute,
|
||||||
|
}
|
||||||
|
|
||||||
|
roles = {
|
||||||
|
'type': XRefRole(),
|
||||||
|
'namespace': XRefRole(),
|
||||||
|
'id': XRefRole(),
|
||||||
|
'enum': XRefRole(),
|
||||||
|
'attr': XRefRole(),
|
||||||
|
'see': XRefRole(),
|
||||||
|
}
|
||||||
|
|
||||||
|
indices = [
|
||||||
|
BroNotices,
|
||||||
|
]
|
||||||
|
|
||||||
|
initial_data = {
|
||||||
|
'objects': {}, # fullname -> docname, objtype
|
||||||
|
}
|
||||||
|
|
||||||
|
def clear_doc(self, docname):
|
||||||
|
for (typ, name), doc in self.data['objects'].items():
|
||||||
|
if doc == docname:
|
||||||
|
del self.data['objects'][typ, name]
|
||||||
|
|
||||||
|
def resolve_xref(self, env, fromdocname, builder, typ, target, node,
|
||||||
|
contnode):
|
||||||
|
objects = self.data['objects']
|
||||||
|
if typ == "see":
|
||||||
|
if target not in self.data['idtypes']:
|
||||||
|
self.env.warn(fromdocname,
|
||||||
|
'unknown target for ":bro:see:`%s`"' % (target))
|
||||||
|
return []
|
||||||
|
objtype = self.data['idtypes'][target]
|
||||||
|
return make_refnode(builder, fromdocname,
|
||||||
|
objects[objtype, target],
|
||||||
|
objtype + '-' + target,
|
||||||
|
contnode, target + ' ' + objtype)
|
||||||
|
else:
|
||||||
|
objtypes = self.objtypes_for_role(typ)
|
||||||
|
for objtype in objtypes:
|
||||||
|
if (objtype, target) in objects:
|
||||||
|
return make_refnode(builder, fromdocname,
|
||||||
|
objects[objtype, target],
|
||||||
|
objtype + '-' + target,
|
||||||
|
contnode, target + ' ' + objtype)
|
||||||
|
else:
|
||||||
|
self.env.warn(fromdocname,
|
||||||
|
'unknown target for ":bro:%s:`%s`"' % (typ, target))
|
||||||
|
|
||||||
|
def get_objects(self):
|
||||||
|
for (typ, name), docname in self.data['objects'].iteritems():
|
||||||
|
yield name, name, typ, docname, typ + '-' + name, 1
|
BIN
doc/ext/bro_lexer/__init__.pyc
Normal file
BIN
doc/ext/bro_lexer/__init__.pyc
Normal file
Binary file not shown.
76
doc/ext/bro_lexer/bro.py
Normal file
76
doc/ext/bro_lexer/bro.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
from pygments.lexer import RegexLexer, bygroups, include
|
||||||
|
from pygments.token import *
|
||||||
|
|
||||||
|
__all__ = ["BroLexer"]
|
||||||
|
|
||||||
|
class BroLexer(RegexLexer):
|
||||||
|
name = 'Bro'
|
||||||
|
aliases = ['bro']
|
||||||
|
filenames = ['*.bro']
|
||||||
|
|
||||||
|
_hex = r'[0-9a-fA-F_]+'
|
||||||
|
_float = r'((\d*\.?\d+)|(\d+\.?\d*))([eE][-+]?\d+)?'
|
||||||
|
_h = r'[A-Za-z0-9][-A-Za-z0-9]*'
|
||||||
|
|
||||||
|
tokens = {
|
||||||
|
'root': [
|
||||||
|
# Whitespace
|
||||||
|
('^@.*?\n', Comment.Preproc),
|
||||||
|
(r'#.*?\n', Comment.Single),
|
||||||
|
(r'\n', Text),
|
||||||
|
(r'\s+', Text),
|
||||||
|
(r'\\\n', Text),
|
||||||
|
# Keywords
|
||||||
|
(r'(add|alarm|break|case|const|continue|delete|do|else|enum|event'
|
||||||
|
r'|export|for|function|if|global|local|module|next'
|
||||||
|
r'|of|print|redef|return|schedule|when|while)\b', Keyword),
|
||||||
|
(r'(addr|any|bool|count|counter|double|file|int|interval|net'
|
||||||
|
r'|pattern|port|record|set|string|subnet|table|time|timer'
|
||||||
|
r'|vector)\b', Keyword.Type),
|
||||||
|
(r'(T|F)\b', Keyword.Constant),
|
||||||
|
(r'(&)((?:add|delete|expire)_func|attr|(create|read|write)_expire'
|
||||||
|
r'|default|disable_print_hook|raw_output|encrypt|group|log'
|
||||||
|
r'|mergeable|optional|persistent|priority|redef'
|
||||||
|
r'|rotate_(?:interval|size)|synchronized)\b', bygroups(Punctuation,
|
||||||
|
Keyword)),
|
||||||
|
(r'\s+module\b', Keyword.Namespace),
|
||||||
|
# Addresses, ports and networks
|
||||||
|
(r'\d+/(tcp|udp|icmp|unknown)\b', Number),
|
||||||
|
(r'(\d+\.){3}\d+', Number),
|
||||||
|
(r'(' + _hex + r'){7}' + _hex, Number),
|
||||||
|
(r'0x' + _hex + r'(' + _hex + r'|:)*::(' + _hex + r'|:)*', Number),
|
||||||
|
(r'((\d+|:)(' + _hex + r'|:)*)?::(' + _hex + r'|:)*', Number),
|
||||||
|
(r'(\d+\.\d+\.|(\d+\.){2}\d+)', Number),
|
||||||
|
# Hostnames
|
||||||
|
(_h + r'(\.' + _h + r')+', String),
|
||||||
|
# Numeric
|
||||||
|
(_float + r'\s+(day|hr|min|sec|msec|usec)s?\b', Literal.Date),
|
||||||
|
(r'0[xX]' + _hex, Number.Hex),
|
||||||
|
(_float, Number.Float),
|
||||||
|
(r'\d+', Number.Integer),
|
||||||
|
(r'/', String.Regex, 'regex'),
|
||||||
|
(r'"', String, 'string'),
|
||||||
|
# Operators
|
||||||
|
(r'[!%*/+-:<=>?~|]', Operator),
|
||||||
|
(r'([-+=&|]{2}|[+-=!><]=)', Operator),
|
||||||
|
(r'(in|match)\b', Operator.Word),
|
||||||
|
(r'[{}()\[\]$.,;]', Punctuation),
|
||||||
|
# Identfier
|
||||||
|
(r'([_a-zA-Z]\w*)(::)', bygroups(Name, Name.Namespace)),
|
||||||
|
(r'[a-zA-Z_][a-zA-Z_0-9]*', Name)
|
||||||
|
],
|
||||||
|
'string': [
|
||||||
|
(r'"', String, '#pop'),
|
||||||
|
(r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
|
||||||
|
(r'[^\\"\n]+', String),
|
||||||
|
(r'\\\n', String),
|
||||||
|
(r'\\', String)
|
||||||
|
],
|
||||||
|
'regex': [
|
||||||
|
(r'/', String.Regex, '#pop'),
|
||||||
|
(r'\\[\\nt/]', String.Regex), # String.Escape is too intense.
|
||||||
|
(r'[^\\/\n]+', String.Regex),
|
||||||
|
(r'\\\n', String.Regex),
|
||||||
|
(r'\\', String.Regex)
|
||||||
|
]
|
||||||
|
}
|
BIN
doc/ext/bro_lexer/bro.pyc
Normal file
BIN
doc/ext/bro_lexer/bro.pyc
Normal file
Binary file not shown.
180
doc/ext/rst_directive.py
Normal file
180
doc/ext/rst_directive.py
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
def setup(app):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
|
||||||
|
Modified version of the the Pygments reStructuredText directive. -Robin
|
||||||
|
|
||||||
|
This provides two new directives:
|
||||||
|
|
||||||
|
- .. code:: [<format>]
|
||||||
|
|
||||||
|
Highlights the following code block according to <format> if
|
||||||
|
given (e.g., "c", "python", etc.).
|
||||||
|
|
||||||
|
- .. console::
|
||||||
|
|
||||||
|
Highlits the following code block as a shell session.
|
||||||
|
|
||||||
|
For compatibility with the original version, "sourcecode" is
|
||||||
|
equivalent to "code".
|
||||||
|
|
||||||
|
Original comment:
|
||||||
|
|
||||||
|
The Pygments reStructuredText directive
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This fragment is a Docutils_ 0.5 directive that renders source code
|
||||||
|
(to HTML only, currently) via Pygments.
|
||||||
|
|
||||||
|
To use it, adjust the options below and copy the code into a module
|
||||||
|
that you import on initialization. The code then automatically
|
||||||
|
registers a ``sourcecode`` directive that you can use instead of
|
||||||
|
normal code blocks like this::
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
My code goes here.
|
||||||
|
|
||||||
|
If you want to have different code styles, e.g. one with line numbers
|
||||||
|
and one without, add formatters with their names in the VARIANTS dict
|
||||||
|
below. You can invoke them instead of the DEFAULT one by using a
|
||||||
|
directive option::
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
My code goes here.
|
||||||
|
|
||||||
|
Look at the `directive documentation`_ to get all the gory details.
|
||||||
|
|
||||||
|
.. _Docutils: http://docutils.sf.net/
|
||||||
|
.. _directive documentation:
|
||||||
|
http://docutils.sourceforge.net/docs/howto/rst-directives.html
|
||||||
|
|
||||||
|
:copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Options
|
||||||
|
# ~~~~~~~
|
||||||
|
|
||||||
|
# Set to True if you want inline CSS styles instead of classes
|
||||||
|
INLINESTYLES = False
|
||||||
|
|
||||||
|
from pygments.formatters import HtmlFormatter
|
||||||
|
|
||||||
|
class MyHtmlFormatter(HtmlFormatter):
|
||||||
|
def format_unencoded(self, tokensource, outfile):
|
||||||
|
|
||||||
|
# A NOP currently.
|
||||||
|
new_tokens = []
|
||||||
|
for (i, piece) in tokensource:
|
||||||
|
new_tokens += [(i, piece)]
|
||||||
|
|
||||||
|
return super(MyHtmlFormatter, self).format_unencoded(new_tokens, outfile)
|
||||||
|
|
||||||
|
# The default formatter
|
||||||
|
DEFAULT = MyHtmlFormatter(noclasses=INLINESTYLES, cssclass="pygments")
|
||||||
|
|
||||||
|
# Add name -> formatter pairs for every variant you want to use
|
||||||
|
VARIANTS = {
|
||||||
|
# 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst import directives, Directive
|
||||||
|
|
||||||
|
from pygments import highlight
|
||||||
|
from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer
|
||||||
|
from pygments.token import Text, Keyword, Error, Operator, Name
|
||||||
|
from pygments.filter import Filter
|
||||||
|
|
||||||
|
# Ugly hack to register the Bro lexer. I'm sure there's a better way to do it,
|
||||||
|
# but it's not obvious ...
|
||||||
|
from bro_lexer.bro import BroLexer
|
||||||
|
from pygments.lexers._mapping import LEXERS
|
||||||
|
LEXERS['BroLexer'] = ('bro_lexer.bro', BroLexer.name, BroLexer.aliases, BroLexer.filenames, ())
|
||||||
|
|
||||||
|
class Pygments(Directive):
|
||||||
|
""" Source code syntax hightlighting.
|
||||||
|
"""
|
||||||
|
#max_line_length = 68
|
||||||
|
max_line_length = 0
|
||||||
|
|
||||||
|
required_arguments = 0
|
||||||
|
optional_arguments = 1
|
||||||
|
final_argument_whitespace = True
|
||||||
|
option_spec = dict([(key, directives.flag) for key in VARIANTS])
|
||||||
|
has_content = True
|
||||||
|
|
||||||
|
def wrapped_content(self):
|
||||||
|
content = []
|
||||||
|
|
||||||
|
if Console.max_line_length:
|
||||||
|
for line in self.content:
|
||||||
|
content += textwrap.wrap(line, Console.max_line_length, subsequent_indent=" ")
|
||||||
|
else:
|
||||||
|
content = self.content
|
||||||
|
|
||||||
|
return u'\n'.join(content)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.assert_has_content()
|
||||||
|
|
||||||
|
content = self.wrapped_content()
|
||||||
|
|
||||||
|
if len(self.arguments) > 0:
|
||||||
|
try:
|
||||||
|
lexer = get_lexer_by_name(self.arguments[0])
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
# lexer not found, use default.
|
||||||
|
lexer = TextLexer()
|
||||||
|
else:
|
||||||
|
lexer = guess_lexer(content)
|
||||||
|
|
||||||
|
# import sys
|
||||||
|
# print >>sys.stderr, self.arguments, lexer.__class__
|
||||||
|
|
||||||
|
# take an arbitrary option if more than one is given
|
||||||
|
formatter = self.options and VARIANTS[self.options.keys()[0]] or DEFAULT
|
||||||
|
parsed = highlight(content, lexer, formatter)
|
||||||
|
return [nodes.raw('', parsed, format='html')]
|
||||||
|
|
||||||
|
class MyFilter(Filter):
|
||||||
|
def filter(self, lexer, stream):
|
||||||
|
|
||||||
|
bol = True
|
||||||
|
|
||||||
|
for (ttype, value) in stream:
|
||||||
|
# Color the '>' prompt sign.
|
||||||
|
if bol and ttype is Text and value == ">":
|
||||||
|
ttype = Name.Variable.Class # This gives us a nice red.
|
||||||
|
|
||||||
|
# Discolor builtin, that can look funny.
|
||||||
|
if ttype is Name.Builtin:
|
||||||
|
ttype = Text
|
||||||
|
|
||||||
|
bol = value.endswith("\n")
|
||||||
|
|
||||||
|
yield (ttype, value)
|
||||||
|
|
||||||
|
class Console(Pygments):
|
||||||
|
required_arguments = 0
|
||||||
|
optional_arguments = 0
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.assert_has_content()
|
||||||
|
content = self.wrapped_content()
|
||||||
|
lexer = get_lexer_by_name("sh")
|
||||||
|
lexer.add_filter(MyFilter())
|
||||||
|
parsed = highlight(content, lexer, DEFAULT)
|
||||||
|
return [nodes.raw('', parsed, format='html')]
|
||||||
|
|
||||||
|
directives.register_directive('sourcecode', Pygments)
|
||||||
|
directives.register_directive('code', Pygments)
|
||||||
|
directives.register_directive('console', Console)
|
171
doc/faq.rst
Normal file
171
doc/faq.rst
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
|
||||||
|
==========================
|
||||||
|
Frequently Asked Questions
|
||||||
|
==========================
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div class="faq">
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
Installation and Configuration
|
||||||
|
==============================
|
||||||
|
|
||||||
|
How can I tune my operating system for best capture performance?
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
Here are some pointers to more information:
|
||||||
|
|
||||||
|
* Fabian Schneider's research on `high performance packet capture
|
||||||
|
<http://www.net.t-labs.tu-berlin.de/research/hppc>`_
|
||||||
|
|
||||||
|
* `NSMWiki <http://nsmwiki.org/Main_Page>`_ has page on
|
||||||
|
*Collecting Data*.
|
||||||
|
|
||||||
|
* An `IMC 2010 paper
|
||||||
|
<http://conferences.sigcomm.org/imc/2010/papers/p206.pdf>`_ by
|
||||||
|
Lothar Braun et. al evaluates packet capture performance on
|
||||||
|
commodity hardware
|
||||||
|
|
||||||
|
Are there any gotchas regarding interface configuration for live capture? Or why might I be seeing abnormally large packets much greater than interface MTU?
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Some NICs offload the reassembly of traffic into "superpackets" so that
|
||||||
|
fewer packets are then passed up the stack (e.g. "TCP segmentation
|
||||||
|
offload", or "generic segmentation offload"). The result is that the
|
||||||
|
capturing application will observe packets much larger than the MTU size
|
||||||
|
of the interface they were captured from and may also interfere with the
|
||||||
|
maximum packet capture length, ``snaplen``, so it's a good idea to disable
|
||||||
|
an interface's offloading features.
|
||||||
|
|
||||||
|
You can use the ``ethtool`` program on Linux to view and disable
|
||||||
|
offloading features of an interface. See this page for more explicit
|
||||||
|
directions:
|
||||||
|
|
||||||
|
http://securityonion.blogspot.com/2011/10/when-is-full-packet-capture-not-full.html
|
||||||
|
|
||||||
|
What does an error message like ``internal error: NB-DNS error`` mean?
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
That often means that DNS is not set up correctly on the system
|
||||||
|
running Bro. Try verifying from the command line that DNS lookups
|
||||||
|
work, e.g., ``host www.google.com``.
|
||||||
|
|
||||||
|
I am using OpenBSD and having problems installing Bro?
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
One potential issue is that the top-level Makefile may not work with
|
||||||
|
OpenBSD's default make program, in which case you can either install
|
||||||
|
the ``gmake`` package and use it instead or first change into the
|
||||||
|
``build/`` directory before doing either ``make`` or ``make install``
|
||||||
|
such that the CMake-generated Makefile's are used directly.
|
||||||
|
|
||||||
|
Generally, please note that we do not regularly test OpenBSD builds.
|
||||||
|
We appreciate any patches that improve Bro's support for this
|
||||||
|
platform.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
How can I identify backscatter?
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Identifying backscatter via connections labeled as ``OTH`` is not a reliable
|
||||||
|
means to detect backscatter. Backscatter is however visible by interpreting
|
||||||
|
the contents of the ``history`` field in the ``conn.log`` file. The basic idea
|
||||||
|
is to watch for connections that never had an initial ``SYN`` but started
|
||||||
|
instead with a ``SYN-ACK`` or ``RST`` (though this latter generally is just
|
||||||
|
discarded). Here are some history fields which provide backscatter examples:
|
||||||
|
``hAFf``, ``r``. Refer to the conn protocol analysis scripts to interpret the
|
||||||
|
individual character meanings in the history field.
|
||||||
|
|
||||||
|
Is there help for understanding Bro's resource consumption?
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
There are two scripts that collect statistics on resource usage:
|
||||||
|
``misc/stats.bro`` and ``misc/profiling.bro``. The former is quite
|
||||||
|
lightweight, while the latter should only be used for debugging.
|
||||||
|
|
||||||
|
How can I capture packets as an unprivileged user?
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Normally, unprivileged users cannot capture packets from a network interface,
|
||||||
|
which means they would not be able to use Bro to read/analyze live traffic.
|
||||||
|
However, there are operating system specific ways to enable packet capture
|
||||||
|
permission for non-root users, which is worth doing in the context of using
|
||||||
|
Bro to monitor live traffic.
|
||||||
|
|
||||||
|
With Linux Capabilities
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Fully implemented since Linux kernel 2.6.24, capabilities are a way of
|
||||||
|
parceling superuser privileges into distinct units. Attach capabilities
|
||||||
|
required to capture packets to the ``bro`` executable file like this:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo setcap cap_net_raw,cap_net_admin=eip /path/to/bro
|
||||||
|
|
||||||
|
Now any unprivileged user should have the capability to capture packets
|
||||||
|
using Bro provided that they have the traditional file permissions to
|
||||||
|
read/execute the ``bro`` binary.
|
||||||
|
|
||||||
|
With BPF Devices
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Systems using Berkeley Packet Filter (BPF) (e.g. FreeBSD & Mac OS X)
|
||||||
|
can allow users with read access to a BPF device to capture packets from
|
||||||
|
it using libpcap.
|
||||||
|
|
||||||
|
* Example of manually changing BPF device permissions to allow users in
|
||||||
|
the ``admin`` group to capture packets:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo chgrp admin /dev/bpf*
|
||||||
|
sudo chmod g+r /dev/bpf*
|
||||||
|
|
||||||
|
* Example of configuring devfs to set permissions of BPF devices, adding
|
||||||
|
entries to ``/etc/devfs.conf`` to grant ``admin`` group permission to
|
||||||
|
capture packets:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo sh -c 'echo "own bpf root:admin" >> /etc/devfs.conf'
|
||||||
|
sudo sh -c 'echo "perm bpf 0640" >> /etc/devfs.conf'
|
||||||
|
sudo service devfs restart
|
||||||
|
|
||||||
|
.. note:: As of Mac OS X 10.6, the BPF device is on devfs, but the used version
|
||||||
|
of devfs isn't capable of setting the device permissions. The permissions
|
||||||
|
can be changed manually, but they will not survive a reboot.
|
||||||
|
|
||||||
|
Why isn't Bro producing the logs I expect? (A Note About Checksums)
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
Normally, Bro's event engine will discard packets which don't have valid
|
||||||
|
checksums. This can be a problem if one wants to analyze locally
|
||||||
|
generated/captured traffic on a system that offloads checksumming to the
|
||||||
|
network adapter. In that case, all transmitted/captured packets will have
|
||||||
|
bad checksums because they haven't yet been calculated by the NIC, thus
|
||||||
|
such packets will not undergo analysis defined in Bro policy scripts as they
|
||||||
|
normally would. Bad checksums in traces may also be a result of some packet
|
||||||
|
alteration tools.
|
||||||
|
|
||||||
|
Bro has two options to workaround such situations and ignore bad checksums:
|
||||||
|
|
||||||
|
1) The ``-C`` command line option to ``bro``.
|
||||||
|
2) An option called ``ignore_checksums`` that can be redefined at the
|
||||||
|
policy script layer (e.g. in your ``$PREFIX/share/bro/site/local.bro``):
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef ignore_checksums = T;
|
||||||
|
|
||||||
|
The other alternative is to disable checksum offloading for your
|
||||||
|
network adapter, but this is not always possible or desirable.
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
</div>
|
102
doc/geoip.rst
Normal file
102
doc/geoip.rst
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
|
||||||
|
===========
|
||||||
|
GeoLocation
|
||||||
|
===========
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
During the process of creating policy scripts the need may arise
|
||||||
|
to find the geographic location for an IP address. Bro has support
|
||||||
|
for the `GeoIP library <http://www.maxmind.com/app/c>`__ at the
|
||||||
|
policy script level beginning with release 1.3 to account for this
|
||||||
|
need.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
GeoIPLite Database Installation
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
A country database for GeoIPLite is included when you do the C API
|
||||||
|
install, but for Bro, we are using the city database which includes
|
||||||
|
cities and regions in addition to countries.
|
||||||
|
|
||||||
|
`Download <http://www.maxmind.com/app/geolitecity>`__ the geolitecity
|
||||||
|
binary database and follow the directions to install it.
|
||||||
|
|
||||||
|
FreeBSD Quick Install
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
pkg_add -r GeoIP
|
||||||
|
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
|
||||||
|
gunzip GeoLiteCity.dat.gz
|
||||||
|
mv GeoLiteCity.dat /usr/local/share/GeoIP/GeoIPCity.dat
|
||||||
|
|
||||||
|
# Set your environment correctly before running Bro's configure script
|
||||||
|
export CFLAGS=-I/usr/local/include
|
||||||
|
export LDFLAGS=-L/usr/local/lib
|
||||||
|
|
||||||
|
|
||||||
|
CentOS Quick Install
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
yum install GeoIP-devel
|
||||||
|
|
||||||
|
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
|
||||||
|
gunzip GeoLiteCity.dat.gz
|
||||||
|
mkdir -p /var/lib/GeoIP/
|
||||||
|
mv GeoLiteCity.dat /var/lib/GeoIP/GeoIPCity.dat
|
||||||
|
|
||||||
|
# Set your environment correctly before running Bro's configure script
|
||||||
|
export CFLAGS=-I/usr/local/include
|
||||||
|
export LDFLAGS=-L/usr/local/lib
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
There is a single built in function that provides the GeoIP
|
||||||
|
functionality:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function lookup_location(a:addr): geo_location
|
||||||
|
|
||||||
|
There is also the ``geo_location`` data structure that is returned
|
||||||
|
from the ``lookup_location`` function:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
type geo_location: record {
|
||||||
|
country_code: string;
|
||||||
|
region: string;
|
||||||
|
city: string;
|
||||||
|
latitude: double;
|
||||||
|
longitude: double;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
To write a line in a log file for every ftp connection from hosts in
|
||||||
|
Ohio, this is now very easy:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global ftp_location_log: file = open_log_file("ftp-location");
|
||||||
|
|
||||||
|
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
||||||
|
{
|
||||||
|
local client = c$id$orig_h;
|
||||||
|
local loc = lookup_location(client);
|
||||||
|
if (loc$region == "OH" && loc$country_code == "US")
|
||||||
|
{
|
||||||
|
print ftp_location_log, fmt("FTP Connection from:%s (%s,%s,%s)", client, loc$city, loc$region, loc$country_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
BIN
doc/images/deployment.png
Normal file
BIN
doc/images/deployment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
89
doc/index.rst
Normal file
89
doc/index.rst
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
.. Bro documentation master file
|
||||||
|
|
||||||
|
=================
|
||||||
|
Bro Documentation
|
||||||
|
=================
|
||||||
|
|
||||||
|
Guides
|
||||||
|
------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
INSTALL
|
||||||
|
quickstart
|
||||||
|
upgrade
|
||||||
|
faq
|
||||||
|
reporting-problems
|
||||||
|
|
||||||
|
Frameworks
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
notice
|
||||||
|
logging
|
||||||
|
cluster
|
||||||
|
signatures
|
||||||
|
|
||||||
|
How-Tos
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
geoip
|
||||||
|
|
||||||
|
Script Reference
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
scripts/packages
|
||||||
|
scripts/index
|
||||||
|
scripts/builtins
|
||||||
|
scripts/bifs
|
||||||
|
|
||||||
|
Other Bro Components
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The following are snapshots of documentation for components that come
|
||||||
|
with this version of Bro (|version|). Since they can also be used
|
||||||
|
independently, see the `download page
|
||||||
|
<http://bro-ids.org/download/index.html>`_ for documentation of any
|
||||||
|
current, independent component releases.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
BinPAC - A protocol parser generator <components/binpac/README>
|
||||||
|
Broccoli - The Bro Client Communication Library (README) <components/broccoli/README>
|
||||||
|
Broccoli - User Manual <components/broccoli/broccoli-manual>
|
||||||
|
Broccoli Python Bindings <components/broccoli-python/README>
|
||||||
|
Broccoli Ruby Bindings <components/broccoli-ruby/README>
|
||||||
|
BroControl - Interactive Bro management shell <components/broctl/README>
|
||||||
|
Bro-Aux - Small auxiliary tools for Bro <components/bro-aux/README>
|
||||||
|
BTest - A unit testing framework <components/btest/README>
|
||||||
|
Capstats - Command-line packet statistic tool <components/capstats/README>
|
||||||
|
PySubnetTree - Python module for CIDR lookups<components/pysubnettree/README>
|
||||||
|
trace-summary - Script for generating break-downs of network traffic <components/trace-summary/README>
|
||||||
|
|
||||||
|
The `Broccoli API Reference <broccoli-api/index.html>`_ may also be of
|
||||||
|
interest.
|
||||||
|
|
||||||
|
Other Indices and References
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
* :ref:`General Index <genindex>`
|
||||||
|
* `Notice Index <bro-noticeindex.html>`_
|
||||||
|
* :ref:`search`
|
||||||
|
|
||||||
|
Internal References
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
scripts/internal
|
375
doc/logging.rst
Normal file
375
doc/logging.rst
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
==========================
|
||||||
|
Customizing Bro's Logging
|
||||||
|
==========================
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
Bro comes with a flexible key-value based logging interface that
|
||||||
|
allows fine-grained control of what gets logged and how it is
|
||||||
|
logged. This document describes how logging can be customized and
|
||||||
|
extended.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
Terminology
|
||||||
|
===========
|
||||||
|
|
||||||
|
Bro's logging interface is built around three main abstractions:
|
||||||
|
|
||||||
|
Log streams
|
||||||
|
A stream corresponds to a single log. It defines the set of
|
||||||
|
fields that a log consists of with their names and fields.
|
||||||
|
Examples are the ``conn`` for recording connection summaries,
|
||||||
|
and the ``http`` stream for recording HTTP activity.
|
||||||
|
|
||||||
|
Filters
|
||||||
|
Each stream has a set of filters attached to it that determine
|
||||||
|
what information gets written out. By default, each stream has
|
||||||
|
one default filter that just logs everything directly to disk
|
||||||
|
with an automatically generated file name. However, further
|
||||||
|
filters can be added to record only a subset, split a stream
|
||||||
|
into different outputs, or to even duplicate the log to
|
||||||
|
multiple outputs. If all filters are removed from a stream,
|
||||||
|
all output is disabled.
|
||||||
|
|
||||||
|
Writers
|
||||||
|
A writer defines the actual output format for the information
|
||||||
|
being logged. At the moment, Bro comes with only one type of
|
||||||
|
writer, which produces tab separated ASCII files. In the
|
||||||
|
future we will add further writers, like for binary output and
|
||||||
|
direct logging into a database.
|
||||||
|
|
||||||
|
Basics
|
||||||
|
======
|
||||||
|
|
||||||
|
The data fields that a stream records are defined by a record type
|
||||||
|
specified when it is created. Let's look at the script generating Bro's
|
||||||
|
connection summaries as an example,
|
||||||
|
:doc:`scripts/base/protocols/conn/main`. It defines a record
|
||||||
|
:bro:type:`Conn::Info` that lists all the fields that go into
|
||||||
|
``conn.log``, each marked with a ``&log`` attribute indicating that it
|
||||||
|
is part of the information written out. To write a log record, the
|
||||||
|
script then passes an instance of :bro:type:`Conn::Info` to the logging
|
||||||
|
framework's :bro:id:`Log::write` function.
|
||||||
|
|
||||||
|
By default, each stream automatically gets a filter named ``default``
|
||||||
|
that generates the normal output by recording all record fields into a
|
||||||
|
single output file.
|
||||||
|
|
||||||
|
In the following, we summarize ways in which the logging can be
|
||||||
|
customized. We continue using the connection summaries as our example
|
||||||
|
to work with.
|
||||||
|
|
||||||
|
Filtering
|
||||||
|
---------
|
||||||
|
|
||||||
|
To create a new output file for an existing stream, you can add a
|
||||||
|
new filter. A filter can, e.g., restrict the set of fields being
|
||||||
|
logged:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
# Add a new filter to the Conn::LOG stream that logs only
|
||||||
|
# timestamp and originator address.
|
||||||
|
local filter: Log::Filter = [$name="orig-only", $path="origs", $include=set("ts", "id.orig_h")];
|
||||||
|
Log::add_filter(Conn::LOG, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Note the fields that are set for the filter:
|
||||||
|
|
||||||
|
``name``
|
||||||
|
A mandatory name for the filter that can later be used
|
||||||
|
to manipulate it further.
|
||||||
|
|
||||||
|
``path``
|
||||||
|
The filename for the output file, without any extension (which
|
||||||
|
may be automatically added by the writer). Default path values
|
||||||
|
are generated by taking the stream's ID and munging it slightly.
|
||||||
|
:bro:enum:`Conn::LOG` is converted into ``conn``,
|
||||||
|
:bro:enum:`PacketFilter::LOG` is converted into
|
||||||
|
``packet_filter``, and :bro:enum:`Notice::POLICY_LOG` is
|
||||||
|
converted into ``notice_policy``.
|
||||||
|
|
||||||
|
``include``
|
||||||
|
A set limiting the fields to the ones given. The names
|
||||||
|
correspond to those in the :bro:type:`Conn::Info` record, with
|
||||||
|
sub-records unrolled by concatenating fields (separated with
|
||||||
|
dots).
|
||||||
|
|
||||||
|
Using the code above, you will now get a new log file ``origs.log``
|
||||||
|
that looks like this::
|
||||||
|
|
||||||
|
#separator \x09
|
||||||
|
#path origs
|
||||||
|
#fields ts id.orig_h
|
||||||
|
#types time addr
|
||||||
|
1128727430.350788 141.42.64.125
|
||||||
|
1128727435.450898 141.42.64.125
|
||||||
|
|
||||||
|
If you want to make this the only log file for the stream, you can
|
||||||
|
remove the default filter (which, conveniently, has the name
|
||||||
|
``default``):
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
# Remove the filter called "default".
|
||||||
|
Log::remove_filter(Conn::LOG, "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
An alternate approach to "turning off" a log is to completely disable
|
||||||
|
the stream:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
Log::disable_stream(Conn::LOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
If you want to skip only some fields but keep the rest, there is a
|
||||||
|
corresponding ``exclude`` filter attribute that you can use instead of
|
||||||
|
``include`` to list only the ones you are not interested in.
|
||||||
|
|
||||||
|
A filter can also determine output paths *dynamically* based on the
|
||||||
|
record being logged. That allows, e.g., to record local and remote
|
||||||
|
connections into separate files. To do this, you define a function
|
||||||
|
that returns the desired path:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function split_log(id: Log::ID, path: string, rec: Conn::Info) : string
|
||||||
|
{
|
||||||
|
# Return "conn-local" if originator is a local IP, otherwise "conn-remote".
|
||||||
|
local lr = Site::is_local_addr(rec$id$orig_h) ? "local" : "remote";
|
||||||
|
return fmt("%s-%s", path, lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
local filter: Log::Filter = [$name="conn-split", $path_func=split_log, $include=set("ts", "id.orig_h")];
|
||||||
|
Log::add_filter(Conn::LOG, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Running this will now produce two files, ``local.log`` and
|
||||||
|
``remote.log``, with the corresponding entries. One could extend this
|
||||||
|
further for example to log information by subnets or even by IP
|
||||||
|
address. Be careful, however, as it is easy to create many files very
|
||||||
|
quickly ...
|
||||||
|
|
||||||
|
.. sidebar:: A More Generic Path Function
|
||||||
|
|
||||||
|
The ``split_log`` method has one draw-back: it can be used
|
||||||
|
only with the :bro:enum:`Conn::LOG` stream as the record type is hardcoded
|
||||||
|
into its argument list. However, Bro allows to do a more generic
|
||||||
|
variant:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function split_log(id: Log::ID, path: string, rec: record { id: conn_id; } ) : string
|
||||||
|
{
|
||||||
|
return Site::is_local_addr(rec$id$orig_h) ? "local" : "remote";
|
||||||
|
}
|
||||||
|
|
||||||
|
This function can be used with all log streams that have records
|
||||||
|
containing an ``id: conn_id`` field.
|
||||||
|
|
||||||
|
While so far we have seen how to customize the columns being logged,
|
||||||
|
you can also control which records are written out by providing a
|
||||||
|
predicate that will be called for each log record:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function http_only(rec: Conn::Info) : bool
|
||||||
|
{
|
||||||
|
# Record only connections with successfully analyzed HTTP traffic
|
||||||
|
return rec$service == "http";
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
local filter: Log::Filter = [$name="http-only", $path="conn-http", $pred=http_only];
|
||||||
|
Log::add_filter(Conn::LOG, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
This will result in a log file ``conn-http.log`` that contains only
|
||||||
|
traffic detected and analyzed as HTTP traffic.
|
||||||
|
|
||||||
|
Extending
|
||||||
|
---------
|
||||||
|
|
||||||
|
You can add further fields to a log stream by extending the record
|
||||||
|
type that defines its content. Let's say we want to add a boolean
|
||||||
|
field ``is_private`` to :bro:type:`Conn::Info` that indicates whether the
|
||||||
|
originator IP address is part of the :rfc:`1918` space:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
# Add a field to the connection log record.
|
||||||
|
redef record Conn::Info += {
|
||||||
|
## Indicate if the originator of the connection is part of the
|
||||||
|
## "private" address space defined in RFC1918.
|
||||||
|
is_private: bool &default=F &log;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Now we need to set the field. A connection's summary is generated at
|
||||||
|
the time its state is removed from memory. We can add another handler
|
||||||
|
at that time that sets our field correctly:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event connection_state_remove(c: connection)
|
||||||
|
{
|
||||||
|
if ( c$id$orig_h in Site::private_address_space )
|
||||||
|
c$conn$is_private = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
Now ``conn.log`` will show a new field ``is_private`` of type
|
||||||
|
``bool``.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- For extending logs this way, one needs a bit of knowledge about how
|
||||||
|
the script that creates the log stream is organizing its state
|
||||||
|
keeping. Most of the standard Bro scripts attach their log state to
|
||||||
|
the :bro:type:`connection` record where it can then be accessed, just
|
||||||
|
as the ``c$conn`` above. For example, the HTTP analysis adds a field
|
||||||
|
``http`` of type :bro:type:`HTTP::Info` to the :bro:type:`connection`
|
||||||
|
record. See the script reference for more information.
|
||||||
|
|
||||||
|
- When extending records as shown above, the new fields must always be
|
||||||
|
declared either with a ``&default`` value or as ``&optional``.
|
||||||
|
Furthermore, you need to add the ``&log`` attribute or otherwise the
|
||||||
|
field won't appear in the output.
|
||||||
|
|
||||||
|
Hooking into the Logging
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Sometimes it is helpful to do additional analysis of the information
|
||||||
|
being logged. For these cases, a stream can specify an event that will
|
||||||
|
be generated every time a log record is written to it. All of Bro's
|
||||||
|
default log streams define such an event. For example, the connection
|
||||||
|
log stream raises the event :bro:id:`Conn::log_conn`. You
|
||||||
|
could use that for example for flagging when a connection to a
|
||||||
|
specific destination exceeds a certain duration:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## Indicates that a connection remained established longer
|
||||||
|
## than 5 minutes.
|
||||||
|
Long_Conn_Found
|
||||||
|
};
|
||||||
|
|
||||||
|
event Conn::log_conn(rec: Conn::Info)
|
||||||
|
{
|
||||||
|
if ( rec$duration > 5mins )
|
||||||
|
NOTICE([$note=Long_Conn_Found,
|
||||||
|
$msg=fmt("unusually long conn to %s", rec$id$resp_h),
|
||||||
|
$id=rec$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Often, these events can be an alternative to post-processing Bro logs
|
||||||
|
externally with Perl scripts. Much of what such an external script
|
||||||
|
would do later offline, one may instead do directly inside of Bro in
|
||||||
|
real-time.
|
||||||
|
|
||||||
|
Rotation
|
||||||
|
--------
|
||||||
|
|
||||||
|
By default, no log rotation occurs, but it's globally controllable for all
|
||||||
|
filters by redefining the :bro:id:`Log::default_rotation_interval` option:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef Log::default_rotation_interval = 1 hr;
|
||||||
|
|
||||||
|
Or specifically for certain :bro:type:`Log::Filter` instances by setting
|
||||||
|
their ``interv`` field. Here's an example of changing just the
|
||||||
|
:bro:enum:`Conn::LOG` stream's default filter rotation.
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
local f = Log::get_filter(Conn::LOG, "default");
|
||||||
|
f$interv = 1 min;
|
||||||
|
Log::remove_filter(Conn::LOG, "default");
|
||||||
|
Log::add_filter(Conn::LOG, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASCII Writer Configuration
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The ASCII writer has a number of options for customizing the format of
|
||||||
|
its output, see :doc:`scripts/base/frameworks/logging/writers/ascii`.
|
||||||
|
|
||||||
|
Adding Streams
|
||||||
|
==============
|
||||||
|
|
||||||
|
It's easy to create a new log stream for custom scripts. Here's an
|
||||||
|
example for the ``Foo`` module:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
module Foo;
|
||||||
|
|
||||||
|
export {
|
||||||
|
# Create an ID for our new stream. By convention, this is
|
||||||
|
# called "LOG".
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
# Define the fields. By convention, the type is called "Info".
|
||||||
|
type Info: record {
|
||||||
|
ts: time &log;
|
||||||
|
id: conn_id &log;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Define a hook event. By convention, this is called
|
||||||
|
# "log_<stream>".
|
||||||
|
global log_foo: event(rec: Info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This event should be handled at a higher priority so that when
|
||||||
|
# users modify your stream later and they do it at priority 0,
|
||||||
|
# their code runs after this.
|
||||||
|
event bro_init() &priority=5
|
||||||
|
{
|
||||||
|
# Create the stream. This also adds a default filter automatically.
|
||||||
|
Log::create_stream(Foo::LOG, [$columns=Info, $ev=log_foo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
You can also add the state to the :bro:type:`connection` record to make
|
||||||
|
it easily accessible across event handlers:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef record connection += {
|
||||||
|
foo: Info &optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
Now you can use the :bro:id:`Log::write` method to output log records and
|
||||||
|
save the logged ``Foo::Info`` record into the connection record:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event connection_established(c: connection)
|
||||||
|
{
|
||||||
|
local rec: Foo::Info = [$ts=network_time(), $id=c$id];
|
||||||
|
c$foo = rec;
|
||||||
|
Log::write(Foo::LOG, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
See the existing scripts for how to work with such a new connection
|
||||||
|
field. A simple example is :doc:`scripts/base/protocols/syslog/main`.
|
||||||
|
|
||||||
|
When you are developing scripts that add data to the :bro:type:`connection`
|
||||||
|
record, care must be given to when and how long data is stored.
|
||||||
|
Normally data saved to the connection record will remain there for the
|
||||||
|
duration of the connection and from a practical perspective it's not
|
||||||
|
uncommon to need to delete that data before the end of the connection.
|
395
doc/notice.rst
Normal file
395
doc/notice.rst
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
|
||||||
|
Notice Framework
|
||||||
|
================
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
One of the easiest ways to customize Bro is writing a local notice
|
||||||
|
policy. Bro can detect a large number of potentially interesting
|
||||||
|
situations, and the notice policy tells which of them the user wants to be
|
||||||
|
acted upon in some manner. In particular, the notice policy can specify
|
||||||
|
actions to be taken, such as sending an email or compiling regular
|
||||||
|
alarm emails. This page gives an introduction into writing such a notice
|
||||||
|
policy.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
Let's start with a little bit of background on Bro's philosophy on reporting
|
||||||
|
things. Bro ships with a large number of policy scripts which perform a wide
|
||||||
|
variety of analyses. Most of these scripts monitor for activity which might be
|
||||||
|
of interest for the user. However, none of these scripts determines the
|
||||||
|
importance of what it finds itself. Instead, the scripts only flag situations
|
||||||
|
as *potentially* interesting, leaving it to the local configuration to define
|
||||||
|
which of them are in fact actionable. This decoupling of detection and
|
||||||
|
reporting allows Bro to address the different needs that sites have:
|
||||||
|
definitions of what constitutes an attack or even a compromise differ quite a
|
||||||
|
bit between environments, and activity deemed malicious at one site might be
|
||||||
|
fully acceptable at another.
|
||||||
|
|
||||||
|
Whenever one of Bro's analysis scripts sees something potentially
|
||||||
|
interesting it flags the situation by calling the :bro:see:`NOTICE`
|
||||||
|
function and giving it a single :bro:see:`Notice::Info` record. A Notice
|
||||||
|
has a :bro:see:`Notice::Type`, which reflects the kind of activity that
|
||||||
|
has been seen, and it is usually also augmented with further context
|
||||||
|
about the situation.
|
||||||
|
|
||||||
|
More information about raising notices can be found in the `Raising Notices`_
|
||||||
|
section.
|
||||||
|
|
||||||
|
Once a notice is raised, it can have any number of actions applied to it by
|
||||||
|
the :bro:see:`Notice::policy` set which is described in the `Notice Policy`_
|
||||||
|
section below. Such actions can be to send a mail to the configured
|
||||||
|
address(es) or to simply ignore the notice. Currently, the following actions
|
||||||
|
are defined:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 20 80
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Action
|
||||||
|
- Description
|
||||||
|
|
||||||
|
* - Notice::ACTION_LOG
|
||||||
|
- Write the notice to the :bro:see:`Notice::LOG` logging stream.
|
||||||
|
|
||||||
|
* - Notice::ACTION_ALARM
|
||||||
|
- Log into the :bro:see:`Notice::ALARM_LOG` stream which will rotate
|
||||||
|
hourly and email the contents to the email address or addresses
|
||||||
|
defined in the :bro:see:`Notice::mail_dest` variable.
|
||||||
|
|
||||||
|
* - Notice::ACTION_EMAIL
|
||||||
|
- Send the notice in an email to the email address or addresses given in
|
||||||
|
the :bro:see:`Notice::mail_dest` variable.
|
||||||
|
|
||||||
|
* - Notice::ACTION_PAGE
|
||||||
|
- Send an email to the email address or addresses given in the
|
||||||
|
:bro:see:`Notice::mail_page_dest` variable.
|
||||||
|
|
||||||
|
* - Notice::ACTION_NO_SUPPRESS
|
||||||
|
- This action will disable the built in notice suppression for the
|
||||||
|
notice. Keep in mind that this action will need to be applied to
|
||||||
|
every notice that shouldn't be suppressed including each of the future
|
||||||
|
notices that would have normally been suppressed.
|
||||||
|
|
||||||
|
How these notice actions are applied to notices is discussed in the
|
||||||
|
`Notice Policy`_ and `Notice Policy Shortcuts`_ sections.
|
||||||
|
|
||||||
|
Processing Notices
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Notice Policy
|
||||||
|
*************
|
||||||
|
|
||||||
|
The predefined set :bro:see:`Notice::policy` provides the mechanism for
|
||||||
|
applying actions and other behavior modifications to notices. Each entry
|
||||||
|
of :bro:see:`Notice::policy` is a record of the type
|
||||||
|
:bro:see:`Notice::PolicyItem` which defines a condition to be matched
|
||||||
|
against all raised notices and one or more of a variety of behavior
|
||||||
|
modifiers. The notice policy is defined by adding any number of
|
||||||
|
:bro:see:`Notice::PolicyItem` records to the :bro:see:`Notice::policy`
|
||||||
|
set.
|
||||||
|
|
||||||
|
Here's a simple example which tells Bro to send an email for all notices of
|
||||||
|
type :bro:see:`SSH::Login` if the server is 10.0.0.1:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef Notice::policy += {
|
||||||
|
[$pred(n: Notice::Info) = {
|
||||||
|
return n$note == SSH::Login && n$id$resp_h == 10.0.0.1;
|
||||||
|
},
|
||||||
|
$action = Notice::ACTION_EMAIL]
|
||||||
|
};
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Keep in mind that the semantics of the SSH::Login notice are
|
||||||
|
such that it is only raised when Bro heuristically detects a successful
|
||||||
|
login. No apparently failed logins will raise this notice.
|
||||||
|
|
||||||
|
While the syntax might look a bit convoluted at first, it provides a lot of
|
||||||
|
flexibility due to having access to Bro's full programming language.
|
||||||
|
|
||||||
|
Predicate Field
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The :bro:see:`Notice::PolicyItem` record type has a field name ``$pred``
|
||||||
|
which defines the entry's condition in the form of a predicate written
|
||||||
|
as a Bro function. The function is passed the notice as a
|
||||||
|
:bro:see:`Notice::Info` record and it returns a boolean value indicating
|
||||||
|
if the entry is applicable to that particular notice.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The lack of a predicate in a ``Notice::PolicyItem`` is implicitly true
|
||||||
|
(``T``) since an implicit false (``F``) value would never be used.
|
||||||
|
|
||||||
|
Bro evaluates the predicates of each entry in the order defined by the
|
||||||
|
``$priority`` field in :bro:see:`Notice::PolicyItem` records. The valid
|
||||||
|
values are 0-10 with 10 being earliest evaluated. If ``$priority`` is
|
||||||
|
omitted, the default priority is 5.
|
||||||
|
|
||||||
|
Behavior Modification Fields
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There are a set of fields in the :bro:see:`Notice::PolicyItem` record type that
|
||||||
|
indicate ways that either the notice or notice processing should be modified
|
||||||
|
if the predicate field (``$pred``) evaluated to true (``T``). Those fields are
|
||||||
|
explained in more detail in the following table.
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 20 30 20
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Field
|
||||||
|
- Description
|
||||||
|
- Example
|
||||||
|
|
||||||
|
* - ``$action=<Notice::Action>``
|
||||||
|
- Each :bro:see:`Notice::PolicyItem` can have a single action
|
||||||
|
applied to the notice with this field.
|
||||||
|
- ``$action = Notice::ACTION_EMAIL``
|
||||||
|
|
||||||
|
* - ``$suppress_for=<interval>``
|
||||||
|
- This field makes it possible for a user to modify the behavior of the
|
||||||
|
notice framework's automated suppression of intrinsically similar
|
||||||
|
notices. More information about the notice framework's automated
|
||||||
|
suppression can be found in the `Automated Suppression`_ section of
|
||||||
|
this document.
|
||||||
|
- ``$suppress_for = 10mins``
|
||||||
|
|
||||||
|
* - ``$halt=<bool>``
|
||||||
|
- This field can be used for modification of the notice policy
|
||||||
|
evaluation. To stop processing of notice policy items before
|
||||||
|
evaluating all of them, set this field to ``T`` and make the ``$pred``
|
||||||
|
field return ``T``. :bro:see:`Notice::PolicyItem` records defined at
|
||||||
|
a higher priority as defined by the ``$priority`` field will still be
|
||||||
|
evaluated but those at a lower priority won't.
|
||||||
|
- ``$halt = T``
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef Notice::policy += {
|
||||||
|
[$pred(n: Notice::Info) = {
|
||||||
|
return n$note == SSH::Login && n$id$resp_h == 10.0.0.1;
|
||||||
|
},
|
||||||
|
$action = Notice::ACTION_EMAIL,
|
||||||
|
$priority=5]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Notice Policy Shortcuts
|
||||||
|
***********************
|
||||||
|
|
||||||
|
Although the notice framework provides a great deal of flexibility and
|
||||||
|
configurability there are many times that the full expressiveness isn't needed
|
||||||
|
and actually becomes a hindrance to achieving results. The framework provides
|
||||||
|
a default :bro:see:`Notice::policy` suite as a way of giving users the
|
||||||
|
shortcuts to easily apply many common actions to notices.
|
||||||
|
|
||||||
|
These are implemented as sets and tables indexed with a
|
||||||
|
:bro:see:`Notice::Type` enum value. The following table shows and describes
|
||||||
|
all of the variables available for shortcut configuration of the notice
|
||||||
|
framework.
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 32 40
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Variable name
|
||||||
|
- Description
|
||||||
|
|
||||||
|
* - :bro:see:`Notice::ignored_types`
|
||||||
|
- Adding a :bro:see:`Notice::Type` to this set results in the notice
|
||||||
|
being ignored. It won't have any other action applied to it, not even
|
||||||
|
:bro:see:`Notice::ACTION_LOG`.
|
||||||
|
|
||||||
|
* - :bro:see:`Notice::emailed_types`
|
||||||
|
- Adding a :bro:see:`Notice::Type` to this set results in
|
||||||
|
:bro:see:`Notice::ACTION_EMAIL` being applied to the notices of
|
||||||
|
that type.
|
||||||
|
|
||||||
|
* - :bro:see:`Notice::alarmed_types`
|
||||||
|
- Adding a :bro:see:`Notice::Type` to this set results in
|
||||||
|
:bro:see:`Notice::ACTION_ALARM` being applied to the notices of
|
||||||
|
that type.
|
||||||
|
|
||||||
|
* - :bro:see:`Notice::not_suppressed_types`
|
||||||
|
- Adding a :bro:see:`Notice::Type` to this set results in that notice
|
||||||
|
no longer undergoing the normal notice suppression that would
|
||||||
|
take place. Be careful when using this in production it could
|
||||||
|
result in a dramatic increase in the number of notices being
|
||||||
|
processed.
|
||||||
|
|
||||||
|
* - :bro:see:`Notice::type_suppression_intervals`
|
||||||
|
- This is a table indexed on :bro:see:`Notice::Type` and yielding an
|
||||||
|
interval. It can be used as an easy way to extend the default
|
||||||
|
suppression interval for an entire :bro:see:`Notice::Type`
|
||||||
|
without having to create a whole :bro:see:`Notice::policy` entry
|
||||||
|
and setting the ``$suppress_for`` field.
|
||||||
|
|
||||||
|
Raising Notices
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A script should raise a notice for any occurrence that a user may want
|
||||||
|
to be notified about or take action on. For example, whenever the base
|
||||||
|
SSH analysis scripts sees an SSH session where it is heuristically
|
||||||
|
guessed to be a successful login, it raises a Notice of the type
|
||||||
|
:bro:see:`SSH::Login`. The code in the base SSH analysis script looks
|
||||||
|
like this:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
NOTICE([$note=SSH::Login,
|
||||||
|
$msg="Heuristically detected successful SSH login.",
|
||||||
|
$conn=c]);
|
||||||
|
|
||||||
|
:bro:see:`NOTICE` is a normal function in the global namespace which
|
||||||
|
wraps a function within the ``Notice`` namespace. It takes a single
|
||||||
|
argument of the :bro:see:`Notice::Info` record type. The most common
|
||||||
|
fields used when raising notices are described in the following table:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 32 40
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Field name
|
||||||
|
- Description
|
||||||
|
|
||||||
|
* - ``$note``
|
||||||
|
- This field is required and is an enum value which represents the
|
||||||
|
notice type.
|
||||||
|
|
||||||
|
* - ``$msg``
|
||||||
|
- This is a human readable message which is meant to provide more
|
||||||
|
information about this particular instance of the notice type.
|
||||||
|
|
||||||
|
* - ``$sub``
|
||||||
|
- This is a sub-message meant for human readability but will
|
||||||
|
frequently also be used to contain data meant to be matched with the
|
||||||
|
``Notice::policy``.
|
||||||
|
|
||||||
|
* - ``$conn``
|
||||||
|
- If a connection record is available when the notice is being raised
|
||||||
|
and the notice represents some attribute of the connection, then the
|
||||||
|
connection record can be given here. Other fields such as ``$id`` and
|
||||||
|
``$src`` will automatically be populated from this value.
|
||||||
|
|
||||||
|
* - ``$id``
|
||||||
|
- If a conn_id record is available when the notice is being raised and
|
||||||
|
the notice represents some attribute of the connection, then the
|
||||||
|
connection can be given here. Other fields such as ``$src`` will
|
||||||
|
automatically be populated from this value.
|
||||||
|
|
||||||
|
* - ``$src``
|
||||||
|
- If the notice represents an attribute of a single host then it's
|
||||||
|
possible that only this field should be filled out to represent the
|
||||||
|
host that is being "noticed".
|
||||||
|
|
||||||
|
* - ``$n``
|
||||||
|
- This normally represents a number if the notice has to do with some
|
||||||
|
number. It's most frequently used for numeric tests in the
|
||||||
|
``Notice::policy`` for making policy decisions.
|
||||||
|
|
||||||
|
* - ``$identifier``
|
||||||
|
- This represents a unique identifier for this notice. This field is
|
||||||
|
described in more detail in the `Automated Suppression`_ section.
|
||||||
|
|
||||||
|
* - ``$suppress_for``
|
||||||
|
- This field can be set if there is a natural suppression interval for
|
||||||
|
the notice that may be different than the default value. The
|
||||||
|
value set to this field can also be modified by a user's
|
||||||
|
:bro:see:`Notice::policy` so the value is not set permanently
|
||||||
|
and unchangeably.
|
||||||
|
|
||||||
|
When writing Bro scripts which raise notices, some thought should be given to
|
||||||
|
what the notice represents and what data should be provided to give a consumer
|
||||||
|
of the notice the best information about the notice. If the notice is
|
||||||
|
representative of many connections and is an attribute of a host (e.g. a
|
||||||
|
scanning host) it probably makes most sense to fill out the ``$src`` field and
|
||||||
|
not give a connection or conn_id. If a notice is representative of a
|
||||||
|
connection attribute (e.g. an apparent SSH login) then it makes sense to fill
|
||||||
|
out either ``$conn`` or ``$id`` based on the data that is available when the
|
||||||
|
notice is raised. Using care when inserting data into a notice will make later
|
||||||
|
analysis easier when only the data to fully represent the occurrence that
|
||||||
|
raised the notice is available. If complete connection information is
|
||||||
|
available when an SSL server certificate is expiring, the logs will be very
|
||||||
|
confusing because the connection that the certificate was detected on is a
|
||||||
|
side topic to the fact that an expired certificate was detected. It's possible
|
||||||
|
in many cases that two or more separate notices may need to be generated. As
|
||||||
|
an example, one could be for the detection of the expired SSL certificate and
|
||||||
|
another could be for if the client decided to go ahead with the connection
|
||||||
|
neglecting the expired certificate.
|
||||||
|
|
||||||
|
Automated Suppression
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The notice framework supports suppression for notices if the author of the
|
||||||
|
script that is generating the notice has indicated to the notice framework how
|
||||||
|
to identify notices that are intrinsically the same. Identification of these
|
||||||
|
"intrinsically duplicate" notices is implemented with an optional field in
|
||||||
|
:bro:see:`Notice::Info` records named ``$identifier`` which is a simple string.
|
||||||
|
If the ``$identifier`` and ``$type`` fields are the same for two notices, the
|
||||||
|
notice framework actually considers them to be the same thing and can use that
|
||||||
|
information to suppress duplicates for a configurable period of time.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If the ``$identifier`` is left out of a notice, no notice suppression
|
||||||
|
takes place due to the framework's inability to identify duplicates. This
|
||||||
|
could be completely legitimate usage if no notices could ever be
|
||||||
|
considered to be duplicates.
|
||||||
|
|
||||||
|
The ``$identifier`` field is typically comprised of several pieces of
|
||||||
|
data related to the notice that when combined represent a unique
|
||||||
|
instance of that notice. Here is an example of the script
|
||||||
|
:doc:`scripts/policy/protocols/ssl/validate-certs` raising a notice
|
||||||
|
for session negotiations where the certificate or certificate chain did
|
||||||
|
not validate successfully against the available certificate authority
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
NOTICE([$note=SSL::Invalid_Server_Cert,
|
||||||
|
$msg=fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status),
|
||||||
|
$sub=c$ssl$subject,
|
||||||
|
$conn=c,
|
||||||
|
$identifier=cat(c$id$resp_h,c$id$resp_p,c$ssl$validation_status,c$ssl$cert_hash)]);
|
||||||
|
|
||||||
|
In the above example you can see that the ``$identifier`` field contains a
|
||||||
|
string that is built from the responder IP address and port, the validation
|
||||||
|
status message, and the MD5 sum of the server certificate. Those fields in
|
||||||
|
particular are chosen because different SSL certificates could be seen on any
|
||||||
|
port of a host, certificates could fail validation for different reasons, and
|
||||||
|
multiple server certificates could be used on that combination of IP address
|
||||||
|
and port with the ``server_name`` SSL extension (explaining the addition of
|
||||||
|
the MD5 sum of the certificate). The result is that if a certificate fails
|
||||||
|
validation and all four pieces of data match (IP address, port, validation
|
||||||
|
status, and certificate hash) that particular notice won't be raised again for
|
||||||
|
the default suppression period.
|
||||||
|
|
||||||
|
Setting the ``$identifier`` field is left to those raising notices because
|
||||||
|
it's assumed that the script author who is raising the notice understands the
|
||||||
|
full problem set and edge cases of the notice which may not be readily
|
||||||
|
apparent to users. If users don't want the suppression to take place or simply
|
||||||
|
want a different interval, they can always modify it with the
|
||||||
|
:bro:see:`Notice::policy`.
|
||||||
|
|
||||||
|
|
||||||
|
Extending Notice Framework
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Adding Custom Notice Actions
|
||||||
|
****************************
|
||||||
|
|
||||||
|
Extending Notice Emails
|
||||||
|
***********************
|
||||||
|
|
||||||
|
Cluster Considerations
|
||||||
|
----------------------
|
||||||
|
|
592
doc/quickstart.rst
Normal file
592
doc/quickstart.rst
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
.. _CMake: http://www.cmake.org
|
||||||
|
.. _SWIG: http://www.swig.org
|
||||||
|
.. _MacPorts: http://www.macports.org
|
||||||
|
.. _Fink: http://www.finkproject.org
|
||||||
|
.. _Homebrew: http://mxcl.github.com/homebrew
|
||||||
|
.. _bro downloads page: http://bro-ids.org/download/index.html
|
||||||
|
|
||||||
|
=================
|
||||||
|
Quick Start Guide
|
||||||
|
=================
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
The short story for getting Bro up and running in a simple configuration
|
||||||
|
for analysis of either live traffic from a network interface or a packet
|
||||||
|
capture trace file.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
Bro works on most modern, Unix-based systems and requires no custom
|
||||||
|
hardware. It can be downloaded in either pre-built binary package or
|
||||||
|
source code forms.
|
||||||
|
|
||||||
|
Pre-Built Binary Release Packages
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
See the `bro downloads page`_ for currently supported/targeted platforms.
|
||||||
|
|
||||||
|
* RPM
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo yum localinstall Bro-*.rpm
|
||||||
|
|
||||||
|
* DEB
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo gdebi Bro-*.deb
|
||||||
|
|
||||||
|
* MacOS Disk Image with Installer
|
||||||
|
|
||||||
|
Just open the ``Bro-*.dmg`` and then run the ``.pkg`` installer.
|
||||||
|
Everything installed by the package will go into ``/opt/bro``.
|
||||||
|
|
||||||
|
The primary install prefix for binary packages is ``/opt/bro``.
|
||||||
|
Non-MacOS packages that include BroControl also put variable/runtime
|
||||||
|
data (e.g. Bro logs) in ``/var/opt/bro``.
|
||||||
|
|
||||||
|
Building From Source
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Required Dependencies
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The following dependencies are required to build Bro:
|
||||||
|
|
||||||
|
* RPM/RedHat-based Linux:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel file-devel
|
||||||
|
|
||||||
|
* DEB/Debian-based Linux:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python-dev swig zlib1g-dev libmagic-dev
|
||||||
|
|
||||||
|
* FreeBSD
|
||||||
|
|
||||||
|
Most required dependencies should come with a minimal FreeBSD install
|
||||||
|
except for the following.
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo pkg_add -r bash cmake swig bison python
|
||||||
|
|
||||||
|
Note that ``bash`` needs to be in ``PATH``, which by default it is
|
||||||
|
not. The FreeBSD package installs the binary into
|
||||||
|
``/usr/local/bin``.
|
||||||
|
|
||||||
|
* Mac OS X
|
||||||
|
|
||||||
|
Snow Leopard (10.6) comes with all required dependencies except for CMake_.
|
||||||
|
|
||||||
|
Lion (10.7) comes with all required dependencies except for CMake_ and SWIG_.
|
||||||
|
|
||||||
|
Distributions of these dependencies can be obtained from the project websites
|
||||||
|
linked above, but they're also likely available from your preferred Mac OS X
|
||||||
|
package management system (e.g. MacPorts_, Fink_, or Homebrew_).
|
||||||
|
|
||||||
|
Note that the MacPorts ``swig`` package may not include any specific
|
||||||
|
language support so you may need to also install ``swig-ruby`` and
|
||||||
|
``swig-python``.
|
||||||
|
|
||||||
|
Optional Dependencies
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Bro can use libGeoIP for geo-locating IP addresses, and sendmail for
|
||||||
|
sending emails.
|
||||||
|
|
||||||
|
* RPM/RedHat-based Linux:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo yum install GeoIP-devel sendmail
|
||||||
|
|
||||||
|
* DEB/Debian-based Linux:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo apt-get install libgeoip-dev sendmail
|
||||||
|
|
||||||
|
* Ports-based FreeBSD
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo pkg_add -r GeoIP
|
||||||
|
|
||||||
|
sendmail is typically already available.
|
||||||
|
|
||||||
|
* Mac OS X
|
||||||
|
|
||||||
|
Vanilla OS X installations don't ship with libmagic or libGeoIP, but
|
||||||
|
if installed from your preferred package management system (e.g. MacPorts,
|
||||||
|
Fink, or Homebrew), they should be automatically detected and Bro will compile
|
||||||
|
against them.
|
||||||
|
|
||||||
|
Additional steps may be needed to :doc:`get the right GeoIP database <geoip>`
|
||||||
|
|
||||||
|
Compiling Bro Source Code
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Bro releases are bundled into source packages for convenience and
|
||||||
|
available from the `bro downloads page`_.
|
||||||
|
|
||||||
|
The latest Bro development versions are obtainable through git
|
||||||
|
repositories hosted at `git.bro-ids.org <http://git.bro-ids.org>`_. See
|
||||||
|
our `git development documentation
|
||||||
|
<http://bro-ids.org/development/process.html>`_ for comprehensive
|
||||||
|
information on Bro's use of git revision control, but the short story
|
||||||
|
for downloading the full source code experience for Bro via git is:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
git clone --recursive git://git.bro-ids.org/bro
|
||||||
|
|
||||||
|
.. note:: If you choose to clone the ``bro`` repository non-recursively for
|
||||||
|
a "minimal Bro experience", be aware that compiling it depends on
|
||||||
|
BinPAC, which has its own ``binpac`` repository. Either install it
|
||||||
|
first or initialize/update the cloned ``bro`` repository's
|
||||||
|
``aux/binpac`` submodule.
|
||||||
|
|
||||||
|
See the ``INSTALL`` file included with the source code for more information
|
||||||
|
on compiling, but this is the typical way to build and install from source
|
||||||
|
(of course, changing the value of the ``--prefix`` option to point to the
|
||||||
|
desired root install path):
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
./configure --prefix=/desired/install/path
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
The default installation prefix is ``/usr/local/bro``, which would typically
|
||||||
|
require root privileges when doing the ``make install``.
|
||||||
|
|
||||||
|
Configure the Run-Time Environment
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Just remember that you may need to adjust your ``PATH`` environment variable
|
||||||
|
according to the platform/shell/package you're using. For example:
|
||||||
|
|
||||||
|
Bourne-Shell Syntax:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
export PATH=/usr/local/bro/bin:$PATH
|
||||||
|
|
||||||
|
C-Shell Syntax:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
setenv PATH /usr/local/bro/bin:$PATH
|
||||||
|
|
||||||
|
Or substitute ``/opt/bro/bin`` instead if you installed from a binary package.
|
||||||
|
|
||||||
|
Using BroControl
|
||||||
|
================
|
||||||
|
|
||||||
|
BroControl is an interactive shell for easily operating/managing Bro
|
||||||
|
installations on a single system or even across multiple systems in a
|
||||||
|
traffic-monitoring cluster.
|
||||||
|
|
||||||
|
.. note:: Below, ``$PREFIX`` is used to reference the Bro installation
|
||||||
|
root directory.
|
||||||
|
|
||||||
|
A Minimal Starting Configuration
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
These are the basic configuration changes to make for a minimal BroControl installation
|
||||||
|
that will manage a single Bro instance on the ``localhost``:
|
||||||
|
|
||||||
|
1) In ``$PREFIX/etc/node.cfg``, set the right interface to monitor.
|
||||||
|
2) In ``$PREFIX/etc/networks.cfg``, comment out the default settings and add
|
||||||
|
the networks that Bro will consider local to the monitored environment.
|
||||||
|
3) In ``$PREFIX/etc/broctl.cfg``, change the ``MailTo`` email address to a
|
||||||
|
desired recipient and the ``LogRotationInterval`` to a desired log
|
||||||
|
archival frequency.
|
||||||
|
|
||||||
|
Now start the BroControl shell like:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
broctl
|
||||||
|
|
||||||
|
Since this is the first-time use of the shell, perform an initial installation
|
||||||
|
of the BroControl configuration:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[BroControl] > install
|
||||||
|
|
||||||
|
Then start up a Bro instance:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[BroControl] > start
|
||||||
|
|
||||||
|
If there are errors while trying to start the Bro instance, you can
|
||||||
|
can view the details with the ``diag`` command. If started successfully,
|
||||||
|
the Bro instance will begin analyzing traffic according to a default
|
||||||
|
policy and output the results in ``$PREFIX/logs``.
|
||||||
|
|
||||||
|
.. note:: The user starting BroControl needs permission to capture
|
||||||
|
network traffic. If you are not root, you may need to grant further
|
||||||
|
privileges to the account you're using; see the :doc:`FAQ <faq>`.
|
||||||
|
Also, if it looks like Bro is not seeing any traffic, check out
|
||||||
|
the FAQ entry on checksum offloading.
|
||||||
|
|
||||||
|
You can leave it running for now, but to stop this Bro instance you would do:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[BroControl] > stop
|
||||||
|
|
||||||
|
We also recommend to insert the following entry into `crontab`::
|
||||||
|
|
||||||
|
0-59/5 * * * * $PREFIX/bin/broctl cron
|
||||||
|
|
||||||
|
This will perform a number of regular housekeeping tasks, including
|
||||||
|
verifying that the process is still running (and restarting if not in
|
||||||
|
case of any abnormal termination).
|
||||||
|
|
||||||
|
Browsing Log Files
|
||||||
|
------------------
|
||||||
|
|
||||||
|
By default, logs are written out in human-readable (ASCII) format and
|
||||||
|
data is organized into columns (tab-delimited). Logs that are part of
|
||||||
|
the current rotation interval are accumulated in
|
||||||
|
``$PREFIX/logs/current/`` (if Bro is not running, the directory will
|
||||||
|
be empty). For example, the ``http.log`` contains the results of Bro
|
||||||
|
HTTP protocol analysis. Here are the first few columns of
|
||||||
|
``http.log``::
|
||||||
|
|
||||||
|
# ts uid orig_h orig_p resp_h resp_p
|
||||||
|
1311627961.8 HSH4uV8KVJg 192.168.1.100 52303 192.150.187.43 80
|
||||||
|
|
||||||
|
Logs that deal with analysis of a network protocol will often start like this:
|
||||||
|
a timestamp, a unique connection identifier (UID), and a connection 4-tuple
|
||||||
|
(originator host/port and responder host/port). The UID can be used to
|
||||||
|
identify all logged activity (possibly across multiple log files) associated
|
||||||
|
with a given connection 4-tuple over its lifetime.
|
||||||
|
|
||||||
|
The remaining columns of protocol-specific logs then detail the
|
||||||
|
protocol-dependent activity that's occurring. E.g. ``http.log``'s next few
|
||||||
|
columns (shortened for brevity) show a request to the root of Bro website::
|
||||||
|
|
||||||
|
# method host uri referrer user_agent
|
||||||
|
GET bro-ids.org / - <...>Chrome/12.0.742.122<...>
|
||||||
|
|
||||||
|
Some logs are worth explicit mention:
|
||||||
|
|
||||||
|
``weird.log``
|
||||||
|
Contains unusual/exceptional activity that can indicate
|
||||||
|
malformed connections, traffic that doesn't conform to a particular
|
||||||
|
protocol, malfunctioning/misconfigured hardware, or even an attacker
|
||||||
|
attempting to avoid/confuse a sensor. Without context, it's hard to
|
||||||
|
judge whether this category of activity is interesting and so that is
|
||||||
|
left up to the user to configure.
|
||||||
|
|
||||||
|
``notice.log``
|
||||||
|
Identifies specific activity that Bro recognizes as
|
||||||
|
potentially interesting, odd, or bad. In Bro-speak, such
|
||||||
|
activity is called a "notice".
|
||||||
|
|
||||||
|
|
||||||
|
By default, ``BroControl`` regularly takes all the logs from
|
||||||
|
``$PREFIX/logs/current`` and archives/compresses them to a directory
|
||||||
|
named by date, e.g. ``$PREFIX/logs/2011-10-06``. The frequency at
|
||||||
|
which this is done can be configured via the ``LogRotationInterval``
|
||||||
|
option in ``$PREFIX/etc/broctl.cfg``.
|
||||||
|
|
||||||
|
Deployment Customization
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The goal of most Bro *deployments* may be to send email alarms when a network
|
||||||
|
event requires human intervention/investigation, but sometimes that conflicts
|
||||||
|
with Bro's goal as a *distribution* to remain policy and site neutral -- the
|
||||||
|
events on one network may be less noteworthy than the same events on another.
|
||||||
|
As a result, deploying Bro can be an iterative process of
|
||||||
|
updating its policy to take different actions for events that are noticed, and
|
||||||
|
using its scripting language to programmatically extend traffic analysis
|
||||||
|
in a precise way.
|
||||||
|
|
||||||
|
One of the first steps to take in customizing Bro might be to get familiar
|
||||||
|
with the notices it can generate by default and either tone down or escalate
|
||||||
|
the action that's taken when specific ones occur.
|
||||||
|
|
||||||
|
Let's say that we've been looking at the ``notice.log`` for a bit and see two
|
||||||
|
changes we want to make:
|
||||||
|
|
||||||
|
1) ``SSL::Invalid_Server_Cert`` (found in the ``note`` column) is one type of
|
||||||
|
notice that means an SSL connection was established and the server's
|
||||||
|
certificate couldn't be validated using Bro's default trust roots, but
|
||||||
|
we want to ignore it.
|
||||||
|
2) ``SSH::Login`` is a notice type that is triggered when an SSH connection
|
||||||
|
attempt looks like it may have been successful, and we want email when
|
||||||
|
that happens, but only for certain servers.
|
||||||
|
|
||||||
|
So we've defined *what* we want to do, but need to know *where* to do it.
|
||||||
|
The answer is to use a script written in the Bro programming language, so
|
||||||
|
let's do a quick intro to Bro scripting.
|
||||||
|
|
||||||
|
Bro Scripts
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Bro ships with many pre-written scripts that are highly customizable
|
||||||
|
to support traffic analysis for your specific environment. By
|
||||||
|
default, these will be installed into ``$PREFIX/share/bro`` and can be
|
||||||
|
identified by the use of a ``.bro`` file name extension. These files
|
||||||
|
should **never** be edited directly as changes will be lost when
|
||||||
|
upgrading to newer versions of Bro. The exception to this rule is the
|
||||||
|
directory ``$PREFIX/share/bro/site`` where local site-specific files
|
||||||
|
can be put without fear of being clobbered later. The other main
|
||||||
|
script directories under ``$PREFIX/share/bro`` are ``base`` and
|
||||||
|
``policy``. By default, Bro automatically loads all scripts under
|
||||||
|
``base`` (unless the ``-b`` command line option is supplied), which
|
||||||
|
deal either with collecting basic/useful state about network
|
||||||
|
activities or providing frameworks/utilities that extend Bro's
|
||||||
|
functionality without any performance cost. Scripts under the
|
||||||
|
``policy`` directory may be more situational or costly, and so users
|
||||||
|
must explicitly choose if they want to load them.
|
||||||
|
|
||||||
|
The main entry point for the default analysis configuration of a standalone
|
||||||
|
Bro instance managed by BroControl is the ``$PREFIX/share/bro/site/local.bro``
|
||||||
|
script. So we'll be adding to that in the following sections, but first
|
||||||
|
we have to figure out what to add.
|
||||||
|
|
||||||
|
Redefining Script Option Variables
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Many simple customizations just require you to redefine a variable
|
||||||
|
from a standard Bro script with your own value, using Bro's ``redef``
|
||||||
|
operator.
|
||||||
|
|
||||||
|
The typical way a standard Bro script advertises tweak-able options to users
|
||||||
|
is by defining variables with the ``&redef`` attribute and ``const`` qualifier.
|
||||||
|
A redefineable constant might seem strange, but what that really means is that
|
||||||
|
the variable's value may not change at run-time, but whose initial value can be
|
||||||
|
modified via the ``redef`` operator at parse-time.
|
||||||
|
|
||||||
|
So let's continue on our path to modify the behavior for the two SSL
|
||||||
|
and SSH notices. Looking at :doc:`scripts/base/frameworks/notice/main`,
|
||||||
|
we see that it advertises:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
module Notice;
|
||||||
|
|
||||||
|
export {
|
||||||
|
...
|
||||||
|
## Ignored notice types.
|
||||||
|
const ignored_types: set[Notice::Type] = {} &redef;
|
||||||
|
}
|
||||||
|
|
||||||
|
That's exactly what we want to do for the SSL notice. So add to ``local.bro``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
redef Notice::ignored_types += { SSL::Invalid_Server_Cert };
|
||||||
|
|
||||||
|
.. note:: The ``Notice`` namespace scoping is necessary here because the
|
||||||
|
variable was declared and exported inside the ``Notice`` module, but is
|
||||||
|
being referenced from outside of it. Variables declared and exported
|
||||||
|
inside a module do not have to be scoped if referring to them while still
|
||||||
|
inside the module.
|
||||||
|
|
||||||
|
Then go into the BroControl shell to check whether the configuration change
|
||||||
|
is valid before installing it and then restarting the Bro instance:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[BroControl] > check
|
||||||
|
bro is ok.
|
||||||
|
[BroControl] > install
|
||||||
|
removing old policies in /usr/local/bro/spool/policy/site ... done.
|
||||||
|
removing old policies in /usr/local/bro/spool/policy/auto ... done.
|
||||||
|
creating policy directories ... done.
|
||||||
|
installing site policies ... done.
|
||||||
|
generating standalone-layout.bro ... done.
|
||||||
|
generating local-networks.bro ... done.
|
||||||
|
generating broctl-config.bro ... done.
|
||||||
|
updating nodes ... done.
|
||||||
|
[BroControl] > restart
|
||||||
|
stopping bro ...
|
||||||
|
starting bro ...
|
||||||
|
|
||||||
|
Now that the SSL notice is ignored, let's look at how to send an email on
|
||||||
|
the SSH notice. The notice framework has a similar option called
|
||||||
|
``emailed_types``, but that can't differentiate between SSH servers and we
|
||||||
|
only want email for logins to certain ones. Then we come to the ``PolicyItem``
|
||||||
|
record and ``policy`` set and realize that those are actually what get used
|
||||||
|
to implement the simple functionality of ``ignored_types`` and
|
||||||
|
``emailed_types``, but it's extensible such that the condition and action taken
|
||||||
|
on notices can be user-defined.
|
||||||
|
|
||||||
|
In ``local.bro``, let's add a new ``PolicyItem`` record to the ``policy`` set
|
||||||
|
that only takes the email action for SSH logins to a defined set of servers:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
const watched_servers: set[addr] = {
|
||||||
|
192.168.1.100,
|
||||||
|
192.168.1.101,
|
||||||
|
192.168.1.102,
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
redef Notice::policy += {
|
||||||
|
[$action = Notice::ACTION_EMAIL,
|
||||||
|
$pred(n: Notice::Info) =
|
||||||
|
{
|
||||||
|
return n$note == SSH::Login && n$id$resp_h in watched_servers;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
You'll just have to trust the syntax for now, but what we've done is
|
||||||
|
first declare our own variable to hold a set of watched addresses,
|
||||||
|
``watched_servers``; then added a record to the policy that will generate
|
||||||
|
an email on the condition that the predicate function evaluates to true, which
|
||||||
|
is whenever the notice type is an SSH login and the responding host stored
|
||||||
|
inside the ``Info`` record's connection field is in the set of watched servers.
|
||||||
|
|
||||||
|
.. note:: record field member access is done with the '$' character
|
||||||
|
instead of a '.' as might be expected from other languages, in
|
||||||
|
order to avoid ambiguity with the builtin address type's use of '.'
|
||||||
|
in IPv4 dotted decimal representations.
|
||||||
|
|
||||||
|
Remember, to finalize that configuration change perform the ``check``,
|
||||||
|
``install``, ``restart`` commands in that order inside the BroControl shell.
|
||||||
|
|
||||||
|
Next Steps
|
||||||
|
----------
|
||||||
|
|
||||||
|
By this point, we've learned how to set up the most basic Bro instance and
|
||||||
|
tweak the most basic options. Here's some suggestions on what to explore next:
|
||||||
|
|
||||||
|
* We only looked at how to change options declared in the notice framework,
|
||||||
|
there's many more options to look at in other script packages.
|
||||||
|
* Look at the scripts in ``$PREFIX/share/bro/policy`` for further ones
|
||||||
|
you may want to load.
|
||||||
|
* Reading the code of scripts that ship with Bro is also a great way to gain
|
||||||
|
understanding of the language and how you can start writing your own custom
|
||||||
|
analysis.
|
||||||
|
* Review the :doc:`FAQ <faq>`.
|
||||||
|
* Continue reading below for another mini-tutorial on using Bro as a standalone
|
||||||
|
command-line utility.
|
||||||
|
|
||||||
|
Bro, the Command-Line Utility
|
||||||
|
=============================
|
||||||
|
|
||||||
|
If you prefer not to use BroControl (e.g. don't need its automation and
|
||||||
|
management features), here's how to directly control Bro for your analysis
|
||||||
|
activities.
|
||||||
|
|
||||||
|
Monitoring Live Traffic
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Analyzing live traffic from an interface is simple:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -i en0 <list of scripts to load>
|
||||||
|
|
||||||
|
``en0`` can be replaced by the interface of your choice and for the list of
|
||||||
|
scripts, you can just use "all" for now to perform all the default analysis
|
||||||
|
that's available.
|
||||||
|
|
||||||
|
Bro will output log files into the working directory.
|
||||||
|
|
||||||
|
.. note:: The :doc:`FAQ <faq>` entries about
|
||||||
|
capturing as an unprivileged user and checksum offloading are particularly
|
||||||
|
relevant at this point.
|
||||||
|
|
||||||
|
To use the site-specific ``local.bro`` script, just add it to the
|
||||||
|
command-line:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -i en0 local
|
||||||
|
|
||||||
|
This will cause Bro to print a warning about lacking the
|
||||||
|
``Site::local_nets`` variable being configured. You can supply this
|
||||||
|
information at the command line like this (supply your "local" subnets
|
||||||
|
in place of the example subnets):
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }"
|
||||||
|
|
||||||
|
|
||||||
|
Reading Packet Capture (pcap) Files
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Capturing packets from an interface and writing them to a file can be done
|
||||||
|
like this:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
sudo tcpdump -i en0 -s 0 -w mypackets.trace
|
||||||
|
|
||||||
|
Where ``en0`` can be replaced by the correct interface for your system as
|
||||||
|
shown by e.g. ``ifconfig``. (The ``-s 0`` argument tells it to capture
|
||||||
|
whole packets; in cases where it's not supported use ``-s 65535`` instead).
|
||||||
|
|
||||||
|
After a while of capturing traffic, kill the ``tcpdump`` (with ctrl-c),
|
||||||
|
and tell Bro to perform all the default analysis on the capture which primarily includes :
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -r mypackets.trace
|
||||||
|
|
||||||
|
Bro will output log files into the working directory.
|
||||||
|
|
||||||
|
If you are interested in more detection, you can again load the ``local``
|
||||||
|
script that we include as a suggested configuration:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -r mypackets.trace local
|
||||||
|
|
||||||
|
|
||||||
|
Telling Bro Which Scripts to Load
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
A command-line invocation of Bro typically looks like:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro <options> <policies...>
|
||||||
|
|
||||||
|
Where the last arguments are the specific policy scripts that this Bro
|
||||||
|
instance will load. These arguments don't have to include the ``.bro``
|
||||||
|
file extension, and if the corresponding script resides under the default
|
||||||
|
installation path, ``$PREFIX/share/bro``, then it requires no path
|
||||||
|
qualification. Further, a directory of scripts can be specified as
|
||||||
|
an argument to be loaded as a "package" if it contains a ``__load__.bro``
|
||||||
|
script that defines the scripts that are part of the package.
|
||||||
|
|
||||||
|
This example does all of the base analysis (primarily protocol
|
||||||
|
logging) and adds SSL certificate validation.
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
bro -r mypackets.trace protocols/ssl/validate-certs
|
||||||
|
|
||||||
|
You might notice that a script you load from the command line uses the
|
||||||
|
``@load`` directive in the Bro language to declare dependence on other scripts.
|
||||||
|
This directive is similar to the ``#include`` of C/C++, except the semantics
|
||||||
|
are "load this script if it hasn't already been loaded".
|
||||||
|
|
||||||
|
.. note:: If one wants Bro to be able to load scripts that live outside the
|
||||||
|
default directories in Bro's installation root, the ``BROPATH`` environment
|
||||||
|
variable will need to be extended to include all the directories that need
|
||||||
|
to be searched for scripts. See the default search path by doing
|
||||||
|
``bro --help``.
|
||||||
|
|
194
doc/reporting-problems.rst
Normal file
194
doc/reporting-problems.rst
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
|
||||||
|
Reporting Problems
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
Here we summarize some steps to follow when you see Bro doing
|
||||||
|
something it shouldn't. To provide help, it is often crucial for
|
||||||
|
us to have a way of reliably reproducing the effect you're seeing.
|
||||||
|
Unfortunately, reproducing problems can be rather tricky with Bro
|
||||||
|
because more often than not, they occur only in either very rare
|
||||||
|
situations or only after Bro has been running for some time. In
|
||||||
|
particular, getting a small trace showing a specific effect can be
|
||||||
|
a real problem. In the following, we'll summarize some strategies
|
||||||
|
to this end.
|
||||||
|
|
||||||
|
Reporting Problems
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Generally, when you encounter a problem with Bro, the best thing to do
|
||||||
|
is opening a new ticket in `Bro's issue tracker
|
||||||
|
<http://tracker.bro-ids.org/>`__ and include information on how to
|
||||||
|
reproduce the issue. Ideally, your ticket should come with the
|
||||||
|
following:
|
||||||
|
|
||||||
|
* The Bro version you're using (if working directly from the git
|
||||||
|
repository, the branch and revision number.)
|
||||||
|
|
||||||
|
* The output you're seeing along with a description of what you'd expect
|
||||||
|
Bro to do instead.
|
||||||
|
|
||||||
|
* A *small* trace in `libpcap format <http://www.tcpdump.org>`__
|
||||||
|
demonstrating the effect (assuming the problem doesn't happen right
|
||||||
|
at startup already).
|
||||||
|
|
||||||
|
* The exact command-line you're using to run Bro with that trace. If
|
||||||
|
you can, please try to run the Bro binary directly from the command
|
||||||
|
line rather than using BroControl.
|
||||||
|
|
||||||
|
* Any non-standard scripts you're using (but please only those really
|
||||||
|
necessary; just a small code snippet triggering the problem would
|
||||||
|
be perfect).
|
||||||
|
|
||||||
|
* If you encounter a crash, information from the core dump, such as
|
||||||
|
the stack backtrace, can be very helpful. See below for more on
|
||||||
|
this.
|
||||||
|
|
||||||
|
|
||||||
|
How Do I Get a Trace File?
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
As Bro is usually running live, coming up with a small trace file that
|
||||||
|
reproduces a problem can turn out to be quite a challenge. Often it
|
||||||
|
works best to start with a large trace that triggers the problem,
|
||||||
|
and then successively thin it out as much as possible.
|
||||||
|
|
||||||
|
To get to the initial large trace, here are a few things you can try:
|
||||||
|
|
||||||
|
* Capture a trace with `tcpdump <http://www.tcpdump.org/>`__, either
|
||||||
|
on the same interface Bro is running on, or on another host where
|
||||||
|
you can generate traffic of the kind likely triggering the problem
|
||||||
|
(e.g., if you're seeing problems with the HTTP analyzer, record some
|
||||||
|
of your Web browsing on your desktop.) When using tcpdump, don't
|
||||||
|
forget to record *complete* packets (``tcpdump -s 0 ...``). You can
|
||||||
|
reduce the amount of traffic captured by using a suitable BPF filter
|
||||||
|
(e.g., for HTTP only, try ``port 80``).
|
||||||
|
|
||||||
|
* Bro's command-line option ``-w <trace>`` records all packets it
|
||||||
|
processes into the given file. You can then later run Bro
|
||||||
|
offline on this trace and it will process the packets in the same
|
||||||
|
way as it did live. This is particularly helpful with problems that
|
||||||
|
only occur after Bro has already been running for some time. For
|
||||||
|
example, sometimes a crash may be triggered by a particular kind of
|
||||||
|
traffic only occurring rarely. Running Bro live with ``-w`` and
|
||||||
|
then, after the crash, offline on the recorded trace might, with a
|
||||||
|
little bit of luck, reproduce the problem reliably. However, be
|
||||||
|
careful with ``-w``: it can result in huge trace files, quickly
|
||||||
|
filling up your disk. (One way to mitigate the space issues is to
|
||||||
|
periodically delete the trace file by configuring
|
||||||
|
``rotate-logs.bro`` accordingly. BroControl does that for you if you
|
||||||
|
set its ``SaveTraces`` option.)
|
||||||
|
|
||||||
|
* Finally, you can try running Bro on a publically available trace
|
||||||
|
file, such as `anonymized FTP traffic <http://www-nrg.ee.lbl.gov
|
||||||
|
/anonymized-traces.html>`__, `headers-only enterprise traffic
|
||||||
|
<http://www.icir.org/enterprise-tracing/Overview.html>`__, or
|
||||||
|
`Defcon traffic <http://cctf.shmoo.com/>`__. Some of these
|
||||||
|
particularly stress certain components of Bro (e.g., the Defcon
|
||||||
|
traces contain tons of scans).
|
||||||
|
|
||||||
|
Once you have a trace that demonstrates the effect, you will often
|
||||||
|
notice that it's pretty big, in particular if recorded from the link
|
||||||
|
you're monitoring. Therefore, the next step is to shrink its size as
|
||||||
|
much as possible. Here are a few things you can try to this end:
|
||||||
|
|
||||||
|
* Very often, a single connection is able to demonstrate the problem.
|
||||||
|
If you can identify which one it is (e.g., from one of Bro's
|
||||||
|
``*.log`` files) you can extract the connection's packets from the
|
||||||
|
trace using tcpdump by filtering for the corresponding 4-tuple of
|
||||||
|
addresses and ports:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
> tcpdump -r large.trace -w small.trace host <ip1> and port <port1> and host <ip2> and port <port2>
|
||||||
|
|
||||||
|
* If you can't reduce the problem to a connection, try to identify
|
||||||
|
either a host pair or a single host triggering it, and filter down
|
||||||
|
the trace accordingly.
|
||||||
|
|
||||||
|
* You can try to extract a smaller time slice from the trace using
|
||||||
|
`TCPslice <http://www.tcpdump.org/related.html>`__. For example, to
|
||||||
|
extract the first 100 seconds from the trace:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
# Test comment
|
||||||
|
> tcpslice +100 <in >out
|
||||||
|
|
||||||
|
Alternatively, tcpdump extracts the first ``n`` packets with its
|
||||||
|
option ``-c <n>``.
|
||||||
|
|
||||||
|
|
||||||
|
Getting More Information After a Crash
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
If Bro crashes, a *core dump* can be very helpful to nail down the
|
||||||
|
problem. Examining a core is not for the faint of heart but can reveal
|
||||||
|
extremely useful information.
|
||||||
|
|
||||||
|
First, you should configure Bro with the option ``--enable-debug`` and
|
||||||
|
recompile; this will disable all compiler optimizations and thus make
|
||||||
|
the core dump more useful (don't expect great performance with this
|
||||||
|
version though; compiling Bro without optimization has a noticeable
|
||||||
|
impact on its CPU usage.). Then enable core dumps if you haven't
|
||||||
|
already (e.g., ``ulimit -c unlimited`` if you're using bash).
|
||||||
|
|
||||||
|
Once Bro has crashed, start gdb with the Bro binary and the file
|
||||||
|
containing the core dump. (Alternatively, you can also run Bro
|
||||||
|
directly inside gdb instead of working from a core file.) The first
|
||||||
|
helpful information to include with your tracker ticket is a stack
|
||||||
|
backtrace, which you get with gdb's ``bt`` command:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
> gdb bro core
|
||||||
|
[...]
|
||||||
|
> bt
|
||||||
|
|
||||||
|
|
||||||
|
If the crash occurs inside Bro's script interpreter, the next thing to
|
||||||
|
do is identifying the line of script code processed just before the
|
||||||
|
abnormal termination. Look for methods in the stack backtrace which
|
||||||
|
belong to any of the script interpreter's classes. Roughly speaking,
|
||||||
|
these are all classes with names ending in ``Expr``, ``Stmt``, or
|
||||||
|
``Val``. Then climb up the stack with ``up`` until you reach the first
|
||||||
|
of these methods. The object to which ``this`` is pointing will have a
|
||||||
|
``Location`` object, which in turn contains the file name and line
|
||||||
|
number of the corresponding piece of script code. Continuing the
|
||||||
|
example from above, here's how to get that information:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[in gdb]
|
||||||
|
> up
|
||||||
|
> ...
|
||||||
|
> up
|
||||||
|
> print this->location->filename
|
||||||
|
> print this->location->first_line
|
||||||
|
|
||||||
|
|
||||||
|
If the crash occurs while processing input packets but you cannot
|
||||||
|
directly tell which connection is responsible (and thus not extract
|
||||||
|
its packets from the trace as suggested above), try getting the
|
||||||
|
4-tuple of the connection currently being processed from the core dump
|
||||||
|
by again examining the stack backtrace, this time looking for methods
|
||||||
|
belonging to the ``Connection`` class. That class has members
|
||||||
|
``orig_addr``/``resp_addr`` and ``orig_port``/``resp_port`` storing
|
||||||
|
(pointers to) the IP addresses and ports respectively:
|
||||||
|
|
||||||
|
.. console::
|
||||||
|
|
||||||
|
[in gdb]
|
||||||
|
> up
|
||||||
|
> ...
|
||||||
|
> up
|
||||||
|
> printf "%08x:%04x %08x:%04x\n", *this->orig_addr, this->orig_port, *this->resp_addr, this->resp_port
|
||||||
|
|
||||||
|
|
||||||
|
Note that these values are stored in `network byte order
|
||||||
|
<http://en.wikipedia.org/wiki/Endianness#Endianness_in_networking>`__
|
||||||
|
so you will need to flip the bytes around if you are on a low-endian
|
||||||
|
machine (which is why the above example prints them in hex). For
|
||||||
|
example, if an IP address prints as ``0100007f`` , that's 127.0.0.1 .
|
||||||
|
|
205
doc/scripts/CMakeLists.txt
Normal file
205
doc/scripts/CMakeLists.txt
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
# find out what BROPATH to use when executing bro
|
||||||
|
execute_process(COMMAND ${CMAKE_BINARY_DIR}/bro-path-dev
|
||||||
|
OUTPUT_VARIABLE BROPATH
|
||||||
|
RESULT_VARIABLE retval
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if (NOT ${retval} EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Problem setting BROPATH")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# This macro is used to add a new makefile target for reST policy script
|
||||||
|
# documentation that can be generated using Bro itself to parse policy scripts.
|
||||||
|
# It's called like:
|
||||||
|
#
|
||||||
|
# rest_target(srcDir broInput [group])
|
||||||
|
#
|
||||||
|
# srcDir: the directory which contains broInput
|
||||||
|
# broInput: the file name of a bro policy script, any path prefix of this
|
||||||
|
# argument will be used to derive what path under policy/ the generated
|
||||||
|
# documentation will be placed.
|
||||||
|
# group: optional name of group that the script documentation will belong to.
|
||||||
|
# If this is not given, .bif files automatically get their own group or
|
||||||
|
# the group is automatically by any path portion of the broInput argument.
|
||||||
|
#
|
||||||
|
# In addition to adding the makefile target, several CMake variables are set:
|
||||||
|
#
|
||||||
|
# MASTER_POLICY_INDEX_TEXT: a running list of policy scripts docs that have
|
||||||
|
# been generated so far, formatted such that it can be appended to a file
|
||||||
|
# that ends in a Sphinx toctree directive
|
||||||
|
# ALL_REST_OUTPUTS: a running list (the CMake list type) of all reST docs
|
||||||
|
# that are to be generated
|
||||||
|
# MASTER_GROUP_LIST: a running list (the CMake list type) of all script groups
|
||||||
|
# MASTER_PKG_LIST: a running list (the CMake list type) of all script groups
|
||||||
|
# that were defived from the path portion of the broInput argument
|
||||||
|
# ${group}_files: a running list of files belonging to a given group, from
|
||||||
|
# which summary text can be extracted at build time
|
||||||
|
# ${group}_doc_names: a running list of reST style document names that can be
|
||||||
|
# given to a :doc: role, shared indices with ${group}_files
|
||||||
|
|
||||||
|
macro(REST_TARGET srcDir broInput)
|
||||||
|
set(absSrcPath ${srcDir}/${broInput})
|
||||||
|
get_filename_component(basename ${broInput} NAME)
|
||||||
|
string(REPLACE .bro "" basename ${basename})
|
||||||
|
get_filename_component(extension ${broInput} EXT)
|
||||||
|
get_filename_component(relDstDir ${broInput} PATH)
|
||||||
|
|
||||||
|
set(sumTextSrc ${absSrcPath})
|
||||||
|
set(ogSourceFile ${absSrcPath})
|
||||||
|
if (${extension} STREQUAL ".bif.bro")
|
||||||
|
set(ogSourceFile ${BIF_SRC_DIR}/${basename})
|
||||||
|
# the summary text is taken at configure time, but .bif.bro files
|
||||||
|
# may not have been generated yet, so read .bif file instead
|
||||||
|
set(sumTextSrc ${ogSourceFile})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT relDstDir)
|
||||||
|
set(docName "${basename}")
|
||||||
|
set(dstDir "${RST_OUTPUT_DIR}")
|
||||||
|
else ()
|
||||||
|
set(docName "${relDstDir}/${basename}")
|
||||||
|
set(dstDir "${RST_OUTPUT_DIR}/${relDstDir}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(restFile "${docName}.rst")
|
||||||
|
string(REPLACE "/" "^" restFile ${restFile})
|
||||||
|
set(restOutput "${dstDir}/${basename}.rst")
|
||||||
|
|
||||||
|
set(MASTER_POLICY_INDEX_TEXT
|
||||||
|
"${MASTER_POLICY_INDEX_TEXT}\n ${docName} <${docName}>")
|
||||||
|
list(APPEND ALL_REST_OUTPUTS ${restOutput})
|
||||||
|
|
||||||
|
if (NOT "${ARGN}" STREQUAL "")
|
||||||
|
set(group ${ARGN})
|
||||||
|
elseif (${extension} STREQUAL ".bif.bro")
|
||||||
|
set(group bifs)
|
||||||
|
elseif (relDstDir)
|
||||||
|
set(group ${relDstDir}/index)
|
||||||
|
# add package index to master package list if not already in it
|
||||||
|
# and if a __load__.bro exists in the original script directory
|
||||||
|
list(FIND MASTER_PKG_LIST ${relDstDir} _found)
|
||||||
|
if (_found EQUAL -1)
|
||||||
|
if (EXISTS ${CMAKE_SOURCE_DIR}/scripts/${relDstDir}/__load__.bro)
|
||||||
|
list(APPEND MASTER_PKG_LIST ${relDstDir})
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
else ()
|
||||||
|
set(group "")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT "${group}" STREQUAL "")
|
||||||
|
# add group to master group list if not already in it
|
||||||
|
list(FIND MASTER_GROUP_LIST ${group} _found)
|
||||||
|
if (_found EQUAL -1)
|
||||||
|
list(APPEND MASTER_GROUP_LIST ${group})
|
||||||
|
if (MASTER_GROUP_LIST_TEXT)
|
||||||
|
set(MASTER_GROUP_LIST_TEXT "${MASTER_GROUP_LIST_TEXT}\n${group}")
|
||||||
|
else ()
|
||||||
|
set(MASTER_GROUP_LIST_TEXT "${group}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
list(APPEND ${group}_files ${sumTextSrc})
|
||||||
|
list(APPEND ${group}_doc_names ${docName})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${restOutput}
|
||||||
|
# delete any leftover state from previous bro runs
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
ARGS -E remove_directory .state
|
||||||
|
# generate the reST documentation using bro
|
||||||
|
COMMAND BROPATH=${BROPATH}:${srcDir} ${CMAKE_BINARY_DIR}/src/bro
|
||||||
|
ARGS -b -Z ${broInput} || (rm -rf .state *.log *.rst && exit 1)
|
||||||
|
# move generated doc into a new directory tree that
|
||||||
|
# defines the final structure of documents
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
ARGS -E make_directory ${dstDir}
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
ARGS -E copy ${restFile} ${restOutput}
|
||||||
|
# copy the bro or bif script, too
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
ARGS -E copy ${ogSourceFile} ${dstDir}
|
||||||
|
# clean up the build directory
|
||||||
|
COMMAND rm
|
||||||
|
ARGS -rf .state *.log *.rst
|
||||||
|
DEPENDS bro
|
||||||
|
DEPENDS ${absSrcPath}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
|
COMMENT "[Bro] Generating reST docs for ${broInput}"
|
||||||
|
)
|
||||||
|
|
||||||
|
endmacro(REST_TARGET)
|
||||||
|
|
||||||
|
# Schedule Bro scripts for which to generate documentation.
|
||||||
|
include(DocSourcesList.cmake)
|
||||||
|
|
||||||
|
# create temporary list of all docs to include in the master policy/index file
|
||||||
|
file(WRITE ${MASTER_POLICY_INDEX} "${MASTER_POLICY_INDEX_TEXT}")
|
||||||
|
|
||||||
|
# create the temporary list of all packages to include in the master
|
||||||
|
# policy/packages.rst file
|
||||||
|
set(MASTER_PKG_INDEX_TEXT "")
|
||||||
|
foreach (pkg ${MASTER_PKG_LIST})
|
||||||
|
set(MASTER_PKG_INDEX_TEXT
|
||||||
|
"${MASTER_PKG_INDEX_TEXT}\n:doc:`${pkg} <${pkg}/index>`\n")
|
||||||
|
if (EXISTS ${CMAKE_SOURCE_DIR}/scripts/${pkg}/README)
|
||||||
|
file(STRINGS ${CMAKE_SOURCE_DIR}/scripts/${pkg}/README pkgreadme)
|
||||||
|
foreach (line ${pkgreadme})
|
||||||
|
set(MASTER_PKG_INDEX_TEXT "${MASTER_PKG_INDEX_TEXT}\n ${line}")
|
||||||
|
endforeach ()
|
||||||
|
set(MASTER_PKG_INDEX_TEXT "${MASTER_PKG_INDEX_TEXT}\n")
|
||||||
|
endif ()
|
||||||
|
endforeach ()
|
||||||
|
file(WRITE ${MASTER_PACKAGE_INDEX} "${MASTER_PKG_INDEX_TEXT}")
|
||||||
|
|
||||||
|
# create temporary file containing list of all groups
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/group_list
|
||||||
|
"${MASTER_GROUP_LIST_TEXT}")
|
||||||
|
|
||||||
|
# create temporary files containing list of each source file in a given group
|
||||||
|
foreach (group ${MASTER_GROUP_LIST})
|
||||||
|
if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${group}_files)
|
||||||
|
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${group}_files)
|
||||||
|
endif ()
|
||||||
|
if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${group}_doc_names)
|
||||||
|
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${group}_doc_names)
|
||||||
|
endif ()
|
||||||
|
foreach (src ${${group}_files})
|
||||||
|
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${group}_files "${src}\n")
|
||||||
|
endforeach ()
|
||||||
|
foreach (dname ${${group}_doc_names})
|
||||||
|
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${group}_doc_names "${dname}\n")
|
||||||
|
endforeach ()
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
# remove previously generated docs no longer scheduled for generation
|
||||||
|
if (EXISTS ${RST_OUTPUT_DIR})
|
||||||
|
file(GLOB_RECURSE EXISTING_REST_DOCS "${RST_OUTPUT_DIR}/*.rst")
|
||||||
|
foreach (_doc ${EXISTING_REST_DOCS})
|
||||||
|
list(FIND ALL_REST_OUTPUTS ${_doc} _found)
|
||||||
|
if (_found EQUAL -1)
|
||||||
|
file(REMOVE ${_doc})
|
||||||
|
message(STATUS "Broxygen: remove stale reST doc: ${_doc}")
|
||||||
|
string(REPLACE .rst .bro _brofile ${_doc})
|
||||||
|
if (EXISTS ${_brofile})
|
||||||
|
file(REMOVE ${_brofile})
|
||||||
|
message(STATUS "Broxygen: remove stale bro source: ${_brofile}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endforeach ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# The "restdoc" target uses Bro to parse policy scripts in order to
|
||||||
|
# generate reST documentation from them.
|
||||||
|
add_custom_target(restdoc
|
||||||
|
# create symlink to the reST output directory for convenience
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E create_symlink
|
||||||
|
${RST_OUTPUT_DIR}
|
||||||
|
${CMAKE_BINARY_DIR}/reST
|
||||||
|
DEPENDS ${ALL_REST_OUTPUTS})
|
||||||
|
|
||||||
|
# The "restclean" target removes all generated reST documentation from the
|
||||||
|
# build directory.
|
||||||
|
add_custom_target(restclean
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||||
|
${RST_OUTPUT_DIR}
|
||||||
|
VERBATIM)
|
143
doc/scripts/DocSourcesList.cmake
Normal file
143
doc/scripts/DocSourcesList.cmake
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# DO NOT EDIT
|
||||||
|
# This file is auto-generated from the genDocSourcesList.sh script.
|
||||||
|
#
|
||||||
|
# This is a list of Bro script sources for which to generate reST documentation.
|
||||||
|
# It will be included inline in the CMakeLists.txt found in the same directory
|
||||||
|
# in order to create Makefile targets that define how to generate reST from
|
||||||
|
# a given Bro script.
|
||||||
|
#
|
||||||
|
# Note: any path prefix of the script (2nd argument of rest_target macro)
|
||||||
|
# will be used to derive what path under scripts/ the generated documentation
|
||||||
|
# will be placed.
|
||||||
|
|
||||||
|
set(psd ${PROJECT_SOURCE_DIR}/scripts)
|
||||||
|
|
||||||
|
rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro internal)
|
||||||
|
rest_target(${psd} base/init-default.bro internal)
|
||||||
|
rest_target(${psd} base/init-bare.bro internal)
|
||||||
|
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/bro.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/const.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/event.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/logging.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/reporter.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/strings.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/types.bif.bro)
|
||||||
|
rest_target(${psd} base/frameworks/cluster/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/cluster/nodes/manager.bro)
|
||||||
|
rest_target(${psd} base/frameworks/cluster/nodes/proxy.bro)
|
||||||
|
rest_target(${psd} base/frameworks/cluster/nodes/worker.bro)
|
||||||
|
rest_target(${psd} base/frameworks/cluster/setup-connections.bro)
|
||||||
|
rest_target(${psd} base/frameworks/communication/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/control/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/dpd/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/intel/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/logging/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/logging/postprocessors/scp.bro)
|
||||||
|
rest_target(${psd} base/frameworks/logging/postprocessors/sftp.bro)
|
||||||
|
rest_target(${psd} base/frameworks/logging/writers/ascii.bro)
|
||||||
|
rest_target(${psd} base/frameworks/metrics/cluster.bro)
|
||||||
|
rest_target(${psd} base/frameworks/metrics/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/metrics/non-cluster.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/actions/add-geodata.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/actions/drop.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/actions/email_admin.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/actions/page.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/actions/pp-alarms.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/cluster.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/extend-email/hostnames.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/notice/weird.bro)
|
||||||
|
rest_target(${psd} base/frameworks/packet-filter/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/packet-filter/netstats.bro)
|
||||||
|
rest_target(${psd} base/frameworks/reporter/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/signatures/main.bro)
|
||||||
|
rest_target(${psd} base/frameworks/software/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/conn/contents.bro)
|
||||||
|
rest_target(${psd} base/protocols/conn/inactivity.bro)
|
||||||
|
rest_target(${psd} base/protocols/conn/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/dns/consts.bro)
|
||||||
|
rest_target(${psd} base/protocols/dns/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/ftp/file-extract.bro)
|
||||||
|
rest_target(${psd} base/protocols/ftp/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/ftp/utils-commands.bro)
|
||||||
|
rest_target(${psd} base/protocols/http/file-extract.bro)
|
||||||
|
rest_target(${psd} base/protocols/http/file-hash.bro)
|
||||||
|
rest_target(${psd} base/protocols/http/file-ident.bro)
|
||||||
|
rest_target(${psd} base/protocols/http/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/http/utils.bro)
|
||||||
|
rest_target(${psd} base/protocols/irc/dcc-send.bro)
|
||||||
|
rest_target(${psd} base/protocols/irc/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/smtp/entities-excerpt.bro)
|
||||||
|
rest_target(${psd} base/protocols/smtp/entities.bro)
|
||||||
|
rest_target(${psd} base/protocols/smtp/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/ssh/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/ssl/consts.bro)
|
||||||
|
rest_target(${psd} base/protocols/ssl/main.bro)
|
||||||
|
rest_target(${psd} base/protocols/ssl/mozilla-ca-list.bro)
|
||||||
|
rest_target(${psd} base/protocols/syslog/consts.bro)
|
||||||
|
rest_target(${psd} base/protocols/syslog/main.bro)
|
||||||
|
rest_target(${psd} base/utils/addrs.bro)
|
||||||
|
rest_target(${psd} base/utils/conn-ids.bro)
|
||||||
|
rest_target(${psd} base/utils/directions-and-hosts.bro)
|
||||||
|
rest_target(${psd} base/utils/files.bro)
|
||||||
|
rest_target(${psd} base/utils/numbers.bro)
|
||||||
|
rest_target(${psd} base/utils/paths.bro)
|
||||||
|
rest_target(${psd} base/utils/patterns.bro)
|
||||||
|
rest_target(${psd} base/utils/site.bro)
|
||||||
|
rest_target(${psd} base/utils/strings.bro)
|
||||||
|
rest_target(${psd} base/utils/thresholds.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/communication/listen.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/control/controllee.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/control/controller.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/dpd/detect-protocols.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/dpd/packet-segment-logging.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/metrics/conn-example.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/metrics/http-example.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/metrics/ssl-example.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/software/version-changes.bro)
|
||||||
|
rest_target(${psd} policy/frameworks/software/vulnerable.bro)
|
||||||
|
rest_target(${psd} policy/integration/barnyard2/main.bro)
|
||||||
|
rest_target(${psd} policy/integration/barnyard2/types.bro)
|
||||||
|
rest_target(${psd} policy/misc/analysis-groups.bro)
|
||||||
|
rest_target(${psd} policy/misc/capture-loss.bro)
|
||||||
|
rest_target(${psd} policy/misc/loaded-scripts.bro)
|
||||||
|
rest_target(${psd} policy/misc/profiling.bro)
|
||||||
|
rest_target(${psd} policy/misc/stats.bro)
|
||||||
|
rest_target(${psd} policy/misc/trim-trace-file.bro)
|
||||||
|
rest_target(${psd} policy/protocols/conn/known-hosts.bro)
|
||||||
|
rest_target(${psd} policy/protocols/conn/known-services.bro)
|
||||||
|
rest_target(${psd} policy/protocols/conn/weirds.bro)
|
||||||
|
rest_target(${psd} policy/protocols/dns/auth-addl.bro)
|
||||||
|
rest_target(${psd} policy/protocols/dns/detect-external-names.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ftp/detect.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ftp/software.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/detect-MHR.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/detect-intel.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/detect-sqli.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/detect-webapps.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/header-names.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/software-browser-plugins.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/software.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/var-extraction-cookies.bro)
|
||||||
|
rest_target(${psd} policy/protocols/http/var-extraction-uri.bro)
|
||||||
|
rest_target(${psd} policy/protocols/smtp/blocklists.bro)
|
||||||
|
rest_target(${psd} policy/protocols/smtp/detect-suspicious-orig.bro)
|
||||||
|
rest_target(${psd} policy/protocols/smtp/software.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssh/detect-bruteforcing.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssh/geo-data.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssh/interesting-hostnames.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssh/software.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssl/cert-hash.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssl/expiring-certs.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssl/extract-certs-pem.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssl/known-certs.bro)
|
||||||
|
rest_target(${psd} policy/protocols/ssl/validate-certs.bro)
|
||||||
|
rest_target(${psd} policy/tuning/defaults/packet-fragments.bro)
|
||||||
|
rest_target(${psd} policy/tuning/defaults/warnings.bro)
|
||||||
|
rest_target(${psd} policy/tuning/track-all-assets.bro)
|
||||||
|
rest_target(${psd} site/local-manager.bro)
|
||||||
|
rest_target(${psd} site/local-proxy.bro)
|
||||||
|
rest_target(${psd} site/local-worker.bro)
|
||||||
|
rest_target(${psd} site/local.bro)
|
||||||
|
rest_target(${psd} test-all-policy.bro)
|
44
doc/scripts/README
Normal file
44
doc/scripts/README
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
This directory contains scripts and templates that can be used to automate
|
||||||
|
the generation of Bro script documentation. Several build targets are defined
|
||||||
|
by CMake and available in the top-level Makefile:
|
||||||
|
|
||||||
|
``restdoc``
|
||||||
|
|
||||||
|
This target uses Bro to parse policy scripts in order to generate
|
||||||
|
reStructuredText (reST) documentation from them. The list of scripts
|
||||||
|
for which to generate reST documentation is defined in the
|
||||||
|
``CMakeLists.txt`` file in this directory. Script documentation is
|
||||||
|
rebuild automatically if the policy script from which it is derived
|
||||||
|
or the Bro binary becomes out of date
|
||||||
|
|
||||||
|
The resulting output from this target can be found in the CMake
|
||||||
|
``build/`` directory inside ``reST`` (a symlink to
|
||||||
|
``doc/scripts/rest_output``).
|
||||||
|
|
||||||
|
``restclean``
|
||||||
|
|
||||||
|
This target removes any reST documentation that has been generated so far.
|
||||||
|
|
||||||
|
The ``genDocSourcesList.sh`` script can be run to automatically generate
|
||||||
|
``DocSourcesList.cmake``, which is the file CMake uses to define the list
|
||||||
|
of documentation targets. This script should be run after adding new
|
||||||
|
Bro script source files, and the changes commited to git.
|
||||||
|
|
||||||
|
If a script shouldn't have documentation generated for it, there's also a
|
||||||
|
blacklist manifest that can be maintained in the ``genDocSourcesList.sh``
|
||||||
|
script.
|
||||||
|
|
||||||
|
The blacklist can also be used if you want to define a certain grouping for
|
||||||
|
the script's generated docs to belong to (as opposed to the automatic grouping
|
||||||
|
the happens for script packages/directories). To do that, add the
|
||||||
|
script's name to the blacklist, then append a ``rest_target()`` to the
|
||||||
|
``statictext`` variable where the first argument is the source directory
|
||||||
|
containing the policy script to document, the second argument is the file
|
||||||
|
name of the policy script, and the third argument is the path/name of a
|
||||||
|
pre-created reST document in the ``../`` source directory to which the
|
||||||
|
``make doc`` process can append script documentation references. This
|
||||||
|
pre-created reST document should also then be linked to from the TOC tree
|
||||||
|
in ``../index.rst``.
|
||||||
|
|
||||||
|
See ``example.bro`` for an example of how to document a Bro script such that
|
||||||
|
``make doc`` will be able to produce reST/HTML documentation for it.
|
5
doc/scripts/bifs.rst
Normal file
5
doc/scripts/bifs.rst
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.. This is a stub doc to which broxygen appends during the build process
|
||||||
|
|
||||||
|
Built-In Functions (BIFs)
|
||||||
|
=========================
|
||||||
|
|
635
doc/scripts/builtins.rst
Normal file
635
doc/scripts/builtins.rst
Normal file
|
@ -0,0 +1,635 @@
|
||||||
|
Builtin Types and Attributes
|
||||||
|
============================
|
||||||
|
|
||||||
|
Types
|
||||||
|
-----
|
||||||
|
|
||||||
|
The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
|
.. bro:type:: void
|
||||||
|
|
||||||
|
An internal Bro type representing an absence of a type. Should
|
||||||
|
most often be seen as a possible function return type.
|
||||||
|
|
||||||
|
.. bro:type:: bool
|
||||||
|
|
||||||
|
Reflects a value with one of two meanings: true or false. The two
|
||||||
|
``bool`` constants are ``T`` and ``F``.
|
||||||
|
|
||||||
|
.. bro:type:: int
|
||||||
|
|
||||||
|
A numeric type representing a signed integer. An ``int`` constant
|
||||||
|
is a string of digits preceded by a ``+`` or ``-`` sign, e.g.
|
||||||
|
``-42`` or ``+5``. When using type inferencing use care so that the
|
||||||
|
intended type is inferred, e.g. ``local size_difference = 0`` will
|
||||||
|
infer :bro:type:`count`, while ``local size_difference = +0``
|
||||||
|
will infer :bro:type:`int`.
|
||||||
|
|
||||||
|
.. bro:type:: count
|
||||||
|
|
||||||
|
A numeric type representing an unsigned integer. A ``count``
|
||||||
|
constant is a string of digits, e.g. ``1234`` or ``0``.
|
||||||
|
|
||||||
|
.. bro:type:: counter
|
||||||
|
|
||||||
|
An alias to :bro:type:`count`.
|
||||||
|
|
||||||
|
.. TODO: is there anything special about this type?
|
||||||
|
|
||||||
|
.. bro:type:: double
|
||||||
|
|
||||||
|
A numeric type representing a double-precision floating-point
|
||||||
|
number. Floating-point constants are written as a string of digits
|
||||||
|
with an optional decimal point, optional scale-factor in scientific
|
||||||
|
notation, and optional ``+`` or ``-`` sign. Examples are ``-1234``,
|
||||||
|
``-1234e0``, ``3.14159``, and ``.003e-23``.
|
||||||
|
|
||||||
|
.. bro:type:: time
|
||||||
|
|
||||||
|
A temporal type representing an absolute time. There is currently
|
||||||
|
no way to specify a ``time`` constant, but one can use the
|
||||||
|
:bro:id:`current_time` or :bro:id:`network_time` built-in functions
|
||||||
|
to assign a value to a ``time``-typed variable.
|
||||||
|
|
||||||
|
.. bro:type:: interval
|
||||||
|
|
||||||
|
A temporal type representing a relative time. An ``interval``
|
||||||
|
constant can be written as a numeric constant followed by a time
|
||||||
|
unit where the time unit is one of ``usec``, ``sec``, ``min``,
|
||||||
|
``hr``, or ``day`` which respectively represent microseconds,
|
||||||
|
seconds, minutes, hours, and days. Whitespace between the numeric
|
||||||
|
constant and time unit is optional. Appending the letter "s" to the
|
||||||
|
time unit in order to pluralize it is also optional (to no semantic
|
||||||
|
effect). Examples of ``interval`` constants are ``3.5 min`` and
|
||||||
|
``3.5mins``. An ``interval`` can also be negated, for example ``-
|
||||||
|
12 hr`` represents "twelve hours in the past". Intervals also
|
||||||
|
support addition, subtraction, multiplication, division, and
|
||||||
|
comparison operations.
|
||||||
|
|
||||||
|
.. bro:type:: string
|
||||||
|
|
||||||
|
A type used to hold character-string values which represent text.
|
||||||
|
String constants are created by enclosing text in double quotes (")
|
||||||
|
and the backslash character (\\) introduces escape sequences.
|
||||||
|
|
||||||
|
Note that Bro represents strings internally as a count and vector of
|
||||||
|
bytes rather than a NUL-terminated byte string (although string
|
||||||
|
constants are also automatically NUL-terminated). This is because
|
||||||
|
network traffic can easily introduce NULs into strings either by
|
||||||
|
nature of an application, inadvertently, or maliciously. And while
|
||||||
|
NULs are allowed in Bro strings, when present in strings passed as
|
||||||
|
arguments to many functions, a run-time error can occur as their
|
||||||
|
presence likely indicates a sort of problem. In that case, the
|
||||||
|
string will also only be represented to the user as the literal
|
||||||
|
"<string-with-NUL>" string.
|
||||||
|
|
||||||
|
.. bro:type:: pattern
|
||||||
|
|
||||||
|
A type representing regular-expression patterns which can be used
|
||||||
|
for fast text-searching operations. Pattern constants are created
|
||||||
|
by enclosing text within forward slashes (/) and is the same syntax
|
||||||
|
as the patterns supported by the `flex lexical analyzer
|
||||||
|
<http://flex.sourceforge.net/manual/Patterns.html>`_. The speed of
|
||||||
|
regular expression matching does not depend on the complexity or
|
||||||
|
size of the patterns. Patterns support two types of matching, exact
|
||||||
|
and embedded.
|
||||||
|
|
||||||
|
In exact matching the ``==`` equality relational operator is used
|
||||||
|
with one :bro:type:`string` operand and one :bro:type:`pattern`
|
||||||
|
operand to check whether the full string exactly matches the
|
||||||
|
pattern. In this case, the ``^`` beginning-of-line and ``$``
|
||||||
|
end-of-line anchors are redundant since pattern is implicitly
|
||||||
|
anchored to the beginning and end of the line to facilitate an exact
|
||||||
|
match. For example::
|
||||||
|
|
||||||
|
"foo" == /foo|bar/
|
||||||
|
|
||||||
|
yields true, while::
|
||||||
|
|
||||||
|
/foo|bar/ == "foobar"
|
||||||
|
|
||||||
|
yields false. The ``!=`` operator would yield the negation of ``==``.
|
||||||
|
|
||||||
|
In embedded matching the ``in`` operator is again used with one
|
||||||
|
:bro:type:`string` operand and one :bro:type:`pattern` operand
|
||||||
|
(which must be on the left-hand side), but tests whether the pattern
|
||||||
|
appears anywhere within the given string. For example::
|
||||||
|
|
||||||
|
/foo|bar/ in "foobar"
|
||||||
|
|
||||||
|
yields true, while::
|
||||||
|
|
||||||
|
/^oob/ in "foobar"
|
||||||
|
|
||||||
|
is false since "oob" does not appear at the start of "foobar". The
|
||||||
|
``!in`` operator would yield the negation of ``in``.
|
||||||
|
|
||||||
|
.. bro:type:: enum
|
||||||
|
|
||||||
|
A type allowing the specification of a set of related values that
|
||||||
|
have no further structure. The only operations allowed on
|
||||||
|
enumerations are equality comparisons and they do not have
|
||||||
|
associated values or ordering. An example declaration:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
type color: enum { Red, White, Blue, };
|
||||||
|
|
||||||
|
The last comma after ``Blue`` is optional.
|
||||||
|
|
||||||
|
.. bro:type:: timer
|
||||||
|
|
||||||
|
.. TODO: is this a type that's exposed to users?
|
||||||
|
|
||||||
|
.. bro:type:: port
|
||||||
|
|
||||||
|
A type representing transport-level port numbers. Besides TCP and
|
||||||
|
UDP ports, there is a concept of an ICMP "port" where the source
|
||||||
|
port is the ICMP message type and the destination port the ICMP
|
||||||
|
message code. A ``port`` constant is written as an unsigned integer
|
||||||
|
followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``.
|
||||||
|
|
||||||
|
Ports can be compared for equality and also for ordering. When
|
||||||
|
comparing order across transport-level protocols, ``unknown`` <
|
||||||
|
``tcp`` < ``udp`` < ``icmp``, for example ``65535/tcp`` is smaller
|
||||||
|
than ``0/udp``.
|
||||||
|
|
||||||
|
.. bro:type:: addr
|
||||||
|
|
||||||
|
A type representing an IP address. Currently, Bro defaults to only
|
||||||
|
supporting IPv4 addresses unless configured/built with
|
||||||
|
``--enable-brov6``, in which case, IPv6 addresses are supported.
|
||||||
|
|
||||||
|
IPv4 address constants are written in "dotted quad" format,
|
||||||
|
``A1.A2.A3.A4``, where Ai all lie between 0 and 255.
|
||||||
|
|
||||||
|
IPv6 address constants are written as colon-separated hexadecimal form
|
||||||
|
as described by :rfc:`2373`.
|
||||||
|
|
||||||
|
Hostname constants can also be used, but since a hostname can
|
||||||
|
correspond to multiple IP addresses, the type of such variable is a
|
||||||
|
:bro:type:`set` of :bro:type:`addr` elements. For example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local a = www.google.com;
|
||||||
|
|
||||||
|
Addresses can be compared for (in)equality using ``==`` and ``!=``.
|
||||||
|
They can also be masked with ``/`` to produce a :bro:type:`subnet`:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local a: addr = 192.168.1.100;
|
||||||
|
local s: subnet = 192.168.0.0/16;
|
||||||
|
if ( a/16 == s )
|
||||||
|
print "true";
|
||||||
|
|
||||||
|
And checked for inclusion within a :bro:type:`subnet` using ``in`` :
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local a: addr = 192.168.1.100;
|
||||||
|
local s: subnet = 192.168.0.0/16;
|
||||||
|
if ( a in s )
|
||||||
|
print "true";
|
||||||
|
|
||||||
|
.. bro:type:: subnet
|
||||||
|
|
||||||
|
A type representing a block of IP addresses in CIDR notation. A
|
||||||
|
``subnet`` constant is written as an :bro:type:`addr` followed by a
|
||||||
|
slash (/) and then the network prefix size specified as a decimal
|
||||||
|
number. For example, ``192.168.0.0/16``.
|
||||||
|
|
||||||
|
.. bro:type:: any
|
||||||
|
|
||||||
|
Used to bypass strong typing. For example, a function can take an
|
||||||
|
argument of type ``any`` when it may be of different types.
|
||||||
|
|
||||||
|
.. bro:type:: table
|
||||||
|
|
||||||
|
An associate array that maps from one set of values to another. The
|
||||||
|
values being mapped are termed the *index* or *indices* and the
|
||||||
|
result of the mapping is called the *yield*. Indexing into tables
|
||||||
|
is very efficient, and internally it is just a single hash table
|
||||||
|
lookup.
|
||||||
|
|
||||||
|
The table declaration syntax is::
|
||||||
|
|
||||||
|
table [ type^+ ] of type
|
||||||
|
|
||||||
|
where *type^+* is one or more types, separated by commas. For example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global a: table[count] of string;
|
||||||
|
|
||||||
|
declares a table indexed by :bro:type:`count` values and yielding
|
||||||
|
:bro:type:`string` values. The yield type can also be more complex:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global a: table[count] of table[addr, port] of string;
|
||||||
|
|
||||||
|
which declares a table indexed by :bro:type:`count` and yielding
|
||||||
|
another :bro:type:`table` which is indexed by an :bro:type:`addr`
|
||||||
|
and :bro:type:`port` to yield a :bro:type:`string`.
|
||||||
|
|
||||||
|
Initialization of tables occurs by enclosing a set of initializers within
|
||||||
|
braces, for example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global t: table[count] of string = {
|
||||||
|
[11] = "eleven",
|
||||||
|
[5] = "five",
|
||||||
|
};
|
||||||
|
|
||||||
|
Accessing table elements if provided by enclosing values within square
|
||||||
|
brackets (``[]``), for example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
t[13] = "thirteen";
|
||||||
|
|
||||||
|
And membership can be tested with ``in``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
if ( 13 in t )
|
||||||
|
...
|
||||||
|
|
||||||
|
Iterate over tables with a ``for`` loop:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local t: table[count] of string;
|
||||||
|
for ( n in t )
|
||||||
|
...
|
||||||
|
|
||||||
|
local services: table[addr, port] of string;
|
||||||
|
for ( [a, p] in services )
|
||||||
|
...
|
||||||
|
|
||||||
|
Remove individual table elements with ``delete``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
delete t[13];
|
||||||
|
|
||||||
|
Nothing happens if the element with value ``13`` isn't present in
|
||||||
|
the table.
|
||||||
|
|
||||||
|
Table size can be obtained by placing the table identifier between
|
||||||
|
vertical pipe (|) characters:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
|t|
|
||||||
|
|
||||||
|
.. bro:type:: set
|
||||||
|
|
||||||
|
A set is like a :bro:type:`table`, but it is a collection of indices
|
||||||
|
that do not map to any yield value. They are declared with the
|
||||||
|
syntax::
|
||||||
|
|
||||||
|
set [ type^+ ]
|
||||||
|
|
||||||
|
where *type^+* is one or more types separated by commas.
|
||||||
|
|
||||||
|
Sets are initialized by listing elements enclosed by curly braces:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
|
||||||
|
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
||||||
|
|
||||||
|
The types are explicitly shown in the example above, but they could
|
||||||
|
have been left to type inference.
|
||||||
|
|
||||||
|
Set membership is tested with ``in``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
if ( 21/tcp in s )
|
||||||
|
...
|
||||||
|
|
||||||
|
Elements are added with ``add``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
add s[22/tcp];
|
||||||
|
|
||||||
|
And removed with ``delete``:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
delete s[21/tcp];
|
||||||
|
|
||||||
|
Set size can be obtained by placing the set identifier between
|
||||||
|
vertical pipe (|) characters:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
|s|
|
||||||
|
|
||||||
|
.. bro:type:: vector
|
||||||
|
|
||||||
|
A vector is like a :bro:type:`table`, except it's always indexed by a
|
||||||
|
:bro:type:`count`. A vector is declared like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global v: vector of string;
|
||||||
|
|
||||||
|
And can be initialized with the vector constructor:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global v: vector of string = vector("one", "two", "three");
|
||||||
|
|
||||||
|
Adding an element to a vector involves accessing/assigning it:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
v[3] = "four"
|
||||||
|
|
||||||
|
Note how the vector indexing is 0-based.
|
||||||
|
|
||||||
|
Vector size can be obtained by placing the vector identifier between
|
||||||
|
vertical pipe (|) characters:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
|v|
|
||||||
|
|
||||||
|
.. bro:type:: record
|
||||||
|
|
||||||
|
A ``record`` is a collection of values. Each value has a field name
|
||||||
|
and a type. Values do not need to have the same type and the types
|
||||||
|
have no restrictions. An example record type definition:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
type MyRecordType: record {
|
||||||
|
c: count;
|
||||||
|
s: string &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
Access to a record field uses the dollar sign (``$``) operator:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global r: MyRecordType;
|
||||||
|
r$c = 13;
|
||||||
|
|
||||||
|
Record assignment can be done field by field or as a whole like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
r = [$c = 13, $s = "thirteen"];
|
||||||
|
|
||||||
|
When assigning a whole record value, all fields that are not
|
||||||
|
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
||||||
|
be specified.
|
||||||
|
|
||||||
|
To test for existence of a field that is :bro:attr:`&optional`, use the
|
||||||
|
``?$`` operator:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
if ( r?$s )
|
||||||
|
...
|
||||||
|
|
||||||
|
.. bro:type:: file
|
||||||
|
|
||||||
|
Bro supports writing to files, but not reading from them. For
|
||||||
|
example, declare, open, and write to a file and finally close it
|
||||||
|
like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global f: file = open("myfile");
|
||||||
|
print f, "hello, world";
|
||||||
|
close(f);
|
||||||
|
|
||||||
|
Writing to files like this for logging usually isn't recommended, for better
|
||||||
|
logging support see :doc:`/logging`.
|
||||||
|
|
||||||
|
.. bro:type:: func
|
||||||
|
|
||||||
|
See :bro:type:`function`.
|
||||||
|
|
||||||
|
.. bro:type:: function
|
||||||
|
|
||||||
|
Function types in Bro are declared using::
|
||||||
|
|
||||||
|
function( argument* ): type
|
||||||
|
|
||||||
|
where *argument* is a (possibly empty) comma-separated list of
|
||||||
|
arguments, and *type* is an optional return type. For example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
global greeting: function(name: string): string;
|
||||||
|
|
||||||
|
Here ``greeting`` is an identifier with a certain function type.
|
||||||
|
The function body is not defined yet and ``greeting`` could even
|
||||||
|
have different function body values at different times. To define
|
||||||
|
a function including a body value, the syntax is like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function greeting(name: string): string
|
||||||
|
{
|
||||||
|
return "Hello, " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that in the definition above, it's not necessary for us to have
|
||||||
|
done the first (forward) declaration of ``greeting`` as a function
|
||||||
|
type, but when it is, the argument list and return type much match
|
||||||
|
exactly.
|
||||||
|
|
||||||
|
Function types don't need to have a name and can be assigned anonymously:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
greeting = function(name: string): string { return "Hi, " + name; };
|
||||||
|
|
||||||
|
And finally, the function can be called like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
print greeting("Dave");
|
||||||
|
|
||||||
|
.. bro:type:: event
|
||||||
|
|
||||||
|
Event handlers are nearly identical in both syntax and semantics to
|
||||||
|
a :bro:type:`function`, with the two differences being that event
|
||||||
|
handlers have no return type since they never return a value, and
|
||||||
|
you cannot call an event handler. Instead of directly calling an
|
||||||
|
event handler from a script, event handler bodies are executed when
|
||||||
|
they are invoked by one of three different methods:
|
||||||
|
|
||||||
|
- From the event engine
|
||||||
|
|
||||||
|
When the event engine detects an event for which you have
|
||||||
|
defined a corresponding event handler, it queues an event for
|
||||||
|
that handler. The handler is invoked as soon as the event
|
||||||
|
engine finishes processing the current packet and flushing the
|
||||||
|
invocation of other event handlers that were queued first.
|
||||||
|
|
||||||
|
- With the ``event`` statement from a script
|
||||||
|
|
||||||
|
Immediately queuing invocation of an event handler occurs like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event password_exposed(user, password);
|
||||||
|
|
||||||
|
This assumes that ``password_exposed`` was previously declared
|
||||||
|
as an event handler type with compatible arguments.
|
||||||
|
|
||||||
|
- Via the ``schedule`` expression in a script
|
||||||
|
|
||||||
|
This delays the invocation of event handlers until some time in
|
||||||
|
the future. For example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
schedule 5 secs { password_exposed(user, password) };
|
||||||
|
|
||||||
|
Multiple event handler bodies can be defined for the same event handler
|
||||||
|
identifier and the body of each will be executed in turn. Ordering
|
||||||
|
of execution can be influenced with :bro:attr:`&priority`.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
|
||||||
|
Attributes occur at the end of type/event declarations and change their
|
||||||
|
behavior. The syntax is ``&key`` or ``&key=val``, e.g., ``type T:
|
||||||
|
set[count] &read_expire=5min`` or ``event foo() &priority=-3``. The Bro
|
||||||
|
scripting language supports the following built-in attributes.
|
||||||
|
|
||||||
|
.. bro:attr:: &optional
|
||||||
|
|
||||||
|
Allows a record field to be missing. For example the type ``record {
|
||||||
|
a: int, b: port &optional }`` could be instantiated both as
|
||||||
|
singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``.
|
||||||
|
|
||||||
|
.. bro:attr:: &default
|
||||||
|
|
||||||
|
Uses a default value for a record field or container elements. For
|
||||||
|
example, ``table[int] of string &default="foo" }`` would create a
|
||||||
|
table that returns the :bro:type:`string` ``"foo"`` for any
|
||||||
|
non-existing index.
|
||||||
|
|
||||||
|
.. bro:attr:: &redef
|
||||||
|
|
||||||
|
Allows for redefinition of initial object values. This is typically
|
||||||
|
used with constants, for example, ``const clever = T &redef;`` would
|
||||||
|
allow the constant to be redefined at some later point during script
|
||||||
|
execution.
|
||||||
|
|
||||||
|
.. bro:attr:: &rotate_interval
|
||||||
|
|
||||||
|
Rotates a file after a specified interval.
|
||||||
|
|
||||||
|
.. bro:attr:: &rotate_size
|
||||||
|
|
||||||
|
Rotates a file after it has reached a given size in bytes.
|
||||||
|
|
||||||
|
.. bro:attr:: &add_func
|
||||||
|
|
||||||
|
.. TODO: needs to be documented.
|
||||||
|
|
||||||
|
.. bro:attr:: &delete_func
|
||||||
|
|
||||||
|
.. TODO: needs to be documented.
|
||||||
|
|
||||||
|
.. bro:attr:: &expire_func
|
||||||
|
|
||||||
|
Called right before a container element expires.
|
||||||
|
|
||||||
|
.. bro:attr:: &read_expire
|
||||||
|
|
||||||
|
Specifies a read expiration timeout for container elements. That is,
|
||||||
|
the element expires after the given amount of time since the last
|
||||||
|
time it has been read. Note that a write also counts as a read.
|
||||||
|
|
||||||
|
.. bro:attr:: &write_expire
|
||||||
|
|
||||||
|
Specifies a write expiration timeout for container elements. That
|
||||||
|
is, the element expires after the given amount of time since the
|
||||||
|
last time it has been written.
|
||||||
|
|
||||||
|
.. bro:attr:: &create_expire
|
||||||
|
|
||||||
|
Specifies a creation expiration timeout for container elements. That
|
||||||
|
is, the element expires after the given amount of time since it has
|
||||||
|
been inserted into the container, regardless of any reads or writes.
|
||||||
|
|
||||||
|
.. bro:attr:: &persistent
|
||||||
|
|
||||||
|
Makes a variable persistent, i.e., its value is writen to disk (per
|
||||||
|
default at shutdown time).
|
||||||
|
|
||||||
|
.. bro:attr:: &synchronized
|
||||||
|
|
||||||
|
Synchronizes variable accesses across nodes. The value of a
|
||||||
|
``&synchronized`` variable is automatically propagated to all peers
|
||||||
|
when it changes.
|
||||||
|
|
||||||
|
.. bro:attr:: &postprocessor
|
||||||
|
|
||||||
|
.. TODO: needs to be documented.
|
||||||
|
|
||||||
|
.. bro:attr:: &encrypt
|
||||||
|
|
||||||
|
Encrypts files right before writing them to disk.
|
||||||
|
|
||||||
|
.. TODO: needs to be documented in more detail.
|
||||||
|
|
||||||
|
.. bro:attr:: &match
|
||||||
|
|
||||||
|
.. TODO: needs to be documented.
|
||||||
|
|
||||||
|
.. bro:attr:: &disable_print_hook
|
||||||
|
|
||||||
|
Deprecated. Will be removed.
|
||||||
|
|
||||||
|
.. bro:attr:: &raw_output
|
||||||
|
|
||||||
|
Opens a file in raw mode, i.e., non-ASCII characters are not
|
||||||
|
escaped.
|
||||||
|
|
||||||
|
.. bro:attr:: &mergeable
|
||||||
|
|
||||||
|
Prefers set union to assignment for synchronized state. This
|
||||||
|
attribute is used in conjunction with :bro:attr:`&synchronized`
|
||||||
|
container types: when the same container is updated at two peers
|
||||||
|
with different value, the propagation of the state causes a race
|
||||||
|
condition, where the last update succeeds. This can cause
|
||||||
|
inconsistencies and can be avoided by unifying the two sets, rather
|
||||||
|
than merely overwriting the old value.
|
||||||
|
|
||||||
|
.. bro:attr:: &priority
|
||||||
|
|
||||||
|
Specifies the execution priority of an event handler. Higher values
|
||||||
|
are executed before lower ones. The default value is 0.
|
||||||
|
|
||||||
|
.. bro:attr:: &group
|
||||||
|
|
||||||
|
Groups event handlers such that those in the same group can be
|
||||||
|
jointly activated or deactivated.
|
||||||
|
|
||||||
|
.. bro:attr:: &log
|
||||||
|
|
||||||
|
Writes a record field to the associated log stream.
|
||||||
|
|
||||||
|
.. bro:attr:: &error_handler
|
||||||
|
|
||||||
|
.. TODO: needs documented
|
||||||
|
|
||||||
|
.. bro:attr:: (&tracked)
|
||||||
|
|
||||||
|
.. TODO: needs documented or removed if it's not used anywhere.
|
225
doc/scripts/example.bro
Normal file
225
doc/scripts/example.bro
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
##! This is an example script that demonstrates documentation features.
|
||||||
|
##! Comments of the form ``##!`` are for the script summary. The contents of
|
||||||
|
##! these comments are transferred directly into the auto-generated
|
||||||
|
##! `reStructuredText <http://docutils.sourceforge.net/rst.html>`_
|
||||||
|
##! (reST) document's summary section.
|
||||||
|
##!
|
||||||
|
##! .. tip:: You can embed directives and roles within ``##``-stylized comments.
|
||||||
|
##!
|
||||||
|
##! There's also a custom role to reference any identifier node in
|
||||||
|
##! the Bro Sphinx domain that's good for "see alsos", e.g.
|
||||||
|
##!
|
||||||
|
##! See also: :bro:see:`Example::a_var`, :bro:see:`Example::ONE`,
|
||||||
|
##! :bro:see:`SSH::Info`
|
||||||
|
##!
|
||||||
|
##! And a custom directive does the equivalent references:
|
||||||
|
##!
|
||||||
|
##! .. bro:see:: Example::a_var Example::ONE SSH::Info
|
||||||
|
|
||||||
|
# Comments that use a single pound sign (#) are not significant to
|
||||||
|
# a script's auto-generated documentation, but ones that use a
|
||||||
|
# double pound sign (##) do matter. In some cases, like record
|
||||||
|
# field comments, it's necessary to disambiguate the field with
|
||||||
|
# which a comment associates: e.g. "##<" can be used on the same line
|
||||||
|
# as a field to signify the comment relates to it and not the
|
||||||
|
# following field. "##<" can also be used more generally in any
|
||||||
|
# variable declarations to associate with the last-declared identifier.
|
||||||
|
#
|
||||||
|
# Generally, the auto-doc comments (##) are associated with the
|
||||||
|
# next declaration/identifier found in the script, but the doc framework
|
||||||
|
# will track/render identifiers regardless of whether they have any
|
||||||
|
# of these special comments associated with them.
|
||||||
|
#
|
||||||
|
# The first sentence contained within the "##"-stylized comments for
|
||||||
|
# a given identifier is special in that it will be used as summary
|
||||||
|
# text in a table containing all such identifiers and short summaries.
|
||||||
|
# If there are no sentences (text terminated with '.'), then everything
|
||||||
|
# in the "##"-stylized comments up until the first empty comment
|
||||||
|
# is taken as the summary text for a given identifier.
|
||||||
|
|
||||||
|
# @load directives are self-documenting
|
||||||
|
@load frameworks/software/vulnerable
|
||||||
|
|
||||||
|
# "module" statements are self-documenting
|
||||||
|
module Example;
|
||||||
|
|
||||||
|
# redefinitions of "capture_filters" are self-documenting and
|
||||||
|
# go into the generated documentation's "Packet Filter" section
|
||||||
|
redef capture_filters += {
|
||||||
|
["ssl"] = "tcp port 443",
|
||||||
|
["nntps"] = "tcp port 562",
|
||||||
|
};
|
||||||
|
|
||||||
|
global example_ports = {
|
||||||
|
443/tcp, 562/tcp,
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
# redefinitions of "dpd_config" are self-documenting and
|
||||||
|
# go into the generated doc's "Port Analysis" section
|
||||||
|
redef dpd_config += {
|
||||||
|
[ANALYZER_SSL] = [$ports = example_ports]
|
||||||
|
};
|
||||||
|
|
||||||
|
# redefinitions of "Notice::Type" are self-documenting, but
|
||||||
|
# more information can be supplied in two different ways
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## any number of this type of comment
|
||||||
|
## will document "Notice_One"
|
||||||
|
Notice_One,
|
||||||
|
Notice_Two, ##< any number of this type of comment
|
||||||
|
##< will document "Notice_Two"
|
||||||
|
Notice_Three,
|
||||||
|
Notice_Four,
|
||||||
|
};
|
||||||
|
|
||||||
|
# Redef'ing the ID enumeration for logging streams is automatically tracked.
|
||||||
|
# Comments of the "##" form can be use to further document it, but it's
|
||||||
|
# better to do all documentation related to logging in the summary section
|
||||||
|
# as is shown above.
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
# Anything declared in the export section will show up in the rendered
|
||||||
|
# documentation's "public interface" section
|
||||||
|
|
||||||
|
export {
|
||||||
|
|
||||||
|
# these headings don't mean anything special to the
|
||||||
|
# doc framework right now, I'm just including them
|
||||||
|
# to make it more clear to the reader how the doc
|
||||||
|
# framework will actually categorize a script's identifiers
|
||||||
|
|
||||||
|
############## types ################
|
||||||
|
|
||||||
|
# Note that I'm just mixing the "##" and "##<"
|
||||||
|
# types of comments in the following declarations
|
||||||
|
# as a demonstration. Normally, it would be good style
|
||||||
|
# to pick one and be consistent.
|
||||||
|
|
||||||
|
## documentation for "SimpleEnum"
|
||||||
|
## goes here.
|
||||||
|
type SimpleEnum: enum {
|
||||||
|
## and more specific info for "ONE"
|
||||||
|
## can span multiple lines
|
||||||
|
ONE,
|
||||||
|
TWO, ##< or more info like this for "TWO"
|
||||||
|
##< can span multiple lines
|
||||||
|
THREE,
|
||||||
|
};
|
||||||
|
|
||||||
|
## document the "SimpleEnum" redef here
|
||||||
|
redef enum SimpleEnum += {
|
||||||
|
FOUR, ##< and some documentation for "FOUR"
|
||||||
|
## also "FIVE" for good measure
|
||||||
|
FIVE
|
||||||
|
};
|
||||||
|
|
||||||
|
## general documentation for a type "SimpleRecord"
|
||||||
|
## goes here.
|
||||||
|
type SimpleRecord: record {
|
||||||
|
## counts something
|
||||||
|
field1: count;
|
||||||
|
field2: bool; ##< toggles something
|
||||||
|
};
|
||||||
|
|
||||||
|
## document the record extension redef here
|
||||||
|
redef record SimpleRecord += {
|
||||||
|
## document the extending field here
|
||||||
|
field_ext: string &optional; ##< (or here)
|
||||||
|
};
|
||||||
|
|
||||||
|
## general documentation for a type "ComplexRecord" goes here
|
||||||
|
type ComplexRecord: record {
|
||||||
|
field1: count; ##< counts something
|
||||||
|
field2: bool; ##< toggles something
|
||||||
|
field3: SimpleRecord;
|
||||||
|
msg: string &default="blah"; ##< attributes are self-documenting
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
## An example record to be used with a logging stream.
|
||||||
|
type Info: record {
|
||||||
|
ts: time &log;
|
||||||
|
uid: string &log;
|
||||||
|
status: count &log &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
############## options ################
|
||||||
|
# right now, I'm just defining an option as
|
||||||
|
# any const with &redef (something that can
|
||||||
|
# change at parse time, but not at run time.
|
||||||
|
|
||||||
|
## add documentation for "an_option" here
|
||||||
|
const an_option: set[addr, addr, string] &redef;
|
||||||
|
|
||||||
|
# default initialization will be self-documenting
|
||||||
|
const option_with_init = 0.01 secs &redef; ##< More docs can be added here.
|
||||||
|
|
||||||
|
############## state variables ############
|
||||||
|
# right now, I'm defining this as any global
|
||||||
|
# that's not a function/event. doesn't matter
|
||||||
|
# if &redef attribute is present
|
||||||
|
|
||||||
|
## put some documentation for "a_var" here
|
||||||
|
global a_var: bool;
|
||||||
|
|
||||||
|
# attributes are self-documenting
|
||||||
|
global var_with_attr: count &persistent;
|
||||||
|
|
||||||
|
# it's fine if the type is inferred, that information is self-documenting
|
||||||
|
global var_without_explicit_type = "this works";
|
||||||
|
|
||||||
|
############## functions/events ############
|
||||||
|
|
||||||
|
## Summarize purpose of "a_function" here.
|
||||||
|
## Give more details about "a_function" here.
|
||||||
|
## Separating the documentation of the params/return values with
|
||||||
|
## empty comments is optional, but improves readability of script.
|
||||||
|
##
|
||||||
|
## tag: function arguments can be described
|
||||||
|
## like this
|
||||||
|
## msg: another param
|
||||||
|
##
|
||||||
|
## Returns: describe the return type here
|
||||||
|
global a_function: function(tag: string, msg: string): string;
|
||||||
|
|
||||||
|
## Summarize "an_event" here.
|
||||||
|
## Give more details about "an_event" here.
|
||||||
|
## Example::an_event should not be confused as a parameter.
|
||||||
|
## name: describe the argument here
|
||||||
|
global an_event: event(name: string);
|
||||||
|
|
||||||
|
## This is a declaration of an example event that can be used in
|
||||||
|
## logging streams and is raised once for each log entry.
|
||||||
|
global log_example: event(rec: Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter_func(rec: Info): bool
|
||||||
|
{
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
# this function is documented in the "private interface" section
|
||||||
|
# of generated documentation and any "##"-stylized comments would also
|
||||||
|
# be rendered there
|
||||||
|
function function_without_proto(tag: string): string
|
||||||
|
{
|
||||||
|
return "blah";
|
||||||
|
}
|
||||||
|
|
||||||
|
# this record type is documented in the "private interface" section
|
||||||
|
# of generated documentation and any "##"-stylized comments would also
|
||||||
|
# be rendered there
|
||||||
|
type PrivateRecord: record {
|
||||||
|
field1: bool;
|
||||||
|
field2: count;
|
||||||
|
};
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
Log::create_stream(Example::LOG, [$columns=Info, $ev=log_example]);
|
||||||
|
Log::add_filter(Example::LOG, [
|
||||||
|
$name="example-filter",
|
||||||
|
$path="example-filter",
|
||||||
|
$pred=filter_func,
|
||||||
|
$exclude=set("ts")
|
||||||
|
]);
|
||||||
|
}
|
291
doc/scripts/example.rst
Normal file
291
doc/scripts/example.rst
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
.. Automatically generated. Do not edit.
|
||||||
|
|
||||||
|
example.bro
|
||||||
|
===========
|
||||||
|
|
||||||
|
:download:`Original Source File <example.bro>`
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
This is an example script that demonstrates how to document. Comments
|
||||||
|
of the form ``##!`` are for the script summary. The contents of
|
||||||
|
these comments are transferred directly into the auto-generated
|
||||||
|
`reStructuredText <http://docutils.sourceforge.net/rst.html>`_
|
||||||
|
(reST) document's summary section.
|
||||||
|
|
||||||
|
.. tip:: You can embed directives and roles within ``##``-stylized comments.
|
||||||
|
|
||||||
|
:Imports: :doc:`policy/frameworks/software/vulnerable </scripts/policy/frameworks/software/vulnerable>`
|
||||||
|
|
||||||
|
Summary
|
||||||
|
~~~~~~~
|
||||||
|
Options
|
||||||
|
#######
|
||||||
|
============================================================================ ======================================
|
||||||
|
:bro:id:`Example::an_option`: :bro:type:`set` :bro:attr:`&redef` add documentation for "an_option" here
|
||||||
|
|
||||||
|
:bro:id:`Example::option_with_init`: :bro:type:`interval` :bro:attr:`&redef`
|
||||||
|
============================================================================ ======================================
|
||||||
|
|
||||||
|
State Variables
|
||||||
|
###############
|
||||||
|
=========================================================================== =======================================
|
||||||
|
:bro:id:`Example::a_var`: :bro:type:`bool` put some documentation for "a_var" here
|
||||||
|
|
||||||
|
:bro:id:`Example::var_with_attr`: :bro:type:`count` :bro:attr:`&persistent`
|
||||||
|
|
||||||
|
:bro:id:`Example::var_without_explicit_type`: :bro:type:`string`
|
||||||
|
=========================================================================== =======================================
|
||||||
|
|
||||||
|
Types
|
||||||
|
#####
|
||||||
|
====================================================== ==========================================================
|
||||||
|
:bro:type:`Example::SimpleEnum`: :bro:type:`enum` documentation for "SimpleEnum"
|
||||||
|
goes here.
|
||||||
|
|
||||||
|
:bro:type:`Example::SimpleRecord`: :bro:type:`record` general documentation for a type "SimpleRecord"
|
||||||
|
goes here.
|
||||||
|
|
||||||
|
:bro:type:`Example::ComplexRecord`: :bro:type:`record` general documentation for a type "ComplexRecord" goes here
|
||||||
|
|
||||||
|
:bro:type:`Example::Info`: :bro:type:`record` An example record to be used with a logging stream.
|
||||||
|
====================================================== ==========================================================
|
||||||
|
|
||||||
|
Events
|
||||||
|
######
|
||||||
|
================================================= =============================================================
|
||||||
|
:bro:id:`Example::an_event`: :bro:type:`event` Summarize "an_event" here.
|
||||||
|
|
||||||
|
:bro:id:`Example::log_example`: :bro:type:`event` This is a declaration of an example event that can be used in
|
||||||
|
logging streams and is raised once for each log entry.
|
||||||
|
================================================= =============================================================
|
||||||
|
|
||||||
|
Functions
|
||||||
|
#########
|
||||||
|
=============================================== =======================================
|
||||||
|
:bro:id:`Example::a_function`: :bro:type:`func` Summarize purpose of "a_function" here.
|
||||||
|
=============================================== =======================================
|
||||||
|
|
||||||
|
Redefinitions
|
||||||
|
#############
|
||||||
|
===================================================== ========================================
|
||||||
|
:bro:type:`Log::ID`: :bro:type:`enum`
|
||||||
|
|
||||||
|
:bro:type:`Example::SimpleEnum`: :bro:type:`enum` document the "SimpleEnum" redef here
|
||||||
|
|
||||||
|
:bro:type:`Example::SimpleRecord`: :bro:type:`record` document the record extension redef here
|
||||||
|
===================================================== ========================================
|
||||||
|
|
||||||
|
Namespaces
|
||||||
|
~~~~~~~~~~
|
||||||
|
.. bro:namespace:: Example
|
||||||
|
|
||||||
|
Notices
|
||||||
|
~~~~~~~
|
||||||
|
:bro:type:`Notice::Type`
|
||||||
|
|
||||||
|
:Type: :bro:type:`enum`
|
||||||
|
|
||||||
|
.. bro:enum:: Example::Notice_One Notice::Type
|
||||||
|
|
||||||
|
any number of this type of comment
|
||||||
|
will document "Notice_One"
|
||||||
|
|
||||||
|
.. bro:enum:: Example::Notice_Two Notice::Type
|
||||||
|
|
||||||
|
any number of this type of comment
|
||||||
|
will document "Notice_Two"
|
||||||
|
|
||||||
|
.. bro:enum:: Example::Notice_Three Notice::Type
|
||||||
|
|
||||||
|
.. bro:enum:: Example::Notice_Four Notice::Type
|
||||||
|
|
||||||
|
Public Interface
|
||||||
|
----------------
|
||||||
|
Options
|
||||||
|
~~~~~~~
|
||||||
|
.. bro:id:: Example::an_option
|
||||||
|
|
||||||
|
:Type: :bro:type:`set` [:bro:type:`addr`, :bro:type:`addr`, :bro:type:`string`]
|
||||||
|
:Attributes: :bro:attr:`&redef`
|
||||||
|
:Default: ``{}``
|
||||||
|
|
||||||
|
add documentation for "an_option" here
|
||||||
|
|
||||||
|
.. bro:id:: Example::option_with_init
|
||||||
|
|
||||||
|
:Type: :bro:type:`interval`
|
||||||
|
:Attributes: :bro:attr:`&redef`
|
||||||
|
:Default: ``10.0 msecs``
|
||||||
|
|
||||||
|
State Variables
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
.. bro:id:: Example::a_var
|
||||||
|
|
||||||
|
:Type: :bro:type:`bool`
|
||||||
|
|
||||||
|
put some documentation for "a_var" here
|
||||||
|
|
||||||
|
.. bro:id:: Example::var_with_attr
|
||||||
|
|
||||||
|
:Type: :bro:type:`count`
|
||||||
|
:Attributes: :bro:attr:`&persistent`
|
||||||
|
|
||||||
|
.. bro:id:: Example::var_without_explicit_type
|
||||||
|
|
||||||
|
:Type: :bro:type:`string`
|
||||||
|
:Default: ``"this works"``
|
||||||
|
|
||||||
|
Types
|
||||||
|
~~~~~
|
||||||
|
.. bro:type:: Example::SimpleEnum
|
||||||
|
|
||||||
|
:Type: :bro:type:`enum`
|
||||||
|
|
||||||
|
.. bro:enum:: Example::ONE Example::SimpleEnum
|
||||||
|
|
||||||
|
and more specific info for "ONE"
|
||||||
|
can span multiple lines
|
||||||
|
|
||||||
|
.. bro:enum:: Example::TWO Example::SimpleEnum
|
||||||
|
|
||||||
|
or more info like this for "TWO"
|
||||||
|
can span multiple lines
|
||||||
|
|
||||||
|
.. bro:enum:: Example::THREE Example::SimpleEnum
|
||||||
|
|
||||||
|
documentation for "SimpleEnum"
|
||||||
|
goes here.
|
||||||
|
|
||||||
|
.. bro:type:: Example::SimpleRecord
|
||||||
|
|
||||||
|
:Type: :bro:type:`record`
|
||||||
|
|
||||||
|
field1: :bro:type:`count`
|
||||||
|
counts something
|
||||||
|
|
||||||
|
field2: :bro:type:`bool`
|
||||||
|
toggles something
|
||||||
|
|
||||||
|
general documentation for a type "SimpleRecord"
|
||||||
|
goes here.
|
||||||
|
|
||||||
|
.. bro:type:: Example::ComplexRecord
|
||||||
|
|
||||||
|
:Type: :bro:type:`record`
|
||||||
|
|
||||||
|
field1: :bro:type:`count`
|
||||||
|
counts something
|
||||||
|
|
||||||
|
field2: :bro:type:`bool`
|
||||||
|
toggles something
|
||||||
|
|
||||||
|
field3: :bro:type:`Example::SimpleRecord`
|
||||||
|
|
||||||
|
msg: :bro:type:`string` :bro:attr:`&default` = ``"blah"`` :bro:attr:`&optional`
|
||||||
|
attributes are self-documenting
|
||||||
|
|
||||||
|
general documentation for a type "ComplexRecord" goes here
|
||||||
|
|
||||||
|
.. bro:type:: Example::Info
|
||||||
|
|
||||||
|
:Type: :bro:type:`record`
|
||||||
|
|
||||||
|
ts: :bro:type:`time` :bro:attr:`&log`
|
||||||
|
|
||||||
|
uid: :bro:type:`string` :bro:attr:`&log`
|
||||||
|
|
||||||
|
status: :bro:type:`count` :bro:attr:`&log` :bro:attr:`&optional`
|
||||||
|
|
||||||
|
An example record to be used with a logging stream.
|
||||||
|
|
||||||
|
Events
|
||||||
|
~~~~~~
|
||||||
|
.. bro:id:: Example::an_event
|
||||||
|
|
||||||
|
:Type: :bro:type:`event` (name: :bro:type:`string`)
|
||||||
|
|
||||||
|
Summarize "an_event" here.
|
||||||
|
Give more details about "an_event" here.
|
||||||
|
|
||||||
|
:param name: describe the argument here
|
||||||
|
|
||||||
|
.. bro:id:: Example::log_example
|
||||||
|
|
||||||
|
:Type: :bro:type:`event` (rec: :bro:type:`Example::Info`)
|
||||||
|
|
||||||
|
This is a declaration of an example event that can be used in
|
||||||
|
logging streams and is raised once for each log entry.
|
||||||
|
|
||||||
|
Functions
|
||||||
|
~~~~~~~~~
|
||||||
|
.. bro:id:: Example::a_function
|
||||||
|
|
||||||
|
:Type: :bro:type:`function` (tag: :bro:type:`string`, msg: :bro:type:`string`) : :bro:type:`string`
|
||||||
|
|
||||||
|
Summarize purpose of "a_function" here.
|
||||||
|
Give more details about "a_function" here.
|
||||||
|
Separating the documentation of the params/return values with
|
||||||
|
empty comments is optional, but improves readability of script.
|
||||||
|
|
||||||
|
|
||||||
|
:param tag: function arguments can be described
|
||||||
|
like this
|
||||||
|
|
||||||
|
:param msg: another param
|
||||||
|
|
||||||
|
|
||||||
|
:returns: describe the return type here
|
||||||
|
|
||||||
|
Redefinitions
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
:bro:type:`Log::ID`
|
||||||
|
|
||||||
|
:Type: :bro:type:`enum`
|
||||||
|
|
||||||
|
.. bro:enum:: Example::LOG Log::ID
|
||||||
|
|
||||||
|
:bro:type:`Example::SimpleEnum`
|
||||||
|
|
||||||
|
:Type: :bro:type:`enum`
|
||||||
|
|
||||||
|
.. bro:enum:: Example::FOUR Example::SimpleEnum
|
||||||
|
|
||||||
|
and some documentation for "FOUR"
|
||||||
|
|
||||||
|
.. bro:enum:: Example::FIVE Example::SimpleEnum
|
||||||
|
|
||||||
|
also "FIVE" for good measure
|
||||||
|
|
||||||
|
document the "SimpleEnum" redef here
|
||||||
|
|
||||||
|
:bro:type:`Example::SimpleRecord`
|
||||||
|
|
||||||
|
:Type: :bro:type:`record`
|
||||||
|
|
||||||
|
field_ext: :bro:type:`string` :bro:attr:`&optional`
|
||||||
|
document the extending field here
|
||||||
|
(or here)
|
||||||
|
|
||||||
|
document the record extension redef here
|
||||||
|
|
||||||
|
Port Analysis
|
||||||
|
-------------
|
||||||
|
:ref:`More Information <common_port_analysis_doc>`
|
||||||
|
|
||||||
|
SSL::
|
||||||
|
|
||||||
|
[ports={
|
||||||
|
443/tcp,
|
||||||
|
562/tcp
|
||||||
|
}]
|
||||||
|
|
||||||
|
Packet Filter
|
||||||
|
-------------
|
||||||
|
:ref:`More Information <common_packet_filter_doc>`
|
||||||
|
|
||||||
|
Filters added::
|
||||||
|
|
||||||
|
[ssl] = tcp port 443,
|
||||||
|
[nntps] = tcp port 562
|
||||||
|
|
86
doc/scripts/genDocSourcesList.sh
Executable file
86
doc/scripts/genDocSourcesList.sh
Executable file
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# ./genDocSourcesList.sh [output file]
|
||||||
|
#
|
||||||
|
# Run this script to a generate file that's used to tell CMake about all the
|
||||||
|
# possible scripts for which reST documentation can be created.
|
||||||
|
#
|
||||||
|
# The optional argument can be used to avoid overwriting the file CMake uses
|
||||||
|
# by default.
|
||||||
|
#
|
||||||
|
# Specific scripts can be blacklisted below when e.g. they currently aren't
|
||||||
|
# parseable or they just aren't meant to be documented.
|
||||||
|
|
||||||
|
export LC_ALL=C # Make sorting stable.
|
||||||
|
|
||||||
|
blacklist ()
|
||||||
|
{
|
||||||
|
if [[ "$blacklist" == "" ]]; then
|
||||||
|
blacklist="$1"
|
||||||
|
else
|
||||||
|
blacklist="$blacklist|$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# files passed into this function are meant to be temporary workarounds
|
||||||
|
# because they're not finished or otherwise can't be loaded for some reason
|
||||||
|
tmp_blacklist ()
|
||||||
|
{
|
||||||
|
echo "Warning: temporarily blacklisted files named '$1'" 1>&2
|
||||||
|
blacklist $1
|
||||||
|
}
|
||||||
|
|
||||||
|
blacklist __load__.bro
|
||||||
|
blacklist test-all.bro
|
||||||
|
blacklist all.bro
|
||||||
|
blacklist init-default.bro
|
||||||
|
blacklist init-bare.bro
|
||||||
|
|
||||||
|
statictext="\
|
||||||
|
# DO NOT EDIT
|
||||||
|
# This file is auto-generated from the "genDocSourcesList.sh" script.
|
||||||
|
#
|
||||||
|
# This is a list of Bro script sources for which to generate reST documentation.
|
||||||
|
# It will be included inline in the CMakeLists.txt found in the same directory
|
||||||
|
# in order to create Makefile targets that define how to generate reST from
|
||||||
|
# a given Bro script.
|
||||||
|
#
|
||||||
|
# Note: any path prefix of the script (2nd argument of rest_target macro)
|
||||||
|
# will be used to derive what path under scripts/ the generated documentation
|
||||||
|
# will be placed.
|
||||||
|
|
||||||
|
set(psd \${PROJECT_SOURCE_DIR}/scripts)
|
||||||
|
|
||||||
|
rest_target(\${CMAKE_CURRENT_SOURCE_DIR} example.bro internal)
|
||||||
|
rest_target(\${psd} base/init-default.bro internal)
|
||||||
|
rest_target(\${psd} base/init-bare.bro internal)
|
||||||
|
"
|
||||||
|
|
||||||
|
if [[ $# -ge 1 ]]; then
|
||||||
|
outfile=$1
|
||||||
|
else
|
||||||
|
outfile=DocSourcesList.cmake
|
||||||
|
fi
|
||||||
|
|
||||||
|
thisdir="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
sourcedir=${thisdir}/../..
|
||||||
|
|
||||||
|
echo "$statictext" > $outfile
|
||||||
|
|
||||||
|
bifs=`( cd ${sourcedir}/src && find . -name \*\.bif | sort )`
|
||||||
|
|
||||||
|
for file in $bifs
|
||||||
|
do
|
||||||
|
f=${file:2}.bro
|
||||||
|
echo "rest_target(\${CMAKE_BINARY_DIR}/src base/$f)" >> $outfile
|
||||||
|
done
|
||||||
|
|
||||||
|
scriptfiles=`( cd ${sourcedir}/scripts && find . -name \*\.bro | sort )`
|
||||||
|
|
||||||
|
for file in $scriptfiles
|
||||||
|
do
|
||||||
|
f=${file:2}
|
||||||
|
if [[ ! $f =~ $blacklist ]]; then
|
||||||
|
echo "rest_target(\${psd} $f)" >> $outfile
|
||||||
|
fi
|
||||||
|
done
|
8
doc/scripts/index.rst
Normal file
8
doc/scripts/index.rst
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.. This is a stub doc to which broxygen appends during the build process
|
||||||
|
|
||||||
|
Index of All Individual Bro Scripts
|
||||||
|
===================================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
5
doc/scripts/internal.rst
Normal file
5
doc/scripts/internal.rst
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.. This is a stub doc to which broxygen appends during the build process
|
||||||
|
|
||||||
|
Internal Scripts
|
||||||
|
================
|
||||||
|
|
12
doc/scripts/packages.rst
Normal file
12
doc/scripts/packages.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.. This is a stub doc to which broxygen appends during the build process
|
||||||
|
|
||||||
|
Index of All Bro Script Packages
|
||||||
|
================================
|
||||||
|
|
||||||
|
Bro has the following script packages (e.g. collections of related scripts in
|
||||||
|
a common directory). If the package directory contains a ``__load__.bro``
|
||||||
|
script, it supports being loaded in mass as a whole directory for convenience.
|
||||||
|
|
||||||
|
Packages/scripts in the ``base/`` directory are all loaded by default, while
|
||||||
|
ones in ``policy/`` provide functionality and customization options that are
|
||||||
|
more appropriate for users to decide whether they'd like to load it or not.
|
390
doc/signatures.rst
Normal file
390
doc/signatures.rst
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
|
||||||
|
==========
|
||||||
|
Signatures
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
Bro relies primarily on its extensive scripting language for
|
||||||
|
defining and analyzing detection policies. In addition, however,
|
||||||
|
Bro also provides an independent *signature language* for doing
|
||||||
|
low-level, Snort-style pattern matching. While signatures are
|
||||||
|
*not* Bro's preferred detection tool, they sometimes come in handy
|
||||||
|
and are closer to what many people are familiar with from using
|
||||||
|
other NIDS. This page gives a brief overview on Bro's signatures
|
||||||
|
and covers some of their technical subtleties.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:depth: 2
|
||||||
|
|
||||||
|
Basics
|
||||||
|
======
|
||||||
|
|
||||||
|
Let's look at an example signature first:
|
||||||
|
|
||||||
|
.. code:: bro-sig
|
||||||
|
|
||||||
|
signature my-first-sig {
|
||||||
|
ip-proto == tcp
|
||||||
|
dst-port == 80
|
||||||
|
payload /.*root/
|
||||||
|
event "Found root!"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
This signature asks Bro to match the regular expression ``.*root`` on
|
||||||
|
all TCP connections going to port 80. When the signature triggers, Bro
|
||||||
|
will raise an event :bro:id:`signature_match` of the form:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event signature_match(state: signature_state, msg: string, data: string)
|
||||||
|
|
||||||
|
Here, ``state`` contains more information on the connection that
|
||||||
|
triggered the match, ``msg`` is the string specified by the
|
||||||
|
signature's event statement (``Found root!``), and data is the last
|
||||||
|
piece of payload which triggered the pattern match.
|
||||||
|
|
||||||
|
To turn such :bro:id:`signature_match` events into actual alarms, you can
|
||||||
|
load Bro's :doc:`/scripts/base/frameworks/signatures/main` script.
|
||||||
|
This script contains a default event handler that raises
|
||||||
|
:bro:enum:`Signatures::Sensitive_Signature` :doc:`Notices <notice>`
|
||||||
|
(as well as others; see the beginning of the script).
|
||||||
|
|
||||||
|
As signatures are independent of Bro's policy scripts, they are put
|
||||||
|
into their own file(s). There are two ways to specify which files
|
||||||
|
contain signatures: By using the ``-s`` flag when you invoke Bro, or
|
||||||
|
by extending the Bro variable :bro:id:`signature_files` using the ``+=``
|
||||||
|
operator. If a signature file is given without a path, it is searched
|
||||||
|
along the normal ``BROPATH``. The default extension of the file name
|
||||||
|
is ``.sig``, and Bro appends that automatically when necessary.
|
||||||
|
|
||||||
|
Signature language
|
||||||
|
==================
|
||||||
|
|
||||||
|
Let's look at the format of a signature more closely. Each individual
|
||||||
|
signature has the format ``signature <id> { <attributes> }``. ``<id>``
|
||||||
|
is a unique label for the signature. There are two types of
|
||||||
|
attributes: *conditions* and *actions*. The conditions define when the
|
||||||
|
signature matches, while the actions declare what to do in the case of
|
||||||
|
a match. Conditions can be further divided into four types: *header*,
|
||||||
|
*content*, *dependency*, and *context*. We discuss these all in more
|
||||||
|
detail in the following.
|
||||||
|
|
||||||
|
Conditions
|
||||||
|
----------
|
||||||
|
|
||||||
|
Header Conditions
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Header conditions limit the applicability of the signature to a subset
|
||||||
|
of traffic that contains matching packet headers. For TCP, this match
|
||||||
|
is performed only for the first packet of a connection. For other
|
||||||
|
protocols, it is done on each individual packet.
|
||||||
|
|
||||||
|
There are pre-defined header conditions for some of the most used
|
||||||
|
header fields. All of them generally have the format ``<keyword> <cmp>
|
||||||
|
<value-list>``, where ``<keyword>`` names the header field; ``cmp`` is
|
||||||
|
one of ``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``; and
|
||||||
|
``<value-list>`` is a list of comma-separated values to compare
|
||||||
|
against. The following keywords are defined:
|
||||||
|
|
||||||
|
``src-ip``/``dst-ip <cmp> <address-list>``
|
||||||
|
Source and destination address, respectively. Addresses can be
|
||||||
|
given as IP addresses or CIDR masks.
|
||||||
|
|
||||||
|
``src-port``/``dst-port`` ``<int-list>``
|
||||||
|
Source and destination port, respectively.
|
||||||
|
|
||||||
|
``ip-proto tcp|udp|icmp``
|
||||||
|
IP protocol.
|
||||||
|
|
||||||
|
For lists of multiple values, they are sequentially compared against
|
||||||
|
the corresponding header field. If at least one of the comparisons
|
||||||
|
evaluates to true, the whole header condition matches (exception: with
|
||||||
|
``!=``, the header condition only matches if all values differ).
|
||||||
|
|
||||||
|
In addition to these pre-defined header keywords, a general header
|
||||||
|
condition can be defined either as
|
||||||
|
|
||||||
|
.. code:: bro-sig
|
||||||
|
|
||||||
|
header <proto>[<offset>:<size>] [& <integer>] <cmp> <value-list>
|
||||||
|
|
||||||
|
This compares the value found at the given position of the packet
|
||||||
|
header with a list of values. ``offset`` defines the position of the
|
||||||
|
value within the header of the protocol defined by ``proto`` (which
|
||||||
|
can be ``ip``, ``tcp``, ``udp`` or ``icmp``). ``size`` is either 1, 2,
|
||||||
|
or 4 and specifies the value to have a size of this many bytes. If the
|
||||||
|
optional ``& <integer>`` is given, the packet's value is first masked
|
||||||
|
with the integer before it is compared to the value-list. ``cmp`` is
|
||||||
|
one of ``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``. ``value-list`` is
|
||||||
|
a list of comma-separated integers similar to those described above.
|
||||||
|
The integers within the list may be followed by an additional ``/
|
||||||
|
mask`` where ``mask`` is a value from 0 to 32. This corresponds to the
|
||||||
|
CIDR notation for netmasks and is translated into a corresponding
|
||||||
|
bitmask applied to the packet's value prior to the comparison (similar
|
||||||
|
to the optional ``& integer``).
|
||||||
|
|
||||||
|
Putting it all together, this is an example condition that is
|
||||||
|
equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``:
|
||||||
|
|
||||||
|
.. code:: bro-sig
|
||||||
|
|
||||||
|
header ip[16:4] == 1.2.3.4/16, 5.6.7.8/24
|
||||||
|
|
||||||
|
Internally, the predefined header conditions are in fact just
|
||||||
|
short-cuts and mapped into a generic condition.
|
||||||
|
|
||||||
|
Content Conditions
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Content conditions are defined by regular expressions. We
|
||||||
|
differentiate two kinds of content conditions: first, the expression
|
||||||
|
may be declared with the ``payload`` statement, in which case it is
|
||||||
|
matched against the raw payload of a connection (for reassembled TCP
|
||||||
|
streams) or of each packet (for ICMP, UDP, and non-reassembled TCP).
|
||||||
|
Second, it may be prefixed with an analyzer-specific label, in which
|
||||||
|
case the expression is matched against the data as extracted by the
|
||||||
|
corresponding analyzer.
|
||||||
|
|
||||||
|
A ``payload`` condition has the form:
|
||||||
|
|
||||||
|
.. code:: bro-sig
|
||||||
|
|
||||||
|
payload /<regular expression>/
|
||||||
|
|
||||||
|
Currently, the following analyzer-specific content conditions are
|
||||||
|
defined (note that the corresponding analyzer has to be activated by
|
||||||
|
loading its policy script):
|
||||||
|
|
||||||
|
``http-request /<regular expression>/``
|
||||||
|
The regular expression is matched against decoded URIs of HTTP
|
||||||
|
requests. Obsolete alias: ``http``.
|
||||||
|
|
||||||
|
``http-request-header /<regular expression>/``
|
||||||
|
The regular expression is matched against client-side HTTP headers.
|
||||||
|
|
||||||
|
``http-request-body /<regular expression>/``
|
||||||
|
The regular expression is matched against client-side bodys of
|
||||||
|
HTTP requests.
|
||||||
|
|
||||||
|
``http-reply-header /<regular expression>/``
|
||||||
|
The regular expression is matched against server-side HTTP headers.
|
||||||
|
|
||||||
|
``http-reply-body /<regular expression>/``
|
||||||
|
The regular expression is matched against server-side bodys of
|
||||||
|
HTTP replys.
|
||||||
|
|
||||||
|
``ftp /<regular expression>/``
|
||||||
|
The regular expression is matched against the command line input
|
||||||
|
of FTP sessions.
|
||||||
|
|
||||||
|
``finger /<regular expression>/``
|
||||||
|
The regular expression is matched against finger requests.
|
||||||
|
|
||||||
|
For example, ``http-request /.*(etc/(passwd|shadow)/`` matches any URI
|
||||||
|
containing either ``etc/passwd`` or ``etc/shadow``. To filter on request
|
||||||
|
types, e.g. ``GET``, use ``payload /GET /``.
|
||||||
|
|
||||||
|
Note that HTTP pipelining (that is, multiple HTTP transactions in a
|
||||||
|
single TCP connection) has some side effects on signature matches. If
|
||||||
|
multiple conditions are specified within a single signature, this
|
||||||
|
signature matches if all conditions are met by any HTTP transaction
|
||||||
|
(not necessarily always the same!) in a pipelined connection.
|
||||||
|
|
||||||
|
Dependency Conditions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To define dependencies between signatures, there are two conditions:
|
||||||
|
|
||||||
|
|
||||||
|
``requires-signature [!] <id>``
|
||||||
|
Defines the current signature to match only if the signature given
|
||||||
|
by ``id`` matches for the same connection. Using ``!`` negates the
|
||||||
|
condition: The current signature only matches if ``id`` does not
|
||||||
|
match for the same connection (using this defers the match
|
||||||
|
decision until the connection terminates).
|
||||||
|
|
||||||
|
``requires-reverse-signature [!] <id>``
|
||||||
|
Similar to ``requires-signature``, but ``id`` has to match for the
|
||||||
|
opposite direction of the same connection, compared to the current
|
||||||
|
signature. This allows to model the notion of requests and
|
||||||
|
replies.
|
||||||
|
|
||||||
|
Context Conditions
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Context conditions pass the match decision on to other components of
|
||||||
|
Bro. They are only evaluated if all other conditions have already
|
||||||
|
matched. The following context conditions are defined:
|
||||||
|
|
||||||
|
``eval <policy-function>``
|
||||||
|
The given policy function is called and has to return a boolean
|
||||||
|
confirming the match. If false is returned, no signature match is
|
||||||
|
going to be triggered. The function has to be of type ``function
|
||||||
|
cond(state: signature_state, data: string): bool``. Here,
|
||||||
|
``content`` may contain the most recent content chunk available at
|
||||||
|
the time the signature was matched. If no such chunk is available,
|
||||||
|
``content`` will be the empty string. ``signature_state`` is
|
||||||
|
defined as follows:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
type signature_state: record {
|
||||||
|
id: string; # ID of the signature
|
||||||
|
conn: connection; # Current connection
|
||||||
|
is_orig: bool; # True if current endpoint is originator
|
||||||
|
payload_size: count; # Payload size of the first packet
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
``payload-size <cmp> <integer>``
|
||||||
|
Compares the integer to the size of the payload of a packet. For
|
||||||
|
reassembled TCP streams, the integer is compared to the size of
|
||||||
|
the first in-order payload chunk. Note that the latter is not very
|
||||||
|
well defined.
|
||||||
|
|
||||||
|
``same-ip``
|
||||||
|
Evaluates to true if the source address of the IP packets equals
|
||||||
|
its destination address.
|
||||||
|
|
||||||
|
``tcp-state <state-list>``
|
||||||
|
Imposes restrictions on the current TCP state of the connection.
|
||||||
|
``state-list`` is a comma-separated list of the keywords
|
||||||
|
``established`` (the three-way handshake has already been
|
||||||
|
performed), ``originator`` (the current data is send by the
|
||||||
|
originator of the connection), and ``responder`` (the current data
|
||||||
|
is send by the responder of the connection).
|
||||||
|
|
||||||
|
|
||||||
|
Actions
|
||||||
|
-------
|
||||||
|
|
||||||
|
Actions define what to do if a signature matches. Currently, there are
|
||||||
|
two actions defined:
|
||||||
|
|
||||||
|
``event <string>``
|
||||||
|
Raises a :bro:id:`signature_match` event. The event handler has the
|
||||||
|
following type:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event signature_match(state: signature_state, msg: string, data: string)
|
||||||
|
|
||||||
|
The given string is passed in as ``msg``, and data is the current
|
||||||
|
part of the payload that has eventually lead to the signature
|
||||||
|
match (this may be empty for signatures without content
|
||||||
|
conditions).
|
||||||
|
|
||||||
|
``enable <string>``
|
||||||
|
Enables the protocol analyzer ``<string>`` for the matching
|
||||||
|
connection (``"http"``, ``"ftp"``, etc.). This is used by Bro's
|
||||||
|
dynamic protocol detection to activate analyzers on the fly.
|
||||||
|
|
||||||
|
Things to keep in mind when writing signatures
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
* Each signature is reported at most once for every connection,
|
||||||
|
further matches of the same signature are ignored.
|
||||||
|
|
||||||
|
* The content conditions perform pattern matching on elements
|
||||||
|
extracted from an application protocol dialogue. For example, ``http
|
||||||
|
/.*passwd/`` scans URLs requested within HTTP sessions. The thing to
|
||||||
|
keep in mind here is that these conditions only perform any matching
|
||||||
|
when the corresponding application analyzer is actually *active* for
|
||||||
|
a connection. Note that by default, analyzers are not enabled if the
|
||||||
|
corresponding Bro script has not been loaded. A good way to
|
||||||
|
double-check whether an analyzer "sees" a connection is checking its
|
||||||
|
log file for corresponding entries. If you cannot find the
|
||||||
|
connection in the analyzer's log, very likely the signature engine
|
||||||
|
has also not seen any application data.
|
||||||
|
|
||||||
|
* As the name indicates, the ``payload`` keyword matches on packet
|
||||||
|
*payload* only. You cannot use it to match on packet headers; use
|
||||||
|
the header conditions for that.
|
||||||
|
|
||||||
|
* For TCP connections, header conditions are only evaluated for the
|
||||||
|
*first packet from each endpoint*. If a header condition does not
|
||||||
|
match the initial packets, the signature will not trigger. Bro
|
||||||
|
optimizes for the most common application here, which is header
|
||||||
|
conditions selecting the connections to be examined more closely
|
||||||
|
with payload statements.
|
||||||
|
|
||||||
|
* For UDP and ICMP flows, the payload matching is done on a per-packet
|
||||||
|
basis; i.e., any content crossing packet boundaries will not be
|
||||||
|
found. For TCP connections, the matching semantics depend on whether
|
||||||
|
Bro is *reassembling* the connection (i.e., putting all of a
|
||||||
|
connection's packets in sequence). By default, Bro is reassembling
|
||||||
|
the first 1K of every TCP connection, which means that within this
|
||||||
|
window, matches will be found without regards to packet order or
|
||||||
|
boundaries (i.e., *stream-wise matching*).
|
||||||
|
|
||||||
|
* For performance reasons, by default Bro *stops matching* on a
|
||||||
|
connection after seeing 1K of payload; see the section on options
|
||||||
|
below for how to change this behaviour. The default was chosen with
|
||||||
|
Bro's main user of signatures in mind: dynamic protocol detection
|
||||||
|
works well even when examining just connection heads.
|
||||||
|
|
||||||
|
* Regular expressions are implicitly anchored, i.e., they work as if
|
||||||
|
prefixed with the ``^`` operator. For reassembled TCP connections,
|
||||||
|
they are anchored at the first byte of the payload *stream*. For all
|
||||||
|
other connections, they are anchored at the first payload byte of
|
||||||
|
each packet. To match at arbitrary positions, you can prefix the
|
||||||
|
regular expression with ``.*``, as done in the examples above.
|
||||||
|
|
||||||
|
* To match on non-ASCII characters, Bro's regular expressions support
|
||||||
|
the ``\x<hex>`` operator. CRs/LFs are not treated specially by the
|
||||||
|
signature engine and can be matched with ``\r`` and ``\n``,
|
||||||
|
respectively. Generally, Bro follows `flex's regular expression
|
||||||
|
syntax
|
||||||
|
<http://flex.sourceforge.net/manual/Patterns.html>`_.
|
||||||
|
See the DPD signatures in ``base/frameworks/dpd/dpd.sig`` for some examples
|
||||||
|
of fairly complex payload patterns.
|
||||||
|
|
||||||
|
* The data argument of the :bro:id:`signature_match` handler might not carry
|
||||||
|
the full text matched by the regular expression. Bro performs the
|
||||||
|
matching incrementally as packets come in; when the signature
|
||||||
|
eventually fires, it can only pass on the most recent chunk of data.
|
||||||
|
|
||||||
|
|
||||||
|
Options
|
||||||
|
=======
|
||||||
|
|
||||||
|
The following options control details of Bro's matching process:
|
||||||
|
|
||||||
|
``dpd_reassemble_first_packets: bool`` (default: ``T``)
|
||||||
|
If true, Bro reassembles the beginning of every TCP connection (of
|
||||||
|
up to ``dpd_buffer_size`` bytes, see below), to facilitate
|
||||||
|
reliable matching across packet boundaries. If false, only
|
||||||
|
connections are reassembled for which an application-layer
|
||||||
|
analyzer gets activated (e.g., by Bro's dynamic protocol
|
||||||
|
detection).
|
||||||
|
|
||||||
|
``dpd_match_only_beginning : bool`` (default: ``T``)
|
||||||
|
If true, Bro performs packet matching only within the initial
|
||||||
|
payload window of ``dpd_buffer_size``. If false, it keeps matching
|
||||||
|
on subsequent payload as well.
|
||||||
|
|
||||||
|
``dpd_buffer_size: count`` (default: ``1024``)
|
||||||
|
Defines the buffer size for the two preceding options. In
|
||||||
|
addition, this value determines the amount of bytes Bro buffers
|
||||||
|
for each connection in order to activate application analyzers
|
||||||
|
even after parts of the payload have already passed through. This
|
||||||
|
is needed by the dynamic protocol detection capability to defer
|
||||||
|
the decision which analyzers to use.
|
||||||
|
|
||||||
|
|
||||||
|
So, how about using Snort signatures with Bro?
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
There was once a script, ``snort2bro``, that converted Snort
|
||||||
|
signatures automatically into Bro's signature syntax. However, in our
|
||||||
|
experience this didn't turn out to be a very useful thing to do
|
||||||
|
because by simply using Snort signatures, one can't benefit from the
|
||||||
|
additional capabilities that Bro provides; the approaches of the two
|
||||||
|
systems are just too different. We therefore stopped maintaining the
|
||||||
|
``snort2bro`` script, and there are now many newer Snort options which
|
||||||
|
it doesn't support. The script is now no longer part of the Bro
|
||||||
|
distribution.
|
||||||
|
|
247
doc/upgrade.rst
Normal file
247
doc/upgrade.rst
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
|
||||||
|
=============================
|
||||||
|
Upgrading From Bro 1.5 to 2.0
|
||||||
|
=============================
|
||||||
|
|
||||||
|
.. rst-class:: opening
|
||||||
|
|
||||||
|
This guide details differences between Bro versions 1.5 and 2.0
|
||||||
|
that may be important for users to know as they work on updating
|
||||||
|
their Bro deployment/configuration to the later version.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
As the version number jump suggests, Bro 2.0 is a major upgrade and
|
||||||
|
lots of things have changed. Most importantly, we have rewritten
|
||||||
|
almost all of Bro's default scripts from scratch, using quite
|
||||||
|
different structure now and focusing more on operational deployment.
|
||||||
|
The result is a system that works much better "out of the box", even
|
||||||
|
without much initial site-specific configuration. The down-side is
|
||||||
|
that 1.x configurations will need to be adapted to work with the new
|
||||||
|
version. The two rules of thumb are:
|
||||||
|
|
||||||
|
(1) If you have written your own Bro scripts
|
||||||
|
that do not depend on any of the standard scripts formerly
|
||||||
|
found in ``policy/``, they will most likely just keep working
|
||||||
|
(although you might want to adapt them to use some of the new
|
||||||
|
features, like the new logging framework; see below).
|
||||||
|
|
||||||
|
(2) If you have custom code that depends on specifics of 1.x
|
||||||
|
default scripts (including most configuration tuning), that is
|
||||||
|
unlikely to work with 2.x. We recommend to start by using just
|
||||||
|
the new scripts first, and then port over any customizations
|
||||||
|
incrementally as necessary (they may be much easier to do now,
|
||||||
|
or even unnecessary). Send mail to the Bro user mailing list
|
||||||
|
if you need help.
|
||||||
|
|
||||||
|
Below we summarize changes from 1.x to 2.x in more detail. This list
|
||||||
|
isn't complete, see the :download:`CHANGES <CHANGES>` file in the
|
||||||
|
distribution for the full story.
|
||||||
|
|
||||||
|
Default Scripts
|
||||||
|
===============
|
||||||
|
|
||||||
|
Organization
|
||||||
|
------------
|
||||||
|
|
||||||
|
In versions before 2.0, Bro scripts were all maintained in a flat
|
||||||
|
directory called ``policy/`` in the source tree. This directory is now
|
||||||
|
renamed to ``scripts/`` and contains major subdirectories ``base/``,
|
||||||
|
``policy/``, and ``site/``, each of which may also be subdivided
|
||||||
|
further.
|
||||||
|
|
||||||
|
The contents of the new ``scripts/`` directory, like the old/flat
|
||||||
|
``policy/`` still gets installed under the ``share/bro``
|
||||||
|
subdirectory of the installation prefix path just like previous
|
||||||
|
versions. For example, if Bro was compiled like ``./configure
|
||||||
|
--prefix=/usr/local/bro && make && make install``, then the script
|
||||||
|
hierarchy can be found in ``/usr/local/bro/share/bro``.
|
||||||
|
|
||||||
|
The main
|
||||||
|
subdirectories of that hierarchy are as follows:
|
||||||
|
|
||||||
|
- ``base/`` contains all scripts that are loaded by Bro by default
|
||||||
|
(unless the ``-b`` command line option is used to run Bro in a
|
||||||
|
minimal configuration). Note that is a major conceptual change:
|
||||||
|
rather than not loading anything by default, Bro now uses an
|
||||||
|
extensive set of default scripts out of the box.
|
||||||
|
|
||||||
|
The scripts under this directory generally either accumulate/log
|
||||||
|
useful state/protocol information for monitored traffic, configure a
|
||||||
|
default/recommended mode of operation, or provide extra Bro
|
||||||
|
scripting-layer functionality that has no significant performance cost.
|
||||||
|
|
||||||
|
- ``policy/`` contains all scripts that a user will need to explicitly
|
||||||
|
tell Bro to load. These are scripts that implement
|
||||||
|
functionality/analysis that not all users may want to use and may have
|
||||||
|
more significant performance costs. For a new installation, you
|
||||||
|
should go through these and see what appears useful to load.
|
||||||
|
|
||||||
|
- ``site/`` remains a directory that can be used to store locally
|
||||||
|
developed scripts. It now comes with some preinstalled example
|
||||||
|
scripts that contain recommended default configurations going beyond
|
||||||
|
the ``base/`` setup. E.g. ``local.bro`` loads extra scripts from
|
||||||
|
``policy/`` and does extra tuning. These files can be customized in
|
||||||
|
place without being overwritten by upgrades/reinstalls, unlike
|
||||||
|
scripts in other directories.
|
||||||
|
|
||||||
|
With version 2.0, the default ``BROPATH`` is set to automatically
|
||||||
|
search for scripts in ``policy/``, ``site/`` and their parent
|
||||||
|
directory, but **not** ``base/``. Generally, everything under
|
||||||
|
``base/`` is loaded automatically, but for users of the ``-b`` option,
|
||||||
|
it's important to know that loading a script in that directory
|
||||||
|
requires the extra ``base/`` path qualification. For example, the
|
||||||
|
following two scripts:
|
||||||
|
|
||||||
|
* ``$PREFIX/share/bro/base/protocols/ssl/main.bro``
|
||||||
|
* ``$PREFIX/share/bro/policy/protocols/ssl/validate-certs.bro``
|
||||||
|
|
||||||
|
are referenced from another Bro script like:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
@load base/protocols/ssl/main
|
||||||
|
@load protocols/ssl/validate-certs
|
||||||
|
|
||||||
|
Notice how ``policy/`` can be omitted as a convenience in the second
|
||||||
|
case. ``@load`` can now also use relative path, e.g., ``@load
|
||||||
|
../main``.
|
||||||
|
|
||||||
|
|
||||||
|
Logging Framework
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- The logs generated by scripts that ship with Bro are entirely redone
|
||||||
|
to use a standardized, machine parsable format via the new logging
|
||||||
|
framework. Generally, the log content has been restructured towards
|
||||||
|
making it more directly useful to operations. Also, several
|
||||||
|
analyzers have been significantly extended and thus now log more
|
||||||
|
information. Take a look at ``ssl.log``.
|
||||||
|
|
||||||
|
* A particular format change that may be useful to note is that the
|
||||||
|
``conn.log`` ``service`` field is derived from DPD instead of
|
||||||
|
well-known ports (while that was already possible in 1.5, it was
|
||||||
|
not the default).
|
||||||
|
|
||||||
|
* Also, ``conn.log`` now reports raw number of packets/bytes per
|
||||||
|
endpoint.
|
||||||
|
|
||||||
|
- The new logging framework makes it possible to extend, customize,
|
||||||
|
and filter logs very easily. See the :doc:`logging framework <logging>`
|
||||||
|
for more information on usage.
|
||||||
|
|
||||||
|
- A common pattern found in the new scripts is to store logging stream
|
||||||
|
records for protocols inside the ``connection`` records so that
|
||||||
|
state can be collected until enough is seen to log a coherent unit
|
||||||
|
of information regarding the activity of that connection. This
|
||||||
|
state is now frequently seen/accessible in event handlers, for
|
||||||
|
example, like ``c$<protocol>`` where ``<protocol>`` is replaced by
|
||||||
|
the name of the protocol. This field is added to the ``connection``
|
||||||
|
record by ``redef``'ing it in a
|
||||||
|
``base/protocols/<protocol>/main.bro`` script.
|
||||||
|
|
||||||
|
- The logging code has been rewritten internally, with script-level
|
||||||
|
interface and output backend now clearly separated. While ASCII
|
||||||
|
logging is still the default, we will add further output types in
|
||||||
|
the future (binary format, direct database logging).
|
||||||
|
|
||||||
|
|
||||||
|
Notice Framework
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The way users interact with "notices" has changed significantly in
|
||||||
|
order to make it easier to define a site policy and more extensible
|
||||||
|
for adding customized actions. See the :doc:`notice framework <notice>`.
|
||||||
|
|
||||||
|
|
||||||
|
New Default Settings
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
- Dynamic Protocol Detection (DPD) is now enabled/loaded by default.
|
||||||
|
|
||||||
|
- The default packet filter now examines all packets instead of
|
||||||
|
dynamically building a filter based on which protocol analysis scripts
|
||||||
|
are loaded. See ``PacketFilter::all_packets`` for how to revert to old
|
||||||
|
behavior.
|
||||||
|
|
||||||
|
API Changes
|
||||||
|
-----------
|
||||||
|
|
||||||
|
- The ``@prefixes`` directive works differently now.
|
||||||
|
Any added prefixes are now searched for and loaded *after* all input
|
||||||
|
files have been parsed. After all input files are parsed, Bro
|
||||||
|
searches ``BROPATH`` for prefixed, flattened versions of all of the
|
||||||
|
parsed input files. For example, if ``lcl`` is in ``@prefixes``, and
|
||||||
|
``site.bro`` is loaded, then a file named ``lcl.site.bro`` that's in
|
||||||
|
``BROPATH`` would end up being automatically loaded as well. Packages
|
||||||
|
work similarly, e.g. loading ``protocols/http`` means a file named
|
||||||
|
``lcl.protocols.http.bro`` in ``BROPATH`` gets loaded automatically.
|
||||||
|
|
||||||
|
- The ``make_addr`` BIF now returns a ``subnet`` versus an ``addr``
|
||||||
|
|
||||||
|
|
||||||
|
Variable Naming
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- ``Module`` is more widely used for namespacing. E.g. the new
|
||||||
|
``site.bro`` exports the ``local_nets`` identifier (among other
|
||||||
|
things) into the ``Site`` module.
|
||||||
|
|
||||||
|
- Identifiers may have been renamed to conform to new `scripting
|
||||||
|
conventions
|
||||||
|
<http://www.bro-ids.org/development/script-conventions.html>`_
|
||||||
|
|
||||||
|
|
||||||
|
BroControl
|
||||||
|
==========
|
||||||
|
|
||||||
|
BroControl looks pretty much similar to the version coming with Bro 1.x,
|
||||||
|
but has been cleaned up and streamlined significantly internally.
|
||||||
|
|
||||||
|
BroControl has a new ``process`` command to process a trace on disk
|
||||||
|
offline using a similar configuration to what BroControl installs for
|
||||||
|
live analysis.
|
||||||
|
|
||||||
|
BroControl now has an extensive plugin interface for adding new
|
||||||
|
commands and options. Note that this is still considered experimental.
|
||||||
|
|
||||||
|
We have removed the ``analysis`` command, and BroControl currently
|
||||||
|
does not send daily alarm summaries anymore (this may be restored
|
||||||
|
later).
|
||||||
|
|
||||||
|
Removed Functionality
|
||||||
|
=====================
|
||||||
|
|
||||||
|
We have remove a bunch of functionality that was rarely used and/or
|
||||||
|
had not been maintained for a while already:
|
||||||
|
|
||||||
|
- The ``net`` script data type.
|
||||||
|
- The ``alarm`` statement; use the notice framework instead.
|
||||||
|
- Trace rewriting.
|
||||||
|
- DFA state expiration in regexp engine.
|
||||||
|
- Active mapping.
|
||||||
|
- Native DAG support (may come back eventually)
|
||||||
|
- ClamAV support.
|
||||||
|
- The connection compressor is now disabled by default, and will
|
||||||
|
be removed in the future.
|
||||||
|
|
||||||
|
Development Infrastructure
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Bro development has moved from using SVN to Git for revision control.
|
||||||
|
Users that want to use the latest Bro development snapshot by checking it out
|
||||||
|
from the source repositories should see the `development process
|
||||||
|
<http://www.bro-ids.org/development/process.html>`_. Note that all the various
|
||||||
|
sub-components now reside in their own repositories. However, the
|
||||||
|
top-level Bro repository includes them as git submodules so it's easy
|
||||||
|
to check them all out simultaneously.
|
||||||
|
|
||||||
|
Bro now uses `CMake <http://www.cmake.org>`_ for its build system so
|
||||||
|
that is a new required dependency when building from source.
|
||||||
|
|
||||||
|
Bro now comes with a growing suite of regression tests in
|
||||||
|
``testing/``.
|
14
pkg/check-cmake
Executable file
14
pkg/check-cmake
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# CMake/CPack versions before 2.8.3 have bugs that can create bad packages
|
||||||
|
# Since packages will be built on several different systems, a single
|
||||||
|
# version of CMake is required to obtain consistency, but can be increased
|
||||||
|
# as new versions of CMake come out that also produce working packages.
|
||||||
|
|
||||||
|
CMAKE_PACK_REQ="cmake version 2.8.6"
|
||||||
|
CMAKE_VER=`cmake -version`
|
||||||
|
|
||||||
|
if [ "${CMAKE_VER}" != "${CMAKE_PACK_REQ}" ]; then
|
||||||
|
echo "Package creation requires ${CMAKE_PACK_REQ}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
47
pkg/make-deb-packages
Executable file
47
pkg/make-deb-packages
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script generates binary DEB packages.
|
||||||
|
# They can be found in ../build/ after running.
|
||||||
|
|
||||||
|
./check-cmake || { exit 1; }
|
||||||
|
|
||||||
|
# The DEB CPack generator depends on `dpkg-shlibdeps` to automatically
|
||||||
|
# determine what dependencies to set for the packages
|
||||||
|
type dpkg-shlibdeps > /dev/null 2>&1 || {
|
||||||
|
echo "\
|
||||||
|
Creating DEB packages requires the "dpkg-shlibs" command, usually provided by
|
||||||
|
the 'dpkg-dev' package, please install it first.
|
||||||
|
" >&2;
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix=/opt/bro
|
||||||
|
|
||||||
|
# During the packaging process, `dpkg-shlibs` will fail if used on a library
|
||||||
|
# that links to other internal/project libraries unless an RPATH is used or
|
||||||
|
# we set LD_LIBRARY_PATH such that it can find the internal/project library
|
||||||
|
# in the temporary packaging tree.
|
||||||
|
export LD_LIBRARY_PATH=./${prefix}/lib
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Minimum Bro
|
||||||
|
./configure --prefix=${prefix} --disable-broccoli --disable-broctl \
|
||||||
|
--pkg-name-prefix=Bro-minimal --binary-package
|
||||||
|
( cd build && make package )
|
||||||
|
|
||||||
|
# Full Bro package
|
||||||
|
./configure --prefix=${prefix} --pkg-name-prefix=Bro --binary-package
|
||||||
|
( cd build && make package )
|
||||||
|
|
||||||
|
# Broccoli
|
||||||
|
cd aux/broccoli
|
||||||
|
./configure --prefix=${prefix} --binary-package
|
||||||
|
( cd build && make package && mv *.deb ../../../build/ )
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Broctl
|
||||||
|
cd aux/broctl
|
||||||
|
./configure --prefix=${prefix} --binary-package
|
||||||
|
( cd build && make package && mv *.deb ../../../build/ )
|
||||||
|
cd ../..
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue