Merge branch 'topic/policy-scripts-new' of ssh://git.bro-ids.org/bro into topic/policy-scripts-new

Conflicts:
	policy/http.bro
This commit is contained in:
Seth Hall 2011-05-24 10:12:45 -04:00
commit 5414c146fa
61 changed files with 589 additions and 303 deletions

@ -1 +1 @@
Subproject commit 54f3ff4e6627d4a44d1e014e8e581e4e9dfed8c3
Subproject commit 8843da57dc8aee433550727dcbd1199824ca9da4

@ -1 +1 @@
Subproject commit c4eaf7c7471ab04ae8af0f2913cb8350d9ae0b3a
Subproject commit 1bf5407722ef5910bafd513bcec6a51b280eeb10

View file

@ -63,10 +63,7 @@ endmacro(SetPackageVersion)
#
# 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.
#
# DEB if the platform has dpkg-shlibdeps installed
#
# CPACK_GENERATOR is set by this macro
# CPACK_SOURCE_GENERATOR is set by this macro
@ -77,9 +74,14 @@ macro(SetPackageGenerators)
list(APPEND CPACK_GENERATOR PackageMaker)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_program(RPMBUILD_EXE rpmbuild)
find_program(DPKGSHLIB_EXE dpkg-shlibdeps)
if (RPMBUILD_EXE)
set(CPACK_GENERATOR ${CPACK_GENERATOR} RPM)
endif ()
if (DPKGSHLIB_EXE)
set(CPACK_GENERATOR ${CPACK_GENERATOR} DEB)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS true)
endif ()
endif ()
endmacro(SetPackageGenerators)
@ -159,11 +161,27 @@ macro(SetPackageInstallScripts VERSION)
endif ()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# DEB packages can automatically handle configuration files
# if provided in a "conffiles" file in the packaging
set(conffiles_file ${CMAKE_CURRENT_BINARY_DIR}/conffiles)
if (INSTALLED_CONFIG_FILES)
string(REPLACE " " ";" conffiles ${INSTALLED_CONFIG_FILES})
endif ()
file(WRITE ${conffiles_file} "")
foreach (_file ${conffiles})
file(APPEND ${conffiles_file} "${_file}\n")
endforeach ()
list(APPEND CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
${CMAKE_CURRENT_BINARY_DIR}/conffiles)
# RPMs don't need any explicit direction regarding config files.
# Leaving the set of installed config files empty will just
# bypass the logic in the pre/post install scripts and let
# the RPM do their own thing (regarding backups, etc.)
# bypass the logic in the default pre/post install scripts and let
# the RPMs/DEBs do their own thing (regarding backups, etc.)
# when upgrading packages.
set (INSTALLED_CONFIG_FILES "")
set(INSTALLED_CONFIG_FILES "")
endif ()
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_preinstall.sh.in)
@ -171,10 +189,16 @@ macro(SetPackageInstallScripts VERSION)
${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_preinstall.sh.in
${CMAKE_CURRENT_BINARY_DIR}/package_preinstall.sh
@ONLY)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_preinstall.sh.in
${CMAKE_CURRENT_BINARY_DIR}/preinst
@ONLY)
set(CPACK_PREFLIGHT_SCRIPT
${CMAKE_CURRENT_BINARY_DIR}/package_preinstall.sh)
set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
${CMAKE_CURRENT_BINARY_DIR}/package_preinstall.sh)
list(APPEND CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
${CMAKE_CURRENT_BINARY_DIR}/preinst)
endif ()
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_postupgrade.sh.in)
@ -182,10 +206,16 @@ macro(SetPackageInstallScripts VERSION)
${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_postupgrade.sh.in
${CMAKE_CURRENT_BINARY_DIR}/package_postupgrade.sh
@ONLY)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/package_postupgrade.sh.in
${CMAKE_CURRENT_BINARY_DIR}/postinst
@ONLY)
set(CPACK_POSTUPGRADE_SCRIPT
${CMAKE_CURRENT_BINARY_DIR}/package_postupgrade.sh)
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE
${CMAKE_CURRENT_BINARY_DIR}/package_postupgrade.sh)
list(APPEND CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
${CMAKE_CURRENT_BINARY_DIR}/postinst)
endif ()
endmacro(SetPackageInstallScripts)

View file

@ -48,21 +48,13 @@ if [ -n "${sampleFiles}" ]; then
EOF
fi
# make sure that world-writeable dirs have the sticky bit set
# so that unprivileged can't rename/remove files within
if [ -d /var/opt/bro/spool ]; then
chmod +t /var/opt/bro/spool
fi
if [ -d /var/opt/bro/spool/tmp ]; then
chmod +t /var/opt/bro/spool/tmp
fi
if [ -d /var/opt/bro/spool/policy ]; then
chmod +t /var/opt/bro/spool/policy
fi
if [ -d /var/opt/bro/logs ]; then
chmod +t /var/opt/bro/logs
# Set up world writeable spool and logs directory for broctl, making sure
# to set the sticky bit so that unprivileged users can't rename/remove files.
# (CMake/CPack is supposed to install them, but has problems with empty dirs)
if [ -n "@EMPTY_WORLD_DIRS@" ]; then
for dir in "@EMPTY_WORLD_DIRS@"; do
mkdir -p ${dir}
chmod 777 ${dir}
chmod +t ${dir}
done
fi

View file

@ -59,8 +59,6 @@ macro(REST_TARGET srcDir broInput)
set(basename "${basename}.init")
endif ()
set (restFile "${basename}.rst")
if (NOT relDstDir)
set(docName "${basename}")
set(dstDir "${RST_OUTPUT_DIR}")
@ -69,7 +67,9 @@ macro(REST_TARGET srcDir broInput)
set(dstDir "${RST_OUTPUT_DIR}/${relDstDir}")
endif ()
set(restOutput "${dstDir}/${restFile}")
set(restFile "${docName}.rst")
string(REPLACE "/" "^" restFile ${restFile})
set(restOutput "${dstDir}/${basename}.rst")
set(indexEntry " ${docName} <${docName}>")
set(MASTER_POLICY_INDEX_TEXT "${MASTER_POLICY_INDEX_TEXT}\n${indexEntry}")
@ -97,7 +97,7 @@ macro(REST_TARGET srcDir broInput)
if (${group} STREQUAL "default" OR ${group} STREQUAL "bifs")
set(BRO_ARGS --doc-scripts --exec '')
else ()
set(BRO_ARGS --doc-scripts ${srcDir}/${broInput})
set(BRO_ARGS --doc-scripts ${broInput})
endif ()
add_custom_command(OUTPUT ${restOutput}
@ -105,7 +105,7 @@ macro(REST_TARGET srcDir broInput)
COMMAND "${CMAKE_COMMAND}"
ARGS -E remove_directory .state
# generate the reST documentation using bro
COMMAND BROPATH=${BROPATH} ${CMAKE_BINARY_DIR}/src/bro
COMMAND BROPATH=${BROPATH}:${srcDir} ${CMAKE_BINARY_DIR}/src/bro
ARGS ${BRO_ARGS} || (rm -rf .state *.log *.rst && exit 1)
# move generated doc into a new directory tree that
# defines the final structure of documents
@ -129,39 +129,113 @@ endmacro(REST_TARGET)
# Schedule Bro scripts for which to generate documentation.
# Note: the script may be located in a subdirectory off of one of the main
# directories in BROPATH. In that case, just list the script as 'foo/bar.bro'
rest_target(${POLICY_SRC_DIR} alarm.bro user)
rest_target(${POLICY_SRC_DIR} arp.bro user)
rest_target(${POLICY_SRC_DIR} conn.bro user)
rest_target(${POLICY_SRC_DIR} dhcp.bro user)
rest_target(${POLICY_SRC_DIR} dns.bro user)
rest_target(${POLICY_SRC_DIR} ftp.bro user)
rest_target(${POLICY_SRC_DIR} http.bro user)
rest_target(${POLICY_SRC_DIR} http-reply.bro user)
rest_target(${POLICY_SRC_DIR} http-request.bro user)
rest_target(${POLICY_SRC_DIR} irc.bro user)
rest_target(${POLICY_SRC_DIR} smtp.bro user)
rest_target(${POLICY_SRC_DIR} ssl.bro user)
rest_target(${POLICY_SRC_DIR} ssl-ciphers.bro user)
rest_target(${POLICY_SRC_DIR} ssl-errors.bro user)
rest_target(${POLICY_SRC_DIR} synflood.bro user)
rest_target(${POLICY_SRC_DIR} tcp.bro user)
rest_target(${POLICY_SRC_DIR} udp.bro user)
rest_target(${POLICY_SRC_DIR} weird.bro user)
rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro internal)
rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro internal)
rest_target(${POLICY_SRC_DIR} conn.bro user)
rest_target(${POLICY_SRC_DIR} dns.bro policy/dns-index)
rest_target(${POLICY_SRC_DIR} dns/auth-addl.bro policy/dns-index)
rest_target(${POLICY_SRC_DIR} dns/base.bro policy/dns-index)
rest_target(${POLICY_SRC_DIR} dns/consts.bro policy/dns-index)
rest_target(${POLICY_SRC_DIR} dns/detect.bro policy/dns-index)
rest_target(${POLICY_SRC_DIR} dns/passive-replication.bro policy/dns-index)
# TODO: these don't currently work due to something that looks like a
# circular dependency. They'll also change to the 'default' group once
# loaded from bro.init.
#rest_target(${POLICY_SRC_DIR} dpd.bro policy/dpd-index)
#rest_target(${POLICY_SRC_DIR} dpd/base.bro policy/dpd-index)
#rest_target(${POLICY_SRC_DIR} dpd/dyn-disable.bro policy/dpd-index)
#rest_target(${POLICY_SRC_DIR} dpd/packet-segment-logging.bro policy/dpd-index)
rest_target(${POLICY_SRC_DIR} ftp.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} ftp/base.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} ftp/detect.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} ftp/file-extract.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} ftp/software.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} ftp/utils-commands.bro policy/ftp-index)
rest_target(${POLICY_SRC_DIR} functions.bro user)
# TODO: hot.conn.bro currently won't load because hot.bro doesn't exist
#rest_target(${POLICY_SRC_DIR} hot.conn.bro user)
rest_target(${POLICY_SRC_DIR} http.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/base-extended.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/base.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/detect-intel.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/detect-sqli.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/detect-webapps.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/file-extract.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/file-hash.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/file-ident.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/headers.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/software.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/utils.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/var-extraction-cookies.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} http/var-extraction-uri.bro policy/http-index)
rest_target(${POLICY_SRC_DIR} irc.bro policy/irc-index)
rest_target(${POLICY_SRC_DIR} irc/base.bro policy/irc-index)
rest_target(${POLICY_SRC_DIR} irc/dcc-send.bro policy/irc-index)
rest_target(${POLICY_SRC_DIR} known-services.bro user)
rest_target(${POLICY_SRC_DIR} known-hosts.bro user)
rest_target(${POLICY_SRC_DIR} metrics.bro policy/metrics-index)
rest_target(${POLICY_SRC_DIR} metrics/base.bro policy/metrics-index)
rest_target(${POLICY_SRC_DIR} metrics/conn-example.bro policy/metrics-index)
rest_target(${POLICY_SRC_DIR} metrics/http-example.bro policy/metrics-index)
rest_target(${POLICY_SRC_DIR} mime.bro policy/mime-index)
rest_target(${POLICY_SRC_DIR} mime/base.bro policy/mime-index)
rest_target(${POLICY_SRC_DIR} mime/file-extract.bro policy/mime-index)
rest_target(${POLICY_SRC_DIR} mime/file-hash.bro policy/mime-index)
rest_target(${POLICY_SRC_DIR} mime/file-ident.bro policy/mime-index)
rest_target(${POLICY_SRC_DIR} notice-action-filters.bro user)
rest_target(${POLICY_SRC_DIR} notice.bro user)
rest_target(${POLICY_SRC_DIR} site.bro user)
rest_target(${POLICY_SRC_DIR} signatures.bro policy/sig-index)
rest_target(${POLICY_SRC_DIR} signatures/base.bro policy/sig-index)
rest_target(${POLICY_SRC_DIR} smtp.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/base-extended.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/base.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/detect.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/software.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/utils.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} smtp/webmail-ident.bro policy/smtp-index)
rest_target(${POLICY_SRC_DIR} software.bro policy/software-index)
rest_target(${POLICY_SRC_DIR} software/base.bro policy/software-index)
rest_target(${POLICY_SRC_DIR} software/vulnerable.bro policy/software-index)
rest_target(${POLICY_SRC_DIR} ssh.bro policy/ssh-index)
rest_target(${POLICY_SRC_DIR} ssh/base.bro policy/ssh-index)
rest_target(${POLICY_SRC_DIR} ssh/software.bro policy/ssh-index)
rest_target(${POLICY_SRC_DIR} ssl-ciphers.bro policy/ssl-index)
rest_target(${POLICY_SRC_DIR} ssl-errors.bro policy/ssl-index)
rest_target(${POLICY_SRC_DIR} ssl.bro policy/ssl-index)
rest_target(${POLICY_SRC_DIR} utils/pattern.bro user)
rest_target(${POLICY_SRC_DIR} weird.bro user)
# Finding out what scripts bro will generate documentation for by default
# can be done like: `bro --doc-scripts --exec ""`
rest_target(${POLICY_SRC_DIR} bro.init default)
rest_target(${POLICY_SRC_DIR} logging-ascii.bro default)
rest_target(${POLICY_SRC_DIR} logging.bro default)
rest_target(${POLICY_SRC_DIR} pcap.bro default)
rest_target(${POLICY_SRC_DIR} server-ports.bro default)
rest_target(${CMAKE_BINARY_DIR}/src bro.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src const.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src event.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src logging.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src strings.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src types.bif.bro bifs)
rest_target(${POLICY_SRC_DIR} bro.init default)
rest_target(${POLICY_SRC_DIR} logging-ascii.bro default)
rest_target(${POLICY_SRC_DIR} logging.bro default)
rest_target(${POLICY_SRC_DIR} pcap.bro default)
rest_target(${POLICY_SRC_DIR} server-ports.bro default)
rest_target(${CMAKE_BINARY_DIR}/src bro.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src const.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src event.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src logging.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src strings.bif.bro bifs)
rest_target(${CMAKE_BINARY_DIR}/src types.bif.bro bifs)
# create temporary list of all docs to include in the master policy/index file
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp_policy_index

View file

@ -66,7 +66,7 @@ redef dpd_config += {
# redefinitions of "Notice::Type" are self-documenting, but
# more information can be supplied in two different ways
redef enum Notice += {
redef enum Notice::Type += {
## any number of this type of comment
## will document "Notice_One"
Notice_One,

View file

@ -1,4 +1,5 @@
.. This is a stub doc to which the build process can append.
Built-In Functions (BIFs)
=========================
Here's a list of all documentation for BIFs that Bro provides:

View file

@ -11,11 +11,22 @@ Contents:
common
builtins
policy/index
default
bifs
user
policy/dns-index
policy/ftp-index
policy/http-index
policy/irc-index
policy/metrics-index
policy/mime-index
policy/sig-index
policy/smtp-index
policy/software-index
policy/ssh-index
policy/ssl-index
internal
policy/index
Indices and tables
==================

View file

@ -1,3 +1,5 @@
.. This is a stub doc to which the build process can append.
Internal Policy Scripts
=======================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
DNS Policy Scripts
==================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
FTP Policy Scripts
==================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
HTTP Policy Scripts
===================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
IRC Policy Scripts
==================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
Metrics Policy Scripts
======================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
MIME Policy Scripts
===================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
Signature Policy Scripts
========================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
SMTP Policy Scripts
===================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
Software Policy Scripts
=======================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
SSH Policy Scripts
==================

View file

@ -0,0 +1,5 @@
.. This is a stub doc to which the build process can append.
SSL Policy Scripts
==================

View file

@ -1,3 +1,5 @@
User-Facing Policy Scripts
==========================
.. This is a stub doc to which the build process can append.
Other User-Facing Policy Scripts
================================

52
make-deb-packages Executable file
View file

@ -0,0 +1,52 @@
#!/bin/sh
# This script generates binary DEB packages.
# They can be found in build/ after running.
prefix=/opt/bro
# CMake/CPack versions before 2.8.2 have bugs that can create bad packages
CMAKE_PACK_REQ=2.8.2
CMAKE_VER=`cmake -version`
if [ "${CMAKE_VER}" \< "${CMAKE_PACK_REQ}" ]; then
echo "Package creation requires CMake > 2.8.2" >&2
exit 1
fi
# 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;
}
# 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
# Minimum Bro
./configure --prefix=${prefix} --disable-broccoli --disable-broctl \
--pkg-name-prefix=Bro --binary-package
( cd build && make package )
# Full Bro package
./configure --prefix=${prefix} --pkg-name-prefix=Bro-all --binary-package
( cd build && make package )
# Broccoli
cd aux/broccoli
./configure --prefix=${prefix} --binary-package
( cd build && make package && mv Broccoli*.deb ../../../build/ )
cd ../..
# Broctl
cd aux/broctl
./configure --prefix=${prefix} --binary-package
( cd build && make package && mv Broctl*.deb ../../../build/ )
cd ../..

View file

@ -1,11 +1,6 @@
@load const.bif.bro
@load types.bif.bro
global bro_signal: event(signal: count);
# Called (one day) if there's no handler for an internal event.
global no_handler: event(name: string, val: any);
# Type declarations
type string_array: table[count] of string;
type string_set: set[string];
@ -45,8 +40,6 @@ type icmp_context: record {
DF: bool;
};
type addr_set: set[addr];
type dns_mapping: record {
creation_time: time;
@ -298,16 +291,6 @@ const state_write_delay = 0.01 secs &redef;
global done_with_network = F;
event net_done(t: time) { done_with_network = T; }
const SIGHUP = 1;
event bro_signal(signal: count)
{
if ( signal == SIGHUP )
{
flush_all();
checkpoint_state();
}
}
function log_file_name(tag: string): string
{
local suffix = getenv("BRO_LOG_SUFFIX") == "" ? "log" : getenv("BRO_LOG_SUFFIX");

View file

@ -16,8 +16,49 @@ export {
duration: interval &log &optional;
orig_bytes: count &log &optional;
resp_bytes: count &log &optional;
## ========== ===============================================
## conn_state Meaning
## ========== ===============================================
## S0 Connection attempt seen, no reply.
## S1 Connection established, not terminated.
## SF Normal establishment and termination. Note that this is the same symbol as for state S1. You can tell the two apart because for S1 there will not be any byte counts in the summary, while for SF there will be.
## REJ Connection attempt rejected.
## S2 Connection established and close attempt by originator seen (but no reply from responder).
## S3 Connection established and close attempt by responder seen (but no reply from originator).
## RSTO Connection established, originator aborted (sent a RST).
## RSTR Established, responder aborted.
## RSTOS0 Originator sent a SYN followed by a RST, we never saw a SYN-ACK from the responder.
## RSTRH Responder sent a SYN ACK followed by a RST, we never saw a SYN from the (purported) originator.
## SH Originator sent a SYN followed by a FIN, we never saw a SYN ACK from the responder (hence the connection was "half" open).
## SHR Responder sent a SYN ACK followed by a FIN, we never saw a SYN from the originator.
## OTH No SYN seen, just midstream traffic (a "partial connection" that was not later closed).
## ========== ===============================================
conn_state: string &log &optional;
local_orig: bool &log &optional;
## Records the state history of (TCP) connections as
## a string of letters.
##
## ====== ====================================================
## Letter Meaning
## ====== ====================================================
## s a SYN w/o the ACK bit set
## h a SYN+ACK ("handshake")
## a a pure ACK
## d packet with payload ("data")
## f packet with FIN bit set
## r packet with RST bit set
## c packet with a bad checksum
## i inconsistent packet (e.g. SYN+RST bits both set)
## ====== ====================================================
##
## If the letter is in upper case it means the event comes from the
## originator and lower case then means the responder.
## Also, there is compression. We only record one "d" in each direction,
## for instance. I.e., we just record that data went in that direction.
## This history is not meant to encode how much data that happened to be.
history: string &log &optional;
};

View file

@ -1,4 +1,5 @@
@load functions
@load dns/consts
module DNS;
@ -277,4 +278,4 @@ event connection_state_remove(c: connection) &priority=-5
for ( trans_id in c$dns_state$pending )
Log::write(DNS, c$dns_state$pending[trans_id]);
}

View file

@ -1,8 +1,12 @@
##! Script for detecting strange activity within DNS.
##! Detections:
##! * Raise a notice for responses from remote hosts that resolve to local
##! hosts but the name is not considered to be within a local zone.
##! - local_zones variable **must** be set appropriately for this detection.
##!
##! Notices raised:
##!
##! * :bro:enum:`DNS::DNS_ExternalName`
##!
##! A remote host resolves to a local host, but the name is not considered
##! to be within a local zone. :bro:id:`local_zones` variable **must**
##! be set appropriately for this detection.
@load dns/base
@load notice
@ -10,9 +14,9 @@
module DNS;
redef enum Notice::Type += {
# Raised when a non-local name is found to be pointing at a local host.
# This only works appropriately when all of your authoritative DNS
# servers are located in your "local_nets".
## Raised when a non-local name is found to be pointing at a local host.
## This only works appropriately when all of your authoritative DNS
## servers are located in your :bro:id:`local_nets`.
DNS_ExternalName,
};

View file

@ -1,10 +1,11 @@
##! Script for logging passive DNS replication-type data.
##! For a definition of what passive DNS repliction is, see here::
##! https://sie.isc.org/
## NOTE: This is a major hack job.
## TODO: two queries within the create_expire with different results will
## cause only one to be logged.
##! For a definition of what passive DNS repliction is, see here:
##! https://sie.isc.org/
##!
##! .. note:: NOTE: This is a major hack job.
##!
##! TODO: two queries within the create_expire with different results will
##! cause only one to be logged.
@load dns/base
@ -30,4 +31,4 @@ event bro_init()
},
$include=set("ts", "query", "answers")
]);
}
}

View file

@ -4,7 +4,8 @@
##! file name.
##!
##! TODO:
##! * Handle encrypted sessions correctly (get an example?)
##!
##! * Handle encrypted sessions correctly (get an example?)
@load functions
@load ftp/utils-commands

View file

@ -1,8 +1,10 @@
##! Software detection with the FTP protocol.
##! TODO::
##! * Detect server software with initial 220 message
##! * Detect client software with password given for anonymous users
##! (e.g. cyberduck@example.net)
##!
##! TODO:
##!
##! * Detect server software with initial 220 message
##! * Detect client software with password given for anonymous users
##! (e.g. cyberduck@example.net)
@load ftp/base
@load software
@ -21,4 +23,4 @@ event ftp_request(c: connection, command: string, arg: string) &priority=4
local si = Software::parse(arg, c$id$orig_h, FTP_CLIENT);
Software::found(c$id, si);
}
}
}

View file

@ -1,6 +1,5 @@
##! This script is the wrapper script for HTTP analysis.
## Author: Seth Hall <seth@icir.org> - Inspired by the work of many others.
##! :Author: Seth Hall <seth@icir.org> - Inspired by the work of many others.
@load http/base
@load http/base-extended

View file

@ -1,3 +1,3 @@
## Intelligence based HTTP detections.
##! Intelligence based HTTP detections.
module HTTP;
module HTTP;

View file

@ -1,4 +1,6 @@
@load http/utils
@load software
@load signatures
@ -47,4 +49,4 @@ event signature_match(state: signature_state, msg: string, data: string) &priori
}
Software::found(c$id, si);
}
}

View file

@ -8,7 +8,7 @@ redef record Info += {
## The vector of HTTP headers. No header values are included here, just
## the header names.
## TODO: with an empty vector as &default, the vector isn't coerced to the
## correct type.
## correct type.
headers: vector of string &log &optional;
};
@ -20,4 +20,4 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr
if ( ! c$http?$headers )
c$http$headers = vector();
c$http$headers[|c$http$headers|] = name;
}
}

View file

@ -1,6 +1,7 @@
## This script extracts and logs variables from cookies sent by clients
##! This script extracts and logs variables from cookies sent by clients
@load http
@load http/base
@load http/utils
module HTTP;
@ -12,4 +13,4 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr
{
if ( is_orig && name == "COOKIE" )
c$http$cookie_vars = extract_keys(value, /;[[:blank:]]*/);
}
}

View file

@ -1,4 +1,4 @@
## This script extracts and logs variables from the requested URI
##! This script extracts and logs variables from the requested URI
@load http/utils
@ -12,4 +12,4 @@ event http_request(c: connection, method: string, original_URI: string,
unescaped_URI: string, version: string) &priority=2
{
c$http$uri_vars = extract_keys(original_URI, /&/);
}
}

View file

@ -5,9 +5,10 @@
##! but that connection will actually be between B and C which could be
##! analyzed on a different worker.
##!
##! Example line from IRC server indicating that the DCC SEND is about to start:
##! PRIVMSG my_nick :^ADCC SEND whateverfile.zip 3640061780 1026 41709^A
## Example line from IRC server indicating that the DCC SEND is about to start:
## PRIVMSG my_nick :^ADCC SEND whateverfile.zip 3640061780 1026 41709^A
@load irc/base
module IRC;

View file

@ -1,4 +1,4 @@
## A few predefined notice_action_filters (see notice.bro).
##! A few predefined notice_action_filters (see notice.bro).
@load notice
@load functions

View file

@ -25,13 +25,14 @@ export {
uid: string &log &optional;
id: conn_id &log &optional; ##< connection-ID, if we don't have a connection handy
## This is the relevant host for this notice. It could be set because
## either::
## 1. There is no connection associated with this notice.
## 2. There is some underlying semantic of the notice where either
## orig_h or resp_h is the relevant host in the associated
## connection. For example, if a host is detected scanning, the
## particular connection taking place when the notice is generated
## is irrelevant and only the host detected scanning is relevant.
## either:
##
## 1. There is no connection associated with this notice.
## 2. There is some underlying semantic of the notice where either
## orig_h or resp_h is the relevant host in the associated
## connection. For example, if a host is detected scanning, the
## particular connection taking place when the notice is generated
## is irrelevant and only the host detected scanning is relevant.
relevant_host: addr &log &optional;
note: Type &log;

View file

@ -1,4 +1,6 @@
@load functions
module SMTP;
function find_address_in_smtp_header(header: string): string

View file

@ -2,11 +2,14 @@
##! with the USER-AGENT (or other) header unless not possible and will resort
##! to heuristics if necessary.
##!
##! TODO::
##! * Find some heuristic to determine if email was sent through
##! a MS Exhange webmail interface as opposed to a desktop client.
##! TODO:
##!
##! * Find some heuristic to determine if email was sent through
##! a MS Exhange webmail interface as opposed to a desktop client.
##!
@load smtp/base
module SMTP;
redef record Info += {

View file

@ -1,2 +1,2 @@
@load software/base
@load software/vulnerable
@load software/vulnerable

View file

@ -1,8 +1,8 @@
## This script provides the framework for software version detection and
## parsing, but doesn't actually do any detection on it's own. It relys on
## other protocol specific scripts to parse out software from the protocol(s)
## that they analyze. The entry point for providing new software detections
## to this framework is through the Software::found function.
##! This script provides the framework for software version detection and
##! parsing, but doesn't actually do any detection on it's own. It relys on
##! other protocol specific scripts to parse out software from the protocol(s)
##! that they analyze. The entry point for providing new software detections
##! to this framework is through the Software::found function.
@load functions
@load notice
@ -67,9 +67,9 @@ export {
} &redef;
## Other scripts should call this function when they detect software.
## @param unparsed_version: This is the full string from which the
## Software::Info was extracted.
## @return: T if the software was logged, F otherwise.
## unparsed_version: This is the full string from which the
## :bro:type:`Software::Info` was extracted.
## Returns: T if the software was logged, F otherwise.
global found: function(id: conn_id, info: Software::Info): bool;
## This function can take many software version strings and parse them into
@ -80,7 +80,7 @@ export {
software_type: Type): Info;
## Compare two versions.
## @return: Returns -1 for v1 < v2, 0 for v1 == v2, 1 for v1 > v2.
## Returns: -1 for v1 < v2, 0 for v1 == v2, 1 for v1 > v2.
## If the numerical version numbers match, the addl string
## is compared lexicographically.
global cmp_versions: function(v1: Version, v2: Version): int;

View file

@ -58,6 +58,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
{ AnalyzerTag::ICMP_Echo, "ICMP_ECHO",
ICMP_Echo_Analyzer::InstantiateAnalyzer,
ICMP_Echo_Analyzer::Available, 0, false },
{ AnalyzerTag::ICMP_Redir, "ICMP_REDIR",
ICMP_Redir_Analyzer::InstantiateAnalyzer,
ICMP_Redir_Analyzer::Available, 0, false },
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
TCP_Analyzer::Available, 0, false },

View file

@ -22,7 +22,9 @@ namespace AnalyzerTag {
PIA_TCP, PIA_UDP,
// Transport-layer analyzers.
ICMP, ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, TCP, UDP,
ICMP,
ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, ICMP_Redir,
TCP, UDP,
// Application-layer analyzers (hand-written).
BitTorrent, BitTorrentTracker,

View file

@ -7,47 +7,86 @@
#include "BroDoc.h"
#include "BroDocObj.h"
BroDoc::BroDoc(const std::string& sourcename)
BroDoc::BroDoc(const std::string& rel, const std::string& abs)
{
#ifdef DEBUG
fprintf(stdout, "Documenting source: %s\n", sourcename.c_str());
#endif
source_filename = sourcename.substr(sourcename.find_last_of('/') + 1);
size_t f_pos = abs.find_last_of('/');
if ( std::string::npos == f_pos )
source_filename = abs;
else
source_filename = abs.substr(f_pos + 1);
size_t ext_pos = source_filename.find_last_of('.');
std::string ext = source_filename.substr(ext_pos + 1);
if ( ext_pos == std::string::npos || ext != "bro" )
if ( rel == abs )
{
if ( source_filename != "bro.init" && source_filename != "<stdin>" )
{
fprintf(stderr,
"Warning: documenting file without .bro extension: %s\n",
sourcename.c_str());
}
// The Bro script must have been loaded from an explicit path,
// so just use the basename as the document title
doc_title = source_filename;
}
else
{
// Must have relied on BROPATH to load the script, keep the relative
// directory as part of the source file name
size_t ext_pos = rel.find_last_of('.');
std::string rel_ext = rel.substr(ext_pos + 1);
ext_pos = abs.find_last_of('.');
std::string abs_ext = abs.substr(ext_pos + 1);
if ( rel_ext == abs_ext || std::string::npos == ext_pos )
doc_title = rel;
else
{
// Force the reST documentation file to be "bro.init.rst".
ext_pos = std::string::npos;
}
doc_title = rel + "." + abs_ext;
}
reST_filename = source_filename.substr(0, ext_pos);
reST_filename = doc_title;
size_t ext_pos = reST_filename.find(".bro");
if ( std::string::npos == ext_pos )
reST_filename += ".rst";
else
reST_filename.replace(ext_pos, 4, ".rst");
reST_filename = doc_title.substr(0, ext_pos);
reST_filename += ".rst";
/*
// if the bro source file is being loaded from a relative path,
// re-create that directory tree to store the output
size_t f_pos = reST_filename.find_last_of('/');
if ( std::string::npos != f_pos )
{
std::string outdir = reST_filename.substr(0, f_pos);
std::string subdir;
while ( ! outdir.empty() )
{
size_t pos = outdir.find_first_of('/');
if ( pos != std::string::npos ) pos++;
subdir += outdir.substr(0, pos);
outdir.erase(0, pos);
ensure_dir(subdir.c_str());
}
}
*/
// Instead of re-creating the directory hierarchy based on related
// loads, just replace the directory separatories such that the reST
// output will all be placed in a flat directory (the working dir).
std::for_each(reST_filename.begin(), reST_filename.end(), replace_slash());
reST_file = fopen(reST_filename.c_str(), "w");
if ( ! reST_file )
fprintf(stderr, "Failed to open %s", reST_filename.c_str());
fprintf(stderr, "Failed to open %s\n", reST_filename.c_str());
#ifdef DEBUG
else
fprintf(stdout, "Created reST document: %s\n", reST_filename.c_str());
fprintf(stdout, "Documenting absolute source: %s\n", abs.c_str());
fprintf(stdout, "\trelative load: %s\n", rel.c_str());
fprintf(stdout, "\tdoc title: %s\n", doc_title.c_str());
fprintf(stdout, "\tbro file: %s\n", source_filename.c_str());
fprintf(stdout, "\trst file: %s\n", reST_filename.c_str());
#endif
}
BroDoc::~BroDoc()
{
if ( reST_file && fclose( reST_file ) )
fprintf(stderr, "Failed to close %s", reST_filename.c_str());
fprintf(stderr, "Failed to close %s\n", reST_filename.c_str());
FreeBroDocObjPtrList(all);
}
@ -98,7 +137,7 @@ void BroDoc::WriteDocFile() const
{
WriteToDoc(".. Automatically generated. Do not edit.\n\n");
WriteSectionHeading(source_filename.c_str(), '=');
WriteSectionHeading(doc_title.c_str(), '=');
WriteToDoc("\n:download:`Original Source File <%s>`\n\n",
source_filename.c_str());

View file

@ -22,10 +22,15 @@ public:
* the filename of the Bro script that generates it, except any
* ".bro" file extension is stripped and ".rst" takes it place.
* If the filename doesn't end in ".bro", then ".rst" is just appended.
* @param sourcename The name of the Bro script for which to generate
* documentation. May contain a path.
* Any '/' characters in the reST file name that result from choice of
* the 'rel' parameter are replaced with '^'.
* @param rel A string representing the path relative to BROPATH off of
* which the source file is loaded or generally any filesystem
* path to a Bro script. May or may not have .bro file extension.
* @param abs The absolute path to the Bro script for which to generate
* documentation.
*/
BroDoc(const std::string& sourcename);
BroDoc(const std::string& rel, const std::string& abs);
/**
* BroDoc destructor
@ -203,7 +208,8 @@ public:
protected:
FILE* reST_file;
std::string reST_filename;
std::string source_filename;
std::string source_filename; // points to the basename of source file
std::string doc_title;
std::string packet_filter;
std::list<std::string> modules;
@ -357,6 +363,13 @@ private:
{
return ! o->IsPublicAPI();
}
struct replace_slash {
void operator()(char& c)
{
if ( c == '/' ) c = '^';
}
};
};
#endif

View file

@ -229,6 +229,14 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
}
break;
case ICMP_REDIRECT:
if ( ICMP_Redir_Analyzer::Available() )
{
root = new ICMP_Redir_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Redir analyzer");
}
break;
case ICMP_UNREACH:
if ( ICMP_Unreachable_Analyzer::Available() )
{

View file

@ -321,6 +321,24 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
ConnectionEvent(f, vl);
}
ICMP_Redir_Analyzer::ICMP_Redir_Analyzer(Connection* c)
: ICMP_Analyzer(AnalyzerTag::ICMP_Redir, c)
{
}
void ICMP_Redir_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
int caplen, const u_char*& data)
{
uint32 addr = ntohl(icmpp->icmp_hun.ih_void);
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(BuildICMPVal());
vl->append(new AddrVal(htonl(addr)));
ConnectionEvent(icmp_redirect, vl);
}
void ICMP_Context_Analyzer::NextICMP(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data)

View file

@ -74,6 +74,22 @@ protected:
int len, int caplen, const u_char*& data);
};
class ICMP_Redir_Analyzer : public ICMP_Analyzer {
public:
ICMP_Redir_Analyzer(Connection* conn);
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_Redir_Analyzer(conn); }
static bool Available() { return icmp_redirect; }
protected:
ICMP_Redir_Analyzer() { }
virtual void NextICMP(double t, const struct icmp* icmpp,
int len, int caplen, const u_char*& data);
};
class ICMP_Context_Analyzer : public ICMP_Analyzer {
public:
ICMP_Context_Analyzer(AnalyzerTag::Tag tag, Connection* conn)

View file

@ -848,8 +848,8 @@ void TypeDecl::DescribeReST(ODesc* d) const
}
CommentedTypeDecl::CommentedTypeDecl(BroType* t, const char* i,
attr_list* attrs, std::list<std::string>* cmnt_list)
: TypeDecl(t, i, attrs)
attr_list* attrs, bool in_record, std::list<std::string>* cmnt_list)
: TypeDecl(t, i, attrs, in_record)
{
comments = cmnt_list;
}
@ -1157,6 +1157,7 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
for ( int i = 0; i < num_fields; ++i )
{
if ( i > 0 )
{
if ( func_args )
d->Add(", ");
else
@ -1164,6 +1165,7 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
d->NL();
d->NL();
}
}
FieldDecl(i)->DescribeReST(d);
}

View file

@ -420,7 +420,7 @@ public:
class CommentedTypeDecl : public TypeDecl {
public:
CommentedTypeDecl(BroType* t, const char* i, attr_list* attrs = 0,
std::list<std::string>* cmnt_list = 0);
bool in_record = false, std::list<std::string>* cmnt_list = 0);
virtual ~CommentedTypeDecl();
void DescribeReST(ODesc* d) const;

View file

@ -242,15 +242,26 @@ void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */)
// t->GetTypeID() is true.
if ( generate_documentation )
{
if ( t->Tag() == TYPE_RECORD )
{
// Only "shallow" copy record types because we want to be able
// to see additions to the original type's list of fields
switch ( t->Tag() ) {
// Only "shallow" copy types that may contain records because
// we want to be able to see additions to the original record type's
// list of fields
case TYPE_RECORD:
tnew = new RecordType(t->AsRecordType()->Types());
}
else
{
break;
case TYPE_TABLE:
tnew = new TableType(t->AsTableType()->Indices(),
t->AsTableType()->YieldType());
break;
case TYPE_VECTOR:
tnew = new VectorType(t->AsVectorType()->YieldType());
break;
case TYPE_FUNC:
tnew = new FuncType(t->AsFuncType()->Args(),
t->AsFuncType()->YieldType(),
t->AsFuncType()->IsEvent());
break;
default:
SerializationFormat* form = new BinarySerializationFormat();
form->StartWrite();
CloneSerializer ss(form);
@ -267,7 +278,7 @@ void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */)
tnew = t->Unserialize(&uinfo);
delete [] data;
}
}
tnew->SetTypeID(copy_string(id->Name()));
}

View file

@ -39,7 +39,6 @@ extern BroType* internal_type(const char* name);
extern Func* internal_func(const char* name);
extern EventHandlerPtr internal_handler(const char* name);
extern EventHandlerPtr bro_signal;
extern int signal_val; // 0 if no signal pending
#endif

View file

@ -3,9 +3,6 @@
event bro_init%(%);
event bro_done%(%);
# bro_signal is initiated in main.cc
# event bro_signal%(signal: count%);
event dns_mapping_valid%(dm: dns_mapping%);
event dns_mapping_unverified%(dm: dns_mapping%);
event dns_mapping_new_name%(dm: dns_mapping%);
@ -52,6 +49,7 @@ event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count,
event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%);
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_redirect%(c: connection, icmp: icmp_conn, a: addr%);
event net_stats_update%(t: time, ns: net_stats%);
event conn_stats%(c: connection, os: endpoint_stats, rs: endpoint_stats%);
event conn_weird%(name: string, c: connection%);

View file

@ -77,7 +77,6 @@ Logger* bro_logger;
LogMgr* log_mgr;
Func* alarm_hook = 0;
Stmt* stmts;
EventHandlerPtr bro_signal = 0;
EventHandlerPtr net_done = 0;
RuleMatcher* rule_matcher = 0;
PersistenceSerializer* persistence_serializer = 0;
@ -827,7 +826,6 @@ int main(int argc, char** argv)
BroFile::SetDefaultRotation(log_rotate_interval, log_max_size);
alarm_hook = internal_func("alarm_hook");
bro_signal = internal_handler("bro_signal");
net_done = internal_handler("net_done");
if ( ! g_policy_debug )

View file

@ -936,6 +936,7 @@ type_decl:
if ( generate_documentation )
{
// TypeDecl ctor deletes the attr list, so make a copy
attr_list* a = $5;
attr_list* a_copy = 0;
@ -947,7 +948,7 @@ type_decl:
}
last_fake_type_decl = new CommentedTypeDecl(
$4, $2, a_copy, concat_opt_docs($1, $7));
$4, $2, a_copy, (in_record > 0), concat_opt_docs($1, $7));
}
$$ = new TypeDecl($4, $2, $5, (in_record > 0));
@ -1059,7 +1060,8 @@ decl:
BroDocObj* o = new BroDocObj(fake_id, reST_doc_comments, true);
o->SetRole(true);
if ( streq(fake_id->Name(), "Notice" ) )
if ( extract_module_name(fake_id->Name()) == "Notice" &&
extract_var_name(fake_id->Name()) == "Type" )
current_reST_doc->AddNotice(o);
else
current_reST_doc->AddRedef(o);
@ -1091,8 +1093,10 @@ decl:
new RecordType(fake_type_decl_list);
ID* fake = create_dummy_id($3, fake_record);
fake_type_decl_list = 0;
current_reST_doc->AddRedef(
new BroDocObj(fake, reST_doc_comments, true));
BroDocObj* o =
new BroDocObj(fake, reST_doc_comments, true);
o->SetRole(true);
current_reST_doc->AddRedef(o);
}
else
{

View file

@ -610,7 +610,7 @@ static int load_files_with_prefix(const char* orig_file)
if ( generate_documentation )
{
current_reST_doc = new BroDoc(full_filename);
current_reST_doc = new BroDoc(file, full_filename);
docs_generated.push_back(current_reST_doc);
}
}

View file

@ -98,23 +98,23 @@ Namespaces
Notices
~~~~~~~
:bro:type:`Notice`
:bro:type:`Notice::Type`
:Type: :bro:type:`enum`
.. bro:enum:: Example::Notice_One Notice
.. bro:enum:: Example::Notice_One Notice::Type
any number of this type of comment
will document "Notice_One"
.. bro:enum:: Example::Notice_Two Notice
.. bro:enum:: Example::Notice_Two Notice::Type
any number of this type of comment
will document "Notice_Two"
.. bro:enum:: Example::Notice_Three Notice
.. bro:enum:: Example::Notice_Three Notice::Type
.. bro:enum:: Example::Notice_Four Notice
.. bro:enum:: Example::Notice_Four Notice::Type
Public Interface
----------------
@ -279,7 +279,7 @@ Redefinitions
document the "SimpleEnum" redef here
.. bro:type:: Example::SimpleRecord
:bro:type:`Example::SimpleRecord`
:Type: :bro:type:`record`

View file

@ -1,99 +0,0 @@
.. Automatically generated. Do not edit.
autogen-reST-record-add.bro
===========================
:download:`Original Source File <autogen-reST-record-add.bro>`
Overview
--------
Summary
~~~~~~~
State Variables
###############
===================================== =
:bro:id:`a`: :bro:type:`my_record`
:bro:id:`b`: :bro:type:`super_record`
===================================== =
Types
#####
============================================ =
:bro:type:`my_record`: :bro:type:`record`
:bro:type:`super_record`: :bro:type:`record`
============================================ =
Functions
#########
===================================== =
:bro:id:`test_func`: :bro:type:`func`
===================================== =
Redefinitions
#############
========================================= =
:bro:type:`my_record`: :bro:type:`record`
========================================= =
Public Interface
----------------
State Variables
~~~~~~~~~~~~~~~
.. bro:id:: a
:Type: :bro:type:`my_record`
:Default:
::
{
field1=<uninitialized>
field2=<uninitialized>
field3=<uninitialized>
}
.. bro:id:: b
:Type: :bro:type:`super_record`
:Default:
::
{
rec=[field1=<uninitialized>, field2=<uninitialized>, field3=<uninitialized>]
}
Types
~~~~~
.. bro:type:: my_record
:Type: :bro:type:`record`
field1: :bro:type:`bool`
field2: :bro:type:`string`
.. bro:type:: super_record
:Type: :bro:type:`record`
rec: :bro:type:`my_record`
Functions
~~~~~~~~~
.. bro:id:: test_func
:Type: :bro:type:`function` () : :bro:type:`void`
Redefinitions
~~~~~~~~~~~~~
.. bro:type:: my_record
:Type: :bro:type:`record`
field3: :bro:type:`count` :bro:attr:`&optional`

View file

@ -1,12 +1,11 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
# @TEST-EXEC: btest-diff autogen-reST-record-add.rst
# When in doc mode, bro will clone declared types (see add_type() in Var.cc)
# in order to keep track of the identifier name associated with the new type.
# This test makes sure that the cloning is done in a way that's compatible
# with adding fields to a record type -- we want to be sure that cloning
# a record that contains other record fields will correctly see field
# additions to those contained-records.
# a type that contains record types will correctly see field additions to
# those contained-records.
type my_record: record {
field1: bool;
@ -16,17 +15,22 @@ type my_record: record {
type super_record: record {
rec: my_record;
};
type my_table: table[count] of my_record;
type my_vector: vector of my_record;
redef record my_record += {
field3: count &optional;
};
global a: my_record;
global b: super_record;
global c: my_table;
global d: my_vector;
function test_func()
{
{
a?$field3;
b$rec?$field3;
}
c[0]$field3;
d[0]$field3;
}

View file

@ -0,0 +1,9 @@
# @TEST-EXEC: bro --doc-scripts %INPUT
type Tag: enum {
SOMETHING
};
type R: record {
field1: set[Tag] &default=set();
};