mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Merge remote-tracking branch 'origin/master' into topic/seth/faf-updates
Conflicts: scripts/base/frameworks/files/main.bro scripts/base/init-bare.bro scripts/base/protocols/ftp/file-analysis.bro scripts/base/protocols/http/file-analysis.bro scripts/base/protocols/irc/file-analysis.bro scripts/base/protocols/smtp/file-analysis.bro src/const.bif src/event.bif src/file_analysis/Analyzer.h src/file_analysis/file_analysis.bif
This commit is contained in:
commit
58d133e764
555 changed files with 16982 additions and 13190 deletions
120
CHANGES
120
CHANGES
|
@ -1,4 +1,124 @@
|
|||
|
||||
2.1-784 | 2013-07-04 22:28:48 -0400
|
||||
|
||||
* Add a call to lookup_connection in SSH scripts to update connval. (Seth Hall)
|
||||
|
||||
* Updating submodule(s). (Robin Sommer)
|
||||
|
||||
2.1-782 | 2013-07-03 17:00:39 -0700
|
||||
|
||||
* Remove the SSL log queueing mechanism that was included with the
|
||||
log delay mechanism. (Seth Hall)
|
||||
|
||||
2.1-780 | 2013-07-03 16:46:26 -0700
|
||||
|
||||
* Rewrite of the RAW input reader for improved robustness and new
|
||||
features. (Bernhard Amann) This includes:
|
||||
|
||||
- Send "end_of_data" event for all kind of streams.
|
||||
- Send "process_finished" event with exit code of child
|
||||
process at process termination.
|
||||
- Expose name of input stream to readers.
|
||||
- Better error handling.
|
||||
- New "force_kill" option which SIGKILLs processes on reader termination.
|
||||
- Supports reading from stdout and stderr simultaneously.
|
||||
- Support sending data to stdin of child process.
|
||||
- Streaming reads from external commands work without blocking.
|
||||
|
||||
2.1-762 | 2013-07-03 16:33:22 -0700
|
||||
|
||||
* Fix to correct support for TLS 1.2. Addresses #1020. (Seth Hall,
|
||||
with help from Rafal Lesniak).
|
||||
|
||||
2.1-760 | 2013-07-03 16:31:36 -0700
|
||||
|
||||
* Teach broxygen to generate protocol analyzer plugin reference.
|
||||
(Jon Siwek)
|
||||
|
||||
* Adding 'const' to a number of C++ methods. (Jon Siwek)
|
||||
|
||||
2.1-757 | 2013-07-03 16:28:10 -0700
|
||||
|
||||
* Fix redef of table index from clearing table.
|
||||
|
||||
`redef foo["x"] = 1` now acts like `redef foo += { ["x"] = 1 }`
|
||||
instead of `redef foo = { ["x"] = 1 }`.
|
||||
|
||||
Addresses #1013. (Jon Siwek)
|
||||
|
||||
|
||||
2.1-755 | 2013-07-03 16:22:43 -0700
|
||||
|
||||
* Add a general file analysis overview/how-to document. (Jon Siwek)
|
||||
|
||||
* Improve file analysis doxygen comments. (Jon Siwek)
|
||||
|
||||
* Improve tracking of HTTP file extraction. http.log now has files
|
||||
taken from request and response bodies in different fields for
|
||||
each, and can now track multiple files per body. That is, the
|
||||
"extraction_file" field is now "extracted_request_files" and
|
||||
"extracted_response_files". Addresses #988. (Jon Siwek)
|
||||
|
||||
* Fix HTTP multipart body file analysis. Each part now gets assigned
|
||||
a different file handle/id. (Jon Siwek)
|
||||
|
||||
* Remove logging of analyzers field of FileAnalysis::Info. (Jon
|
||||
Siwek)
|
||||
|
||||
* Remove extraction counter in default file extraction scripts. (Jon
|
||||
Siwek)
|
||||
|
||||
* Remove FileAnalysis::postpone_timeout.
|
||||
FileAnalysis::set_timeout_interval can now perform same function.
|
||||
(Jon Siwek)
|
||||
|
||||
* Make default get_file_handle handlers &priority=5 so they're
|
||||
easier to override. (Jon Siwek)
|
||||
|
||||
* Add input interface to forward data for file analysis. The new
|
||||
Input::add_analysis function is used to automatically forward
|
||||
input data on to the file analysis framework. (Jon Siwek)
|
||||
|
||||
* File analysis framework interface simplifications. (Jon Siwek)
|
||||
|
||||
- Remove script-layer data input interface (will be managed directly
|
||||
by input framework later).
|
||||
|
||||
- Only track files internally by file id hash. Chance of collision
|
||||
too small to justify also tracking unique file string.
|
||||
|
||||
|
||||
2.1-741 | 2013-06-07 17:28:50 -0700
|
||||
|
||||
* Fixing typo that could cause an assertion to falsely trigger.
|
||||
(Robin Sommer)
|
||||
|
||||
2.1-740 | 2013-06-07 16:37:32 -0700
|
||||
|
||||
* Fix for CMake 2.6.x. (Robin Sommer)
|
||||
|
||||
2.1-738 | 2013-06-07 08:38:13 -0700
|
||||
|
||||
* Remove invalid free on non-allocated pointer in hash function
|
||||
object. Addresses #1018. (Matthias Vallentin)
|
||||
|
||||
2.1-736 | 2013-06-06 10:05:20 -0700
|
||||
|
||||
* New "magic constants" @DIR and @FILENAME that expand to the
|
||||
directory path of the current script and just the script file name
|
||||
without path, respectively. (Jon Siwek)
|
||||
|
||||
2.1-731 | 2013-06-04 21:19:08 -0700
|
||||
|
||||
* Reorginization of internal protocol analyzer code. We're moving
|
||||
them to a modularized structure, based on a plugin model. Along
|
||||
with this change comes generic plugin infrastructure that we'll
|
||||
later extend to other Bro component as well. For now all plugins
|
||||
are compiled in statically, but in the future we plan to also
|
||||
enable dynamic loading at run time. (Robin Sommer)
|
||||
|
||||
* Ignoring file ids in external tests. (Robin Sommer)
|
||||
|
||||
2.1-675 | 2013-06-02 20:03:19 -0700
|
||||
|
||||
* Fix a compiler warning. (Robin Sommer)
|
||||
|
|
14
NEWS
14
NEWS
|
@ -68,11 +68,17 @@ New Functionality
|
|||
|
||||
global foo: function(s: string, t: string &default="abc", u: count &default=0);
|
||||
|
||||
- Scripts can now use two new "magic constants" @DIR and @FILENAME
|
||||
that expand to the directory path of the current script and just the
|
||||
script file name without path, respectively. (Jon Siwek)
|
||||
|
||||
- The new file analysis framework moves most of the processing of file
|
||||
content from script-land into the core, where it belongs. Much of
|
||||
this is an internal change, the framework comes with the following
|
||||
user-visibible functionality (some of that was already available
|
||||
before, but done differently):
|
||||
content from script-land into the core, where it belongs. See
|
||||
doc/file-analysis.rst for more information.
|
||||
|
||||
Much of this is an internal change, but the framework also comes
|
||||
with the following user-visibible functionality (some of that was
|
||||
already available before, but done differently):
|
||||
|
||||
[TODO: This will probably change with further script updates.]
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.1-675
|
||||
2.1-784
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f86a3169b8d49189d264cbc1a7507260cd9ff51d
|
||||
Subproject commit c39bd478b9d0ecd05b1b83aa9d09a7887893977c
|
|
@ -1 +1 @@
|
|||
Subproject commit cfaf4eea788bdac4ebfe9e46e3de2cd74b0bc068
|
||||
Subproject commit a9942558c7d3dfd80148b8aaded64c82ade3d117
|
|
@ -1 +1 @@
|
|||
Subproject commit 8955807b0f4151f5f6aca2e68d353b9b341d9f86
|
||||
Subproject commit 889f9c65944ceac20ad9230efc39d33e6e1221c3
|
|
@ -1 +1 @@
|
|||
Subproject commit 0eca32b35d16a4d387f41976ab46360ee6ecaed8
|
||||
Subproject commit 017e7732446b36af935c26834394b51829335e7c
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
broPolicies=${BRO_SCRIPT_SOURCE_PATH}:${BRO_SCRIPT_SOURCE_PATH}/policy:${BRO_SCRIPT_SOURCE_PATH}/site
|
||||
|
||||
broGenPolicies=${CMAKE_BINARY_DIR}/src
|
||||
broGenPolicies=${CMAKE_BINARY_DIR}/scripts
|
||||
|
||||
installedPolicies=${BRO_SCRIPT_INSTALL_PATH}:${BRO_SCRIPT_INSTALL_PATH}/site
|
||||
|
||||
|
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
|||
Subproject commit e1a7fd00a0a66d6831a239fe84f5fcfaa54e2c35
|
||||
Subproject commit 0187b33a29d5ec824f940feff60dc5d8c2fe314f
|
|
@ -82,7 +82,8 @@ class BroGeneric(ObjectDescription):
|
|||
|
||||
objects = self.env.domaindata['bro']['objects']
|
||||
key = (self.objtype, name)
|
||||
if key in objects:
|
||||
if ( key in objects and self.objtype != "id" and
|
||||
self.objtype != "type" ):
|
||||
self.env.warn(self.env.docname,
|
||||
'duplicate description of %s %s, ' %
|
||||
(self.objtype, name) +
|
||||
|
@ -150,6 +151,12 @@ class BroEnum(BroGeneric):
|
|||
#self.indexnode['entries'].append(('single', indextext,
|
||||
# targetname, targetname))
|
||||
m = sig.split()
|
||||
|
||||
if len(m) < 2:
|
||||
self.env.warn(self.env.docname,
|
||||
"bro:enum directive missing argument(s)")
|
||||
return
|
||||
|
||||
if m[1] == "Notice::Type":
|
||||
if 'notices' not in self.env.domaindata['bro']:
|
||||
self.env.domaindata['bro']['notices'] = []
|
||||
|
|
|
@ -10,7 +10,7 @@ File Analysis
|
|||
script-layer depending on which network protocol was involved in the
|
||||
file transfer. Scripts written to analyze files over one protocol
|
||||
would have to be copied and modified to fit other protocols. The
|
||||
file analysis framework (FAF) is an attempt to provide a generalized
|
||||
file analysis framework (FAF) instead provides a generalized
|
||||
presentation of file-related information. The information regarding
|
||||
the protocol involved in transporting a file over the network is
|
||||
still available, but it no longer has to dictate how one organizes
|
||||
|
|
|
@ -46,7 +46,7 @@ Script Reference
|
|||
scripts/packages
|
||||
scripts/index
|
||||
scripts/builtins
|
||||
scripts/bifs
|
||||
scripts/proto-analyzers
|
||||
|
||||
Other Bro Components
|
||||
--------------------
|
||||
|
|
|
@ -15,11 +15,11 @@ endif ()
|
|||
#
|
||||
# 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
|
||||
# argument will be used to derive what path under scripts/ 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.
|
||||
# If this is not given, the group is automatically set to any path portion
|
||||
# of the broInput argument.
|
||||
#
|
||||
# In addition to adding the makefile target, several CMake variables are set:
|
||||
#
|
||||
|
@ -45,12 +45,6 @@ macro(REST_TARGET srcDir broInput)
|
|||
|
||||
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}")
|
||||
|
@ -70,8 +64,6 @@ macro(REST_TARGET srcDir broInput)
|
|||
|
||||
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
|
||||
|
@ -132,6 +124,29 @@ endmacro(REST_TARGET)
|
|||
# Schedule Bro scripts for which to generate documentation.
|
||||
include(DocSourcesList.cmake)
|
||||
|
||||
# This reST target is independent of a particular Bro script...
|
||||
add_custom_command(OUTPUT proto-analyzers.rst
|
||||
# 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} BROMAGIC=${CMAKE_SOURCE_DIR}/magic ${CMAKE_BINARY_DIR}/src/bro
|
||||
ARGS -b -Z base/init-bare.bro || (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 proto-analyzers.rst ${dstDir}
|
||||
# clean up the build directory
|
||||
COMMAND rm
|
||||
ARGS -rf .state *.log *.rst
|
||||
DEPENDS bro
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "[Bro] Generating reST docs for proto-analyzers.rst"
|
||||
)
|
||||
list(APPEND ALL_REST_OUTPUTS proto-analyzers.rst)
|
||||
|
||||
# create temporary list of all docs to include in the master policy/index file
|
||||
file(WRITE ${MASTER_POLICY_INDEX} "${MASTER_POLICY_INDEX_TEXT}")
|
||||
|
||||
|
|
|
@ -16,15 +16,64 @@ 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/file_analysis.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/src base/input.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(${CMAKE_BINARY_DIR}/scripts base/bif/analyzer.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/bro.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/const.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/event.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/file_analysis.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/input.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/logging.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ARP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_AYIYA.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_BackDoor.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_BitTorrent.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ConnSize.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DCE_RPC.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DHCP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DNS.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FTP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FTP.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_File.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FileHash.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Finger.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_GTPv1.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Gnutella.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_HTTP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_HTTP.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ICMP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_IRC.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Ident.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_InterConn.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Login.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Login.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_MIME.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Modbus.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NCP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NTP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetBIOS.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetBIOS.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetFlow.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_PIA.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_POP3.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_RPC.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMB.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMTP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMTP.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SOCKS.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSH.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSL.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSL.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SteppingStone.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Syslog.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_TCP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_TCP.functions.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Teredo.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_UDP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ZIP.events.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/reporter.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/strings.bif.bro)
|
||||
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/types.bif.bro)
|
||||
rest_target(${psd} base/frameworks/analyzer/main.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)
|
||||
|
@ -146,7 +195,6 @@ 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/integration/collective-intel/main.bro)
|
||||
rest_target(${psd} policy/misc/analysis-groups.bro)
|
||||
rest_target(${psd} policy/misc/app-metrics.bro)
|
||||
rest_target(${psd} policy/misc/capture-loss.bro)
|
||||
rest_target(${psd} policy/misc/detect-traceroute/main.bro)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
.. This is a stub doc to which broxygen appends during the build process
|
||||
|
||||
Built-In Functions (BIFs)
|
||||
=========================
|
||||
|
|
@ -54,11 +54,11 @@ 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]
|
||||
};
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, example_ports);
|
||||
}
|
||||
|
||||
# redefinitions of "Notice::Type" are self-documenting, but
|
||||
# more information can be supplied in two different ways
|
||||
|
|
|
@ -67,12 +67,12 @@ sourcedir=${thisdir}/../..
|
|||
|
||||
echo "$statictext" > $outfile
|
||||
|
||||
bifs=`( cd ${sourcedir}/src && find . -name \*\.bif | sort )`
|
||||
bifs=`( cd ${sourcedir}/build/scripts/base && find . -name \*\.bif.bro | sort )`
|
||||
|
||||
for file in $bifs
|
||||
do
|
||||
f=${file:2}.bro
|
||||
echo "rest_target(\${CMAKE_BINARY_DIR}/src base/$f)" >> $outfile
|
||||
f=${file:2}
|
||||
echo "rest_target(\${CMAKE_BINARY_DIR}/scripts base/$f)" >> $outfile
|
||||
done
|
||||
|
||||
scriptfiles=`( cd ${sourcedir}/scripts && find . -name \*\.bro | sort )`
|
||||
|
|
1
scripts/base/frameworks/analyzer/__load__.bro
Normal file
1
scripts/base/frameworks/analyzer/__load__.bro
Normal file
|
@ -0,0 +1 @@
|
|||
@load ./main
|
179
scripts/base/frameworks/analyzer/main.bro
Normal file
179
scripts/base/frameworks/analyzer/main.bro
Normal file
|
@ -0,0 +1,179 @@
|
|||
##! Framework for managing Bro's protocol analyzers.
|
||||
##!
|
||||
##! The analyzer framework allows to dynamically enable or disable analyzers, as
|
||||
##! well as to manage the well-known ports which automatically activate a
|
||||
##! particular analyzer for new connections.
|
||||
##!
|
||||
##! Protocol analyzers are identified by unique tags of type
|
||||
##! :bro:type:`Analyzer::Tag`, such as :bro:enum:`Analyzer::ANALYZER_HTTP` and
|
||||
##! :bro:enum:`Analyzer::ANALYZER_HTTP`. These tags are defined internally by
|
||||
##! the analyzers themselves, and documented in their analyzer-specific
|
||||
##! description along with the events that they generate.
|
||||
|
||||
module Analyzer;
|
||||
|
||||
export {
|
||||
## If true, all available analyzers are initially disabled at startup. One
|
||||
## can then selectively enable them with
|
||||
## :bro:id:`Analyzer::enable_analyzer`.
|
||||
global disable_all = F &redef;
|
||||
|
||||
## Enables an analyzer. Once enabled, the analyzer may be used for analysis
|
||||
## of future connections as decided by Bro's dynamic protocol detection.
|
||||
##
|
||||
## tag: The tag of the analyzer to enable.
|
||||
##
|
||||
## Returns: True if the analyzer was successfully enabled.
|
||||
global enable_analyzer: function(tag: Analyzer::Tag) : bool;
|
||||
|
||||
## Disables an analyzer. Once disabled, the analyzer will not be used
|
||||
## further for analysis of future connections.
|
||||
##
|
||||
## tag: The tag of the analyzer to disable.
|
||||
##
|
||||
## Returns: True if the analyzer was successfully disabled.
|
||||
global disable_analyzer: function(tag: Analyzer::Tag) : bool;
|
||||
|
||||
## Registers a set of well-known ports for an analyzer. If a future
|
||||
## connection on one of these ports is seen, the analyzer will be
|
||||
## automatically assigned to parsing it. The function *adds* to all ports
|
||||
## already registered, it doesn't replace them.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## ports: The set of well-known ports to associate with the analyzer.
|
||||
##
|
||||
## Returns: True if the ports were sucessfully registered.
|
||||
global register_for_ports: function(tag: Analyzer::Tag, ports: set[port]) : bool;
|
||||
|
||||
## Registers an individual well-known port for an analyzer. If a future
|
||||
## connection on this port is seen, the analyzer will be automatically
|
||||
## assigned to parsing it. The function *adds* to all ports already
|
||||
## registered, it doesn't replace them.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## p: The well-known port to associate with the analyzer.
|
||||
##
|
||||
## Returns: True if the port was sucessfully registered.
|
||||
global register_for_port: function(tag: Analyzer::Tag, p: port) : bool;
|
||||
|
||||
## Returns a set of all well-known ports currently registered for a
|
||||
## specific analyzer.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## Returns: The set of ports.
|
||||
global registered_ports: function(tag: Analyzer::Tag) : set[port];
|
||||
|
||||
## Returns a table of all ports-to-analyzer mappings currently registered.
|
||||
##
|
||||
## Returns: A table mapping each analyzer to the set of ports
|
||||
## registered for it.
|
||||
global all_registered_ports: function() : table[Analyzer::Tag] of set[port];
|
||||
|
||||
## Translates an analyzer type to a string with the analyzer's name.
|
||||
##
|
||||
## tag: The analyzer tag.
|
||||
##
|
||||
## Returns: The analyzer name corresponding to the tag.
|
||||
global name: function(tag: Analyzer::Tag) : string;
|
||||
|
||||
## Schedules an analyzer for a future connection originating from a given IP
|
||||
## address and port.
|
||||
##
|
||||
## orig: The IP address originating a connection in the future.
|
||||
## 0.0.0.0 can be used as a wildcard to match any originator address.
|
||||
##
|
||||
## resp: The IP address responding to a connection from *orig*.
|
||||
##
|
||||
## resp_p: The destination port at *resp*.
|
||||
##
|
||||
## analyzer: The analyzer ID.
|
||||
##
|
||||
## tout: A timeout interval after which the scheduling request will be
|
||||
## discarded if the connection has not yet been seen.
|
||||
##
|
||||
## Returns: True if succesful.
|
||||
global schedule_analyzer: function(orig: addr, resp: addr, resp_p: port,
|
||||
analyzer: Analyzer::Tag, tout: interval) : bool;
|
||||
|
||||
## A set of analyzers to disable by default at startup. The default set
|
||||
## contains legacy analyzers that are no longer supported.
|
||||
global disabled_analyzers: set[Analyzer::Tag] = {
|
||||
ANALYZER_INTERCONN,
|
||||
ANALYZER_STEPPINGSTONE,
|
||||
ANALYZER_BACKDOOR,
|
||||
ANALYZER_TCPSTATS,
|
||||
} &redef;
|
||||
}
|
||||
|
||||
@load base/bif/analyzer.bif
|
||||
|
||||
global ports: table[Analyzer::Tag] of set[port];
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
if ( disable_all )
|
||||
__disable_all_analyzers();
|
||||
|
||||
for ( a in disabled_analyzers )
|
||||
disable_analyzer(a);
|
||||
}
|
||||
|
||||
function enable_analyzer(tag: Analyzer::Tag) : bool
|
||||
{
|
||||
return __enable_analyzer(tag);
|
||||
}
|
||||
|
||||
function disable_analyzer(tag: Analyzer::Tag) : bool
|
||||
{
|
||||
return __disable_analyzer(tag);
|
||||
}
|
||||
|
||||
function register_for_ports(tag: Analyzer::Tag, ports: set[port]) : bool
|
||||
{
|
||||
local rc = T;
|
||||
|
||||
for ( p in ports )
|
||||
{
|
||||
if ( ! register_for_port(tag, p) )
|
||||
rc = F;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
function register_for_port(tag: Analyzer::Tag, p: port) : bool
|
||||
{
|
||||
if ( ! __register_for_port(tag, p) )
|
||||
return F;
|
||||
|
||||
if ( tag !in ports )
|
||||
ports[tag] = set();
|
||||
|
||||
add ports[tag][p];
|
||||
return T;
|
||||
}
|
||||
|
||||
function registered_ports(tag: Analyzer::Tag) : set[port]
|
||||
{
|
||||
return tag in ports ? ports[tag] : set();
|
||||
}
|
||||
|
||||
function all_registered_ports(): table[Analyzer::Tag] of set[port]
|
||||
{
|
||||
return ports;
|
||||
}
|
||||
|
||||
function name(atype: Analyzer::Tag) : string
|
||||
{
|
||||
return __name(atype);
|
||||
}
|
||||
|
||||
function schedule_analyzer(orig: addr, resp: addr, resp_p: port,
|
||||
analyzer: Analyzer::Tag, tout: interval) : bool
|
||||
{
|
||||
return __schedule_analyzer(orig, resp, resp_p, analyzer, tout);
|
||||
}
|
||||
|
|
@ -41,22 +41,11 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(DPD::LOG, [$columns=Info]);
|
||||
|
||||
# Populate the internal DPD analysis variable.
|
||||
for ( a in dpd_config )
|
||||
{
|
||||
for ( p in dpd_config[a]$ports )
|
||||
{
|
||||
if ( p !in dpd_analyzer_ports )
|
||||
dpd_analyzer_ports[p] = set();
|
||||
add dpd_analyzer_ports[p][a];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=10
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=10
|
||||
{
|
||||
local analyzer = analyzer_name(atype);
|
||||
local analyzer = Analyzer::name(atype);
|
||||
|
||||
if ( fmt("-%s",analyzer) in c$service )
|
||||
delete c$service[fmt("-%s", analyzer)];
|
||||
|
@ -64,10 +53,10 @@ event protocol_confirmation(c: connection, atype: count, aid: count) &priority=1
|
|||
add c$service[analyzer];
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=10
|
||||
{
|
||||
local analyzer = analyzer_name(atype);
|
||||
local analyzer = Analyzer::name(atype);
|
||||
# If the service hasn't been confirmed yet, don't generate a log message
|
||||
# for the protocol violation.
|
||||
if ( analyzer !in c$service )
|
||||
|
@ -86,7 +75,7 @@ event protocol_violation(c: connection, atype: count, aid: count,
|
|||
c$dpd = info;
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=5
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=5
|
||||
{
|
||||
if ( !c?$dpd || aid in c$dpd$disabled_aids )
|
||||
return;
|
||||
|
@ -100,7 +89,7 @@ event protocol_violation(c: connection, atype: count, aid: count, reason: string
|
|||
add c$dpd$disabled_aids[aid];
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=-5
|
||||
{
|
||||
if ( c?$dpd )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
##! An interface for driving the analysis of files, possibly independent of
|
||||
##! any network protocol over which they're transported.
|
||||
|
||||
@load base/file_analysis.bif
|
||||
@load base/bif/file_analysis.bif
|
||||
@load base/frameworks/logging
|
||||
@load base/utils/site
|
||||
|
||||
|
@ -105,7 +105,7 @@ export {
|
|||
|
||||
## A table that can be used to disable file analysis completely for
|
||||
## any files transferred over given network protocol analyzers.
|
||||
const disable: table[AnalyzerTag] of bool = table() &redef;
|
||||
const disable: table[Analyzer::Tag] of bool = table() &redef;
|
||||
|
||||
## The salt concatenated to unique file handle strings generated by
|
||||
## :bro:see:`get_file_handle` before hashing them in to a file id
|
||||
|
|
|
@ -125,7 +125,6 @@ export {
|
|||
## A file analyis input stream type used to forward input data to the
|
||||
## file analysis framework.
|
||||
type AnalysisDescription: record {
|
||||
|
||||
## String that allows the reader to find the source.
|
||||
## For `READER_ASCII`, this is the filename.
|
||||
source: string;
|
||||
|
@ -186,7 +185,7 @@ export {
|
|||
global end_of_data: event(name: string, source:string);
|
||||
}
|
||||
|
||||
@load base/input.bif
|
||||
@load base/bif/input.bif
|
||||
|
||||
|
||||
module Input;
|
||||
|
|
|
@ -6,4 +6,12 @@ export {
|
|||
## Separator between input records.
|
||||
## Please note that the separator has to be exactly one character long
|
||||
const record_separator = "\n" &redef;
|
||||
|
||||
## Event that is called when a process created by the raw reader exits.
|
||||
##
|
||||
## name: name of the input stream
|
||||
## source: source of the input stream
|
||||
## exit_code: exit code of the program, or number of the signal that forced the program to exit
|
||||
## signal_exit: false when program exitted normally, true when program was forced to exit by a signal
|
||||
global process_finished: event(name: string, source:string, exit_code:count, signal_exit:bool);
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ export {
|
|||
# We keep a script-level copy of all filters so that we can manipulate them.
|
||||
global filters: table[ID, string] of Filter;
|
||||
|
||||
@load base/logging.bif # Needs Filter and Stream defined.
|
||||
@load base/bif/logging.bif # Needs Filter and Stream defined.
|
||||
|
||||
module Log;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
##! Note that this framework deals with the handling of internally generated
|
||||
##! reporter messages, for the interface in to actually creating interface
|
||||
##! into actually creating reporter messages from the scripting layer, use
|
||||
##! the built-in functions in :doc:`/scripts/base/reporter.bif`.
|
||||
##! the built-in functions in :doc:`/scripts/base/bif/reporter.bif`.
|
||||
|
||||
module Reporter;
|
||||
|
||||
|
|
|
@ -83,19 +83,17 @@ export {
|
|||
}
|
||||
|
||||
const ayiya_ports = { 5072/udp };
|
||||
redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] };
|
||||
|
||||
const teredo_ports = { 3544/udp };
|
||||
redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] };
|
||||
|
||||
const gtpv1_ports = { 2152/udp, 2123/udp };
|
||||
redef dpd_config += { [ANALYZER_GTPV1] = [$ports = gtpv1_ports] };
|
||||
|
||||
redef likely_server_ports += { ayiya_ports, teredo_ports, gtpv1_ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Tunnel::LOG, [$columns=Info]);
|
||||
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_AYIYA, ayiya_ports);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_TEREDO, teredo_ports);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_GTPV1, gtpv1_ports);
|
||||
}
|
||||
|
||||
function register_all(ecv: EncapsulatingConnVector)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@load base/const.bif
|
||||
@load base/types.bif
|
||||
@load base/bif/const.bif.bro
|
||||
@load base/bif/types.bif
|
||||
|
||||
# Type declarations
|
||||
|
||||
|
@ -222,17 +222,6 @@ type endpoint_stats: record {
|
|||
endian_type: count;
|
||||
};
|
||||
|
||||
## A unique analyzer instance ID. Each time instantiates a protocol analyzers
|
||||
## for a connection, it assigns it a unique ID that can be used to reference
|
||||
## that instance.
|
||||
##
|
||||
## .. bro:see:: analyzer_name disable_analyzer protocol_confirmation
|
||||
## protocol_violation
|
||||
##
|
||||
## .. todo::While we declare an alias for the type here, the events/functions still
|
||||
## use ``count``. That should be changed.
|
||||
type AnalyzerID: count;
|
||||
|
||||
module Tunnel;
|
||||
export {
|
||||
## Records the identity of an encapsulating parent of a tunneled connection.
|
||||
|
@ -713,9 +702,9 @@ type entropy_test_result: record {
|
|||
};
|
||||
|
||||
# Prototypes of Bro built-in functions.
|
||||
@load base/strings.bif
|
||||
@load base/bro.bif
|
||||
@load base/reporter.bif
|
||||
@load base/bif/strings.bif
|
||||
@load base/bif/bro.bif
|
||||
@load base/bif/reporter.bif
|
||||
|
||||
## Deprecated. This is superseded by the new logging framework.
|
||||
global log_file_name: function(tag: string): string &redef;
|
||||
|
@ -2723,7 +2712,7 @@ export {
|
|||
}
|
||||
module GLOBAL;
|
||||
|
||||
@load base/event.bif
|
||||
@load base/bif/event.bif
|
||||
|
||||
## BPF filter the user has set via the -f command line options. Empty if none.
|
||||
const cmd_line_bpf_filter = "" &redef;
|
||||
|
@ -2913,34 +2902,11 @@ const remote_trace_sync_peers = 0 &redef;
|
|||
## consistency check.
|
||||
const remote_check_sync_consistency = F &redef;
|
||||
|
||||
## Analyzer tags. The core automatically defines constants
|
||||
## ``ANALYZER_<analyzer-name>*``, e.g., ``ANALYZER_HTTP``.
|
||||
##
|
||||
## .. bro:see:: dpd_config
|
||||
##
|
||||
## .. todo::We should autodoc these automaticallty generated constants.
|
||||
type AnalyzerTag: count;
|
||||
|
||||
## Set of ports activating a particular protocol analysis.
|
||||
##
|
||||
## .. bro:see:: dpd_config
|
||||
type dpd_protocol_config: record {
|
||||
ports: set[port] &optional; ##< Set of ports.
|
||||
};
|
||||
|
||||
## Port configuration for Bro's "dynamic protocol detection". Protocol
|
||||
## analyzers can be activated via either well-known ports or content analysis.
|
||||
## This table defines the ports.
|
||||
##
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size
|
||||
## dpd_match_only_beginning dpd_ignore_ports
|
||||
const dpd_config: table[AnalyzerTag] of dpd_protocol_config = {} &redef;
|
||||
|
||||
## Reassemble the beginning of all TCP connections before doing
|
||||
## signature-matching. Enabling this provides more accurate matching at the
|
||||
## expensive of CPU cycles.
|
||||
##
|
||||
## .. bro:see:: dpd_config dpd_buffer_size
|
||||
## .. bro:see:: dpd_buffer_size
|
||||
## dpd_match_only_beginning dpd_ignore_ports
|
||||
##
|
||||
## .. note:: Despite the name, this option affects *all* signature matching, not
|
||||
|
@ -2955,24 +2921,24 @@ const dpd_reassemble_first_packets = T &redef;
|
|||
## activated afterwards. Then only analyzers that can deal with partial
|
||||
## connections will be able to analyze the session.
|
||||
##
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_config dpd_match_only_beginning
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_match_only_beginning
|
||||
## dpd_ignore_ports
|
||||
const dpd_buffer_size = 1024 &redef;
|
||||
|
||||
## If true, stops signature matching if dpd_buffer_size has been reached.
|
||||
##
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size
|
||||
## dpd_config dpd_ignore_ports
|
||||
## dpd_ignore_ports
|
||||
##
|
||||
## .. note:: Despite the name, this option affects *all* signature matching, not
|
||||
## only signatures used for dynamic protocol detection.
|
||||
const dpd_match_only_beginning = T &redef;
|
||||
|
||||
## If true, don't consider any ports for deciding which protocol analyzer to
|
||||
## use. If so, the value of :bro:see:`dpd_config` is ignored.
|
||||
## use.
|
||||
##
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size
|
||||
## dpd_match_only_beginning dpd_config
|
||||
## dpd_match_only_beginning
|
||||
const dpd_ignore_ports = F &redef;
|
||||
|
||||
## Ports which the core considers being likely used by servers. For ports in
|
||||
|
@ -2980,13 +2946,6 @@ const dpd_ignore_ports = F &redef;
|
|||
## connection if it misses the initial handshake.
|
||||
const likely_server_ports: set[port] &redef;
|
||||
|
||||
## Deprated. Set of all ports for which we know an analyzer, built by
|
||||
## :doc:`/scripts/base/frameworks/dpd/main`.
|
||||
##
|
||||
## .. todo::This should be defined by :doc:`/scripts/base/frameworks/dpd/main`
|
||||
## itself we still need it.
|
||||
global dpd_analyzer_ports: table[port] of set[AnalyzerTag];
|
||||
|
||||
## Per-incident timer managers are drained after this amount of inactivity.
|
||||
const timer_mgr_inactivity_timeout = 1 min &redef;
|
||||
|
||||
|
@ -3095,10 +3054,12 @@ module GLOBAL;
|
|||
## Number of bytes per packet to capture from live interfaces.
|
||||
const snaplen = 8192 &redef;
|
||||
|
||||
# Load the logging framework here because it uses fairly deep integration with
|
||||
# Load BiFs defined by plugins.
|
||||
@load base/bif/plugins
|
||||
|
||||
# Load these frameworks here because they use fairly deep integration with
|
||||
# BiFs and script-land defined types.
|
||||
@load base/frameworks/logging
|
||||
|
||||
@load base/frameworks/input
|
||||
|
||||
@load base/frameworks/analyzer
|
||||
@load base/frameworks/files
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
# loaded in base/init-bare.bro
|
||||
#@load base/frameworks/logging
|
||||
@load base/frameworks/notice
|
||||
@load base/frameworks/analyzer
|
||||
@load base/frameworks/dpd
|
||||
@load base/frameworks/signatures
|
||||
@load base/frameworks/packet-filter
|
||||
|
|
|
@ -6,9 +6,9 @@ module Conn;
|
|||
export {
|
||||
## Define inactivity timeouts by the service detected being used over
|
||||
## the connection.
|
||||
const analyzer_inactivity_timeouts: table[AnalyzerTag] of interval = {
|
||||
const analyzer_inactivity_timeouts: table[Analyzer::Tag] of interval = {
|
||||
# For interactive services, allow longer periods of inactivity.
|
||||
[[ANALYZER_SSH, ANALYZER_FTP]] = 1 hrs,
|
||||
[[Analyzer::ANALYZER_SSH, Analyzer::ANALYZER_FTP]] = 1 hrs,
|
||||
} &redef;
|
||||
|
||||
## Define inactivity timeouts based on common protocol ports.
|
||||
|
@ -18,7 +18,7 @@ export {
|
|||
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count)
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count)
|
||||
{
|
||||
if ( atype in analyzer_inactivity_timeouts )
|
||||
set_inactivity_timeout(c$id, analyzer_inactivity_timeouts[atype]);
|
||||
|
|
|
@ -130,19 +130,13 @@ redef capture_filters += {
|
|||
["netbios-ns"] = "udp port 137",
|
||||
};
|
||||
|
||||
const dns_ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
redef dpd_config += { [ANALYZER_DNS] = [$ports = dns_ports] };
|
||||
|
||||
const dns_udp_ports = { 53/udp, 137/udp, 5353/udp, 5355/udp };
|
||||
const dns_tcp_ports = { 53/tcp };
|
||||
redef dpd_config += { [ANALYZER_DNS_UDP_BINPAC] = [$ports = dns_udp_ports] };
|
||||
redef dpd_config += { [ANALYZER_DNS_TCP_BINPAC] = [$ports = dns_tcp_ports] };
|
||||
|
||||
redef likely_server_ports += { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
const ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(DNS::LOG, [$columns=Info, $ev=log_dns]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, ports);
|
||||
}
|
||||
|
||||
function new_session(c: connection, trans_id: count): Info
|
||||
|
|
|
@ -111,11 +111,10 @@ redef record connection += {
|
|||
};
|
||||
|
||||
# Configure DPD
|
||||
const ports = { 21/tcp, 2811/tcp } &redef; # 2811/tcp is GridFTP.
|
||||
redef capture_filters += { ["ftp"] = "port 21 and port 2811" };
|
||||
redef dpd_config += { [ANALYZER_FTP] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 21/tcp, 2811/tcp };
|
||||
const ports = { 21/tcp, 2811/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
# Establish the variable for tracking expected connections.
|
||||
global ftp_data_expected: table[addr, port] of Info &read_expire=5mins;
|
||||
|
@ -123,6 +122,7 @@ global ftp_data_expected: table[addr, port] of Info &read_expire=5mins;
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(FTP::LOG, [$columns=Info, $ev=log_ftp]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_FTP, ports);
|
||||
}
|
||||
|
||||
## A set of commands where the argument can be expected to refer
|
||||
|
@ -221,7 +221,7 @@ function add_expected_data_channel(s: Info, chan: ExpectedDataChannel)
|
|||
s$passive = chan$passive;
|
||||
s$data_channel = chan;
|
||||
ftp_data_expected[chan$resp_h, chan$resp_p] = s;
|
||||
expect_connection(chan$orig_h, chan$resp_h, chan$resp_p, ANALYZER_FTP_DATA,
|
||||
Analyzer::schedule_analyzer(chan$orig_h, chan$resp_h, chan$resp_p, Analyzer::ANALYZER_FTP_DATA,
|
||||
5mins);
|
||||
}
|
||||
|
||||
|
@ -338,7 +338,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
|||
}
|
||||
}
|
||||
|
||||
event expected_connection_seen(c: connection, a: count) &priority=10
|
||||
event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10
|
||||
{
|
||||
local id = c$id;
|
||||
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
||||
|
|
|
@ -127,29 +127,26 @@ redef record connection += {
|
|||
http_state: State &optional;
|
||||
};
|
||||
|
||||
# Initialize the HTTP logging stream.
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(HTTP::LOG, [$columns=Info, $ev=log_http]);
|
||||
}
|
||||
|
||||
# DPD configuration.
|
||||
const ports = {
|
||||
80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3128/tcp,
|
||||
8000/tcp, 8080/tcp, 8888/tcp,
|
||||
};
|
||||
redef dpd_config += {
|
||||
[[ANALYZER_HTTP, ANALYZER_HTTP_BINPAC]] = [$ports = ports],
|
||||
};
|
||||
redef capture_filters += {
|
||||
["http"] = "tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888)"
|
||||
};
|
||||
|
||||
redef likely_server_ports += {
|
||||
80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3138/tcp,
|
||||
const ports = {
|
||||
80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3128/tcp,
|
||||
8000/tcp, 8080/tcp, 8888/tcp,
|
||||
};
|
||||
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
|
||||
# Initialize the HTTP logging stream and ports.
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(HTTP::LOG, [$columns=Info, $ev=log_http]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_HTTP, ports);
|
||||
}
|
||||
|
||||
function code_in_range(c: count, min: count, max: count) : bool
|
||||
{
|
||||
return c >= min && c <= max;
|
||||
|
|
|
@ -70,11 +70,11 @@ event irc_dcc_message(c: connection, is_orig: bool,
|
|||
c$irc$dcc_file_name = argument;
|
||||
c$irc$dcc_file_size = size;
|
||||
local p = count_to_port(dest_port, tcp);
|
||||
expect_connection(to_addr("0.0.0.0"), address, p, ANALYZER_IRC_DATA, 5 min);
|
||||
Analyzer::schedule_analyzer(0.0.0.0, address, p, Analyzer::ANALYZER_IRC_DATA, 5 min);
|
||||
dcc_expected_transfers[address, p] = c$irc;
|
||||
}
|
||||
|
||||
event expected_connection_seen(c: connection, a: count) &priority=10
|
||||
event expected_connection_seen(c: connection, a: Analyzer::Tag) &priority=10
|
||||
{
|
||||
local id = c$id;
|
||||
if ( [id$resp_h, id$resp_p] in dcc_expected_transfers )
|
||||
|
|
|
@ -45,14 +45,13 @@ redef capture_filters += { ["irc-6668"] = "port 6668" };
|
|||
redef capture_filters += { ["irc-6669"] = "port 6669" };
|
||||
|
||||
# DPD configuration.
|
||||
const irc_ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
redef dpd_config += { [ANALYZER_IRC] = [$ports = irc_ports] };
|
||||
|
||||
redef likely_server_ports += { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
const ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(IRC::LOG, [$columns=Info, $ev=irc_log]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_IRC, ports);
|
||||
}
|
||||
|
||||
function new_session(c: connection): Info
|
||||
|
|
|
@ -31,12 +31,14 @@ redef record connection += {
|
|||
|
||||
# Configure DPD and the packet filter.
|
||||
redef capture_filters += { ["modbus"] = "tcp port 502" };
|
||||
redef dpd_config += { [ANALYZER_MODBUS] = [$ports = set(502/tcp)] };
|
||||
redef likely_server_ports += { 502/tcp };
|
||||
|
||||
const ports = { 502/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Modbus::LOG, [$columns=Info, $ev=log_modbus]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_MODBUS, ports);
|
||||
}
|
||||
|
||||
event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool) &priority=5
|
||||
|
|
|
@ -74,9 +74,6 @@ export {
|
|||
const mail_path_capture = ALL_HOSTS &redef;
|
||||
|
||||
global log_smtp: event(rec: Info);
|
||||
|
||||
## Configure the default ports for SMTP analysis.
|
||||
const ports = { 25/tcp, 587/tcp } &redef;
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
|
@ -86,13 +83,14 @@ redef record connection += {
|
|||
|
||||
# Configure DPD
|
||||
redef capture_filters += { ["smtp"] = "tcp port 25 or tcp port 587" };
|
||||
redef dpd_config += { [ANALYZER_SMTP] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 25/tcp, 587/tcp };
|
||||
const ports = { 25/tcp, 587/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SMTP::LOG, [$columns=SMTP::Info, $ev=log_smtp]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SMTP, ports);
|
||||
}
|
||||
|
||||
function find_address_in_smtp_header(header: string): string
|
||||
|
|
|
@ -34,9 +34,13 @@ export {
|
|||
global log_socks: event(rec: Info);
|
||||
}
|
||||
|
||||
const ports = { 1080/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SOCKS, ports);
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
|
@ -45,7 +49,6 @@ redef record connection += {
|
|||
|
||||
# Configure DPD
|
||||
redef capture_filters += { ["socks"] = "tcp port 1080" };
|
||||
redef dpd_config += { [ANALYZER_SOCKS] = [$ports = set(1080/tcp)] };
|
||||
redef likely_server_ports += { 1080/tcp };
|
||||
|
||||
function set_session(c: connection, version: count)
|
||||
|
|
|
@ -71,10 +71,11 @@ export {
|
|||
}
|
||||
|
||||
# Configure DPD and the packet filter
|
||||
redef capture_filters += { ["ssh"] = "tcp port 22" };
|
||||
redef dpd_config += { [ANALYZER_SSH] = [$ports = set(22/tcp)] };
|
||||
|
||||
redef likely_server_ports += { 22/tcp };
|
||||
const ports = { 22/tcp };
|
||||
|
||||
redef capture_filters += { ["ssh"] = "tcp port 22" };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
redef record connection += {
|
||||
ssh: Info &optional;
|
||||
|
@ -83,6 +84,7 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports);
|
||||
}
|
||||
|
||||
function set_session(c: connection)
|
||||
|
@ -116,7 +118,7 @@ function check_ssh_connection(c: connection, done: bool)
|
|||
# Responder must have sent fewer than 40 packets.
|
||||
c$resp$num_pkts < 40 &&
|
||||
# If there was a content gap we can't reliably do this heuristic.
|
||||
c?$conn && c$conn$missed_bytes == 0)# &&
|
||||
c?$conn && c$conn$missed_bytes == 0 )# &&
|
||||
# Only "normal" connections can count.
|
||||
#c$conn?$conn_state && c$conn$conn_state in valid_states )
|
||||
{
|
||||
|
@ -176,6 +178,7 @@ event ssh_watcher(c: connection)
|
|||
if ( ! connection_exists(id) )
|
||||
return;
|
||||
|
||||
lookup_connection(c$id);
|
||||
check_ssh_connection(c, F);
|
||||
if ( ! c$ssh$done )
|
||||
schedule +15secs { ssh_watcher(c) };
|
||||
|
|
|
@ -94,11 +94,6 @@ redef record Info += {
|
|||
delay_tokens: set[string] &optional;
|
||||
};
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]);
|
||||
}
|
||||
|
||||
redef capture_filters += {
|
||||
["ssl"] = "tcp port 443",
|
||||
["nntps"] = "tcp port 563",
|
||||
|
@ -117,23 +112,15 @@ redef capture_filters += {
|
|||
const ports = {
|
||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
||||
};
|
||||
} &redef;
|
||||
|
||||
redef dpd_config += {
|
||||
[[ANALYZER_SSL]] = [$ports = ports]
|
||||
};
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
redef likely_server_ports += {
|
||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
||||
};
|
||||
|
||||
# A queue that buffers log records.
|
||||
global log_delay_queue: table[count] of Info;
|
||||
# The top queue index where records are added.
|
||||
global log_delay_queue_head = 0;
|
||||
# The bottom queue index that points to the next record to be flushed.
|
||||
global log_delay_queue_tail = 0;
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, ports);
|
||||
}
|
||||
|
||||
function set_session(c: connection)
|
||||
{
|
||||
|
@ -144,26 +131,17 @@ function set_session(c: connection)
|
|||
|
||||
function delay_log(info: Info, token: string)
|
||||
{
|
||||
if ( ! info?$delay_tokens )
|
||||
info$delay_tokens = set();
|
||||
add info$delay_tokens[token];
|
||||
|
||||
log_delay_queue[log_delay_queue_head] = info;
|
||||
++log_delay_queue_head;
|
||||
}
|
||||
|
||||
function undelay_log(info: Info, token: string)
|
||||
{
|
||||
if ( token in info$delay_tokens )
|
||||
if ( info?$delay_tokens && token in info$delay_tokens )
|
||||
delete info$delay_tokens[token];
|
||||
}
|
||||
|
||||
global log_record: function(info: Info);
|
||||
|
||||
event delay_logging(info: Info)
|
||||
{
|
||||
log_record(info);
|
||||
}
|
||||
|
||||
function log_record(info: Info)
|
||||
{
|
||||
if ( ! info?$delay_tokens || |info$delay_tokens| == 0 )
|
||||
|
@ -172,26 +150,14 @@ function log_record(info: Info)
|
|||
}
|
||||
else
|
||||
{
|
||||
for ( unused_index in log_delay_queue )
|
||||
when ( |info$delay_tokens| == 0 )
|
||||
{
|
||||
if ( log_delay_queue_head == log_delay_queue_tail )
|
||||
return;
|
||||
if ( |log_delay_queue[log_delay_queue_tail]$delay_tokens| > 0 )
|
||||
{
|
||||
if ( info$ts + max_log_delay > network_time() )
|
||||
{
|
||||
schedule 1sec { delay_logging(info) };
|
||||
return;
|
||||
log_record(info);
|
||||
}
|
||||
else
|
||||
timeout max_log_delay
|
||||
{
|
||||
Reporter::info(fmt("SSL delay tokens not released in time (%s)",
|
||||
info$delay_tokens));
|
||||
}
|
||||
}
|
||||
Log::write(SSL::LOG, log_delay_queue[log_delay_queue_tail]);
|
||||
delete log_delay_queue[log_delay_queue_tail];
|
||||
++log_delay_queue_tail;
|
||||
Reporter::info(fmt("SSL delay tokens not released in time (%s tokens remaining)",
|
||||
|info$delay_tokens|));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,28 +254,16 @@ event ssl_established(c: connection) &priority=-5
|
|||
finish(c);
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=5
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5
|
||||
{
|
||||
# Check by checking for existence of c$ssl record.
|
||||
if ( c?$ssl && analyzer_name(atype) == "SSL" )
|
||||
if ( c?$ssl && atype == Analyzer::ANALYZER_SSL )
|
||||
c$ssl$analyzer_id = aid;
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=5
|
||||
{
|
||||
if ( c?$ssl )
|
||||
finish(c);
|
||||
}
|
||||
|
||||
event bro_done()
|
||||
{
|
||||
if ( |log_delay_queue| == 0 )
|
||||
return;
|
||||
for ( unused_index in log_delay_queue )
|
||||
{
|
||||
Log::write(SSL::LOG, log_delay_queue[log_delay_queue_tail]);
|
||||
delete log_delay_queue[log_delay_queue_tail];
|
||||
++log_delay_queue_tail;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,9 @@ export {
|
|||
}
|
||||
|
||||
redef capture_filters += { ["syslog"] = "port 514" };
|
||||
const ports = { 514/udp } &redef;
|
||||
redef dpd_config += { [ANALYZER_SYSLOG_BINPAC] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 514/udp };
|
||||
const ports = { 514/udp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
redef record connection += {
|
||||
syslog: Info &optional;
|
||||
|
@ -39,6 +38,7 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Syslog::LOG, [$columns=Info]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, ports);
|
||||
}
|
||||
|
||||
event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=5
|
||||
|
|
|
@ -21,22 +21,22 @@ export {
|
|||
|
||||
type dir: enum { NONE, INCOMING, OUTGOING, BOTH };
|
||||
|
||||
const valids: table[count, addr, port] of dir = {
|
||||
const valids: table[Analyzer::Tag, addr, port] of dir = {
|
||||
# A couple of ports commonly used for benign HTTP servers.
|
||||
|
||||
# For now we want to see everything.
|
||||
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING,
|
||||
#
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella
|
||||
} &redef;
|
||||
|
||||
# Set of analyzers for which we suppress Server_Found notices
|
||||
|
@ -44,8 +44,8 @@ export {
|
|||
# log files, this also saves memory because for these we don't
|
||||
# need to remember which servers we already have reported, which
|
||||
# for some can be a lot.
|
||||
const suppress_servers: set [count] = {
|
||||
# ANALYZER_HTTP
|
||||
const suppress_servers: set [Analyzer::Tag] = {
|
||||
# Analyzer::ANALYZER_HTTP
|
||||
} &redef;
|
||||
|
||||
# We consider a connection to use a protocol X if the analyzer for X
|
||||
|
@ -60,7 +60,7 @@ export {
|
|||
|
||||
# Entry point for other analyzers to report that they recognized
|
||||
# a certain (sub-)protocol.
|
||||
global found_protocol: function(c: connection, analyzer: count,
|
||||
global found_protocol: function(c: connection, analyzer: Analyzer::Tag,
|
||||
protocol: string);
|
||||
|
||||
# Table keeping reported (server, port, analyzer) tuples (and their
|
||||
|
@ -70,7 +70,7 @@ export {
|
|||
}
|
||||
|
||||
# Table that tracks currently active dynamic analyzers per connection.
|
||||
global conns: table[conn_id] of set[count];
|
||||
global conns: table[conn_id] of set[Analyzer::Tag];
|
||||
|
||||
# Table of reports by other analyzers about the protocol used in a connection.
|
||||
global protocols: table[conn_id] of set[string];
|
||||
|
@ -80,7 +80,7 @@ type protocol : record {
|
|||
sub: string; # "sub-protocols" reported by other sources
|
||||
};
|
||||
|
||||
function get_protocol(c: connection, a: count) : protocol
|
||||
function get_protocol(c: connection, a: Analyzer::Tag) : protocol
|
||||
{
|
||||
local str = "";
|
||||
if ( c$id in protocols )
|
||||
|
@ -89,7 +89,7 @@ function get_protocol(c: connection, a: count) : protocol
|
|||
str = |str| > 0 ? fmt("%s/%s", str, p) : p;
|
||||
}
|
||||
|
||||
return [$a=analyzer_name(a), $sub=str];
|
||||
return [$a=Analyzer::name(a), $sub=str];
|
||||
}
|
||||
|
||||
function fmt_protocol(p: protocol) : string
|
||||
|
@ -97,7 +97,7 @@ function fmt_protocol(p: protocol) : string
|
|||
return p$sub != "" ? fmt("%s (via %s)", p$sub, p$a) : p$a;
|
||||
}
|
||||
|
||||
function do_notice(c: connection, a: count, d: dir)
|
||||
function do_notice(c: connection, a: Analyzer::Tag, d: dir)
|
||||
{
|
||||
if ( d == BOTH )
|
||||
return;
|
||||
|
@ -113,7 +113,7 @@ function do_notice(c: connection, a: count, d: dir)
|
|||
|
||||
NOTICE([$note=Protocol_Found,
|
||||
$msg=fmt("%s %s on port %s", id_string(c$id), s, c$id$resp_p),
|
||||
$sub=s, $conn=c, $n=a]);
|
||||
$sub=s, $conn=c]);
|
||||
|
||||
# We report multiple Server_Found's per host if we find a new
|
||||
# sub-protocol.
|
||||
|
@ -129,7 +129,7 @@ function do_notice(c: connection, a: count, d: dir)
|
|||
NOTICE([$note=Server_Found,
|
||||
$msg=fmt("%s: %s server on port %s%s", c$id$resp_h, s,
|
||||
c$id$resp_p, (known ? " (update)" : "")),
|
||||
$p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h, $n=a]);
|
||||
$p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h]);
|
||||
|
||||
if ( ! known )
|
||||
servers[c$id$resp_h, c$id$resp_p, p$a] = set();
|
||||
|
@ -194,10 +194,10 @@ event connection_state_remove(c: connection)
|
|||
report_protocols(c);
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count)
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count)
|
||||
{
|
||||
# Don't report anything running on a well-known port.
|
||||
if ( atype in dpd_config && c$id$resp_p in dpd_config[atype]$ports )
|
||||
if ( c$id$resp_p in Analyzer::registered_ports(atype) )
|
||||
return;
|
||||
|
||||
if ( c$id in conns )
|
||||
|
@ -214,11 +214,10 @@ event protocol_confirmation(c: connection, atype: count, aid: count)
|
|||
}
|
||||
}
|
||||
|
||||
function found_protocol(c: connection, analyzer: count, protocol: string)
|
||||
function found_protocol(c: connection, atype: Analyzer::Tag, protocol: string)
|
||||
{
|
||||
# Don't report anything running on a well-known port.
|
||||
if ( analyzer in dpd_config &&
|
||||
c$id$resp_p in dpd_config[analyzer]$ports )
|
||||
if ( c$id$resp_p in Analyzer::registered_ports(atype) )
|
||||
return;
|
||||
|
||||
if ( c$id !in protocols )
|
||||
|
|
|
@ -20,7 +20,7 @@ export {
|
|||
}
|
||||
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=4
|
||||
{
|
||||
if ( ! c?$dpd ) return;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
##! This script gives the capability to selectively enable and disable event
|
||||
##! groups at runtime. No events will be raised for all members of a disabled
|
||||
##! event group.
|
||||
|
||||
module AnalysisGroups;
|
||||
|
||||
export {
|
||||
## By default, all event groups are enabled.
|
||||
## We disable all groups in this table.
|
||||
const disabled: set[string] &redef;
|
||||
}
|
||||
|
||||
# Set to remember all groups which were disabled by the last update.
|
||||
global currently_disabled: set[string];
|
||||
|
||||
# This is the event that the control framework uses when it needs to indicate
|
||||
# that an update control action happened.
|
||||
event Control::configuration_update()
|
||||
{
|
||||
# Reenable those which are not to be disabled anymore.
|
||||
for ( g in currently_disabled )
|
||||
if ( g !in disabled )
|
||||
enable_event_group(g);
|
||||
|
||||
# Disable those which are not already disabled.
|
||||
for ( g in disabled )
|
||||
if ( g !in currently_disabled )
|
||||
disable_event_group(g);
|
||||
|
||||
currently_disabled = copy(disabled);
|
||||
}
|
|
@ -87,7 +87,7 @@ function known_services_done(c: connection)
|
|||
event log_it(network_time(), id$resp_h, id$resp_p, c$service);
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=-5
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=-5
|
||||
{
|
||||
known_services_done(c);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
@load integration/barnyard2/types.bro
|
||||
@load integration/collective-intel/__load__.bro
|
||||
@load integration/collective-intel/main.bro
|
||||
@load misc/analysis-groups.bro
|
||||
@load misc/app-metrics.bro
|
||||
@load misc/capture-loss.bro
|
||||
@load misc/detect-traceroute/__load__.bro
|
||||
|
|
403
src/Analyzer.h
403
src/Analyzer.h
|
@ -1,403 +0,0 @@
|
|||
// Main analyzer interface.
|
||||
|
||||
#ifndef ANALYZER_H
|
||||
#define ANALYZER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "AnalyzerTags.h"
|
||||
#include "Conn.h"
|
||||
#include "Obj.h"
|
||||
|
||||
class DPM;
|
||||
class PIA;
|
||||
class Analyzer;
|
||||
typedef list<Analyzer*> analyzer_list;
|
||||
|
||||
typedef void (Analyzer::*analyzer_timer_func)(double t);
|
||||
|
||||
// FIXME: This is a copy of ConnectionTimer, which we may eventually be
|
||||
// able to get rid of.
|
||||
class AnalyzerTimer : public Timer {
|
||||
public:
|
||||
AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type)
|
||||
: Timer(arg_t, arg_type)
|
||||
{ Init(arg_analyzer, arg_timer, arg_do_expire); }
|
||||
virtual ~AnalyzerTimer();
|
||||
|
||||
void Dispatch(double t, int is_expire);
|
||||
|
||||
protected:
|
||||
AnalyzerTimer() {}
|
||||
|
||||
void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
|
||||
|
||||
Analyzer* analyzer;
|
||||
analyzer_timer_func timer;
|
||||
int do_expire;
|
||||
};
|
||||
|
||||
|
||||
// Main analyzer interface.
|
||||
//
|
||||
// Each analyzer is part of a tree, having a parent analyzer and an
|
||||
// arbitrary number of child analyzers. Each analyzer also has a list of
|
||||
// *suppport analyzers*. All its input first passes through this list of
|
||||
// support analyzers, which can perform arbitrary preprocessing. Support
|
||||
// analyzers share the same interface as regular analyzers, except that
|
||||
// they are unidirectional, i.e., they see only one side of a connection.
|
||||
//
|
||||
// When overiding any of these methods, always make sure to call the
|
||||
// base-class version first.
|
||||
|
||||
class SupportAnalyzer;
|
||||
class OutputHandler;
|
||||
|
||||
class Analyzer {
|
||||
public:
|
||||
Analyzer(AnalyzerTag::Tag tag, Connection* conn);
|
||||
virtual ~Analyzer();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Done();
|
||||
|
||||
// Pass data to the analyzer (it's automatically passed through its
|
||||
// support analyzers first). We have packet-wise and stream-wise
|
||||
// interfaces. For the packet-interface, some analyzers may require
|
||||
// more information than others, so IP/caplen and seq may or may
|
||||
// not be set.
|
||||
void NextPacket(int len, const u_char* data, bool orig,
|
||||
int seq = -1, const IP_Hdr* ip = 0, int caplen = 0);
|
||||
void NextStream(int len, const u_char* data, bool is_orig);
|
||||
|
||||
// Used for data that can't be delivered (e.g., due to a previous
|
||||
// sequence hole/gap).
|
||||
void NextUndelivered(int seq, int len, bool is_orig);
|
||||
|
||||
// Report message boundary. (See EndOfData() below.)
|
||||
void NextEndOfData(bool orig);
|
||||
|
||||
// Pass data on to all child analyzer(s). For SupportAnalyzers (see
|
||||
// below), this is overridden to pass it on to the next sibling (or
|
||||
// finally to the parent, if it's the last support analyzer).
|
||||
//
|
||||
// If we have an associated OutputHandler (see below), the data is
|
||||
// additionally passed to that, too. For SupportAnalyzers, it is *only*
|
||||
// delivered to the OutputHandler.
|
||||
virtual void ForwardPacket(int len, const u_char* data,
|
||||
bool orig, int seq,
|
||||
const IP_Hdr* ip, int caplen);
|
||||
virtual void ForwardStream(int len, const u_char* data, bool orig);
|
||||
virtual void ForwardUndelivered(int seq, int len, bool orig);
|
||||
|
||||
// Report a message boundary to all child analyzers
|
||||
virtual void ForwardEndOfData(bool orig);
|
||||
|
||||
AnalyzerID GetID() const { return id; }
|
||||
Connection* Conn() const { return conn; }
|
||||
|
||||
// An OutputHandler can be used to get access to data extracted by this
|
||||
// analyzer (i.e., all data which is passed to
|
||||
// Forward{Packet,Stream,Undelivered}). We take the ownership of
|
||||
// the handler.
|
||||
class OutputHandler {
|
||||
public:
|
||||
virtual ~OutputHandler() { }
|
||||
|
||||
virtual void DeliverPacket(int len, const u_char* data,
|
||||
bool orig, int seq,
|
||||
const IP_Hdr* ip, int caplen)
|
||||
{ }
|
||||
virtual void DeliverStream(int len, const u_char* data,
|
||||
bool orig) { }
|
||||
virtual void Undelivered(int seq, int len, bool orig) { }
|
||||
};
|
||||
|
||||
OutputHandler* GetOutputHandler() const { return output_handler; }
|
||||
void SetOutputHandler(OutputHandler* handler)
|
||||
{ output_handler = handler; }
|
||||
|
||||
// If an analyzer was triggered by a signature match, this returns the
|
||||
// name of the signature; nil if not.
|
||||
const Rule* Signature() const { return signature; }
|
||||
void SetSignature(const Rule* sig) { signature = sig; }
|
||||
|
||||
void SetSkip(bool do_skip) { skip = do_skip; }
|
||||
bool Skipping() const { return skip; }
|
||||
|
||||
bool IsFinished() const { return finished; }
|
||||
|
||||
AnalyzerTag::Tag GetTag() const { return tag; }
|
||||
const char* GetTagName() const;
|
||||
static AnalyzerTag::Tag GetTag(const char* tag);
|
||||
static const char* GetTagName(AnalyzerTag::Tag tag);
|
||||
static bool IsAvailable(AnalyzerTag::Tag tag)
|
||||
{ return analyzer_configs[tag].available(); }
|
||||
|
||||
// Management of the tree.
|
||||
//
|
||||
// We immediately discard an added analyzer if there's already a child
|
||||
// of the same type.
|
||||
void AddChildAnalyzer(Analyzer* analyzer)
|
||||
{ AddChildAnalyzer(analyzer, true); }
|
||||
Analyzer* AddChildAnalyzer(AnalyzerTag::Tag tag);
|
||||
|
||||
void RemoveChildAnalyzer(Analyzer* analyzer);
|
||||
void RemoveChildAnalyzer(AnalyzerID id);
|
||||
|
||||
bool HasChildAnalyzer(AnalyzerTag::Tag tag);
|
||||
|
||||
// Recursive; returns nil if not found.
|
||||
Analyzer* FindChild(AnalyzerID id);
|
||||
|
||||
// Recursive; returns first found, or nil.
|
||||
Analyzer* FindChild(AnalyzerTag::Tag tag);
|
||||
|
||||
const analyzer_list& GetChildren() { return children; }
|
||||
|
||||
Analyzer* Parent() const { return parent; }
|
||||
void SetParent(Analyzer* p) { parent = p; }
|
||||
|
||||
// Remove this child analyzer from the parent's list.
|
||||
void Remove() { assert(parent); parent->RemoveChildAnalyzer(this); }
|
||||
|
||||
// Management of support analyzers. Support analyzers are associated
|
||||
// with a direction, and will only see data in the corresponding flow.
|
||||
//
|
||||
// We immediately discard an added analyzer if there's already a child
|
||||
// of the same type for the same direction.
|
||||
|
||||
// Adds to tail of list.
|
||||
void AddSupportAnalyzer(SupportAnalyzer* analyzer);
|
||||
|
||||
void RemoveSupportAnalyzer(SupportAnalyzer* analyzer);
|
||||
|
||||
// These are the methods where the analyzer actually gets its input.
|
||||
// Each analyzer has only to implement the schemes it supports.
|
||||
|
||||
// Packet-wise (or more generally chunk-wise) input. "data" points
|
||||
// to the payload that the analyzer is supposed to examine. If it's
|
||||
// part of a full packet, "ip" points to its IP header. An analyzer
|
||||
// may or may not require to be given the full packet (and its caplen)
|
||||
// as well.
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
// Stream-wise payload input.
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
// If a parent analyzer can't turn a sequence of packets into a stream
|
||||
// (e.g., due to holes), it can pass the remaining data through this
|
||||
// method to the child.
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
|
||||
// Report a message boundary. This is a generic method that can be used
|
||||
// by specific Analyzers if all data of a message has been delivered,
|
||||
// e.g., to report that HTTP body has been delivered completely by the
|
||||
// HTTP analyzer before it starts with the next body. EndOfData() is
|
||||
// automatically generated by the analyzer's Done() method.
|
||||
virtual void EndOfData(bool is_orig);
|
||||
|
||||
// Occasionally we may find during analysis that we got the direction
|
||||
// of the connection wrong. In these cases, this method is called
|
||||
// to swap state if necessary. This will not happen after payload
|
||||
// has already been passed on, so most analyzers don't need to care.
|
||||
virtual void FlipRoles();
|
||||
|
||||
// Feedback about protocol conformance, to be called by the
|
||||
// analyzer's processing. The methods raise the correspondiong
|
||||
// protocol_confirmation and protocol_violation events.
|
||||
|
||||
// Report that we believe we're parsing the right protocol. This
|
||||
// should be called as early as possible during a connection's
|
||||
// life-time. The protocol_confirmed event is only raised once per
|
||||
// analyzer, even if the method is called multiple times.
|
||||
virtual void ProtocolConfirmation();
|
||||
|
||||
// Return whether the analyzer previously called ProtocolConfirmation()
|
||||
// at least once before.
|
||||
bool ProtocolConfirmed() const
|
||||
{ return protocol_confirmed; }
|
||||
|
||||
// Report that we found a significant protocol violation which might
|
||||
// indicate that the analyzed data is in fact not the expected
|
||||
// protocol. The protocol_violation event is raised once per call to
|
||||
// this method so that the script-level may build up some notion of
|
||||
// how "severely" protocol semantics are violated.
|
||||
virtual void ProtocolViolation(const char* reason,
|
||||
const char* data = 0, int len = 0);
|
||||
|
||||
virtual unsigned int MemoryAllocation() const;
|
||||
|
||||
// Called whenever the connection value needs to be updated. Per
|
||||
// default, this method will be called for each analyzer in the tree.
|
||||
// Analyzers can use this method to attach additional data to the
|
||||
// connections. A call to BuildConnVal will in turn trigger a call to
|
||||
// UpdateConnVal.
|
||||
virtual void UpdateConnVal(RecordVal *conn_val);
|
||||
|
||||
// The following methods are proxies: calls are directly forwarded
|
||||
// to the connection instance. These are for convenience only,
|
||||
// allowing us to reuse more of the old analyzer code unchanged.
|
||||
RecordVal* BuildConnVal()
|
||||
{ return conn->BuildConnVal(); }
|
||||
void Event(EventHandlerPtr f, const char* name = 0)
|
||||
{ conn->Event(f, this, name); }
|
||||
void Event(EventHandlerPtr f, Val* v1, Val* v2 = 0)
|
||||
{ conn->Event(f, this, v1, v2); }
|
||||
void ConnectionEvent(EventHandlerPtr f, val_list* vl)
|
||||
{ conn->ConnectionEvent(f, this, vl); }
|
||||
void Weird(const char* name, const char* addl = "")
|
||||
{ conn->Weird(name, addl); }
|
||||
|
||||
// Factory function to instantiate new analyzers.
|
||||
static Analyzer* InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c);
|
||||
|
||||
protected:
|
||||
friend class DPM;
|
||||
friend class Connection;
|
||||
friend class AnalyzerTimer;
|
||||
friend class TCP_ApplicationAnalyzer;
|
||||
|
||||
Analyzer() { }
|
||||
|
||||
// Associates a connection with this analyzer. Must be called if
|
||||
// we're using the default ctor.
|
||||
void SetConnection(Connection* c) { conn = c; }
|
||||
|
||||
// Creates the given timer to expire at time t. If do_expire
|
||||
// is true, then the timer is also evaluated when Bro terminates,
|
||||
// otherwise not.
|
||||
void AddTimer(analyzer_timer_func timer, double t, int do_expire,
|
||||
TimerType type);
|
||||
|
||||
void RemoveTimer(Timer* t);
|
||||
void CancelTimers();
|
||||
|
||||
bool HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig);
|
||||
|
||||
void AddChildAnalyzer(Analyzer* analyzer, bool init);
|
||||
void InitChildren();
|
||||
void AppendNewChildren();
|
||||
|
||||
private:
|
||||
// Internal method to eventually delete a child analyzer that's
|
||||
// already Done().
|
||||
void DeleteChild(analyzer_list::iterator i);
|
||||
|
||||
AnalyzerTag::Tag tag;
|
||||
AnalyzerID id;
|
||||
|
||||
Connection* conn;
|
||||
Analyzer* parent;
|
||||
const Rule* signature;
|
||||
OutputHandler* output_handler;
|
||||
|
||||
analyzer_list children;
|
||||
SupportAnalyzer* orig_supporters;
|
||||
SupportAnalyzer* resp_supporters;
|
||||
|
||||
analyzer_list new_children;
|
||||
|
||||
bool protocol_confirmed;
|
||||
|
||||
timer_list timers;
|
||||
bool timers_canceled;
|
||||
bool skip;
|
||||
bool finished;
|
||||
bool removing;
|
||||
|
||||
static AnalyzerID id_counter;
|
||||
|
||||
typedef bool (*available_callback)();
|
||||
typedef Analyzer* (*factory_callback)(Connection* conn);
|
||||
typedef bool (*match_callback)(Connection*);
|
||||
|
||||
struct Config {
|
||||
AnalyzerTag::Tag tag;
|
||||
const char* name;
|
||||
factory_callback factory;
|
||||
available_callback available;
|
||||
match_callback match;
|
||||
bool partial;
|
||||
};
|
||||
|
||||
// Table of analyzers.
|
||||
static const Config analyzer_configs[];
|
||||
|
||||
};
|
||||
|
||||
#define ADD_ANALYZER_TIMER(timer, t, do_expire, type) \
|
||||
AddTimer(analyzer_timer_func(timer), (t), (do_expire), (type))
|
||||
|
||||
#define LOOP_OVER_CHILDREN(var) \
|
||||
for ( analyzer_list::iterator var = children.begin(); \
|
||||
var != children.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_CONST_CHILDREN(var) \
|
||||
for ( analyzer_list::const_iterator var = children.begin(); \
|
||||
var != children.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_GIVEN_CHILDREN(var, the_kids) \
|
||||
for ( analyzer_list::iterator var = the_kids.begin(); \
|
||||
var != the_kids.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_GIVEN_CONST_CHILDREN(var, the_kids) \
|
||||
for ( analyzer_list::const_iterator var = the_kids.begin(); \
|
||||
var != the_kids.end(); var++ )
|
||||
|
||||
class SupportAnalyzer : public Analyzer {
|
||||
public:
|
||||
SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
|
||||
: Analyzer(tag, conn) { orig = arg_orig; sibling = 0; }
|
||||
|
||||
virtual ~SupportAnalyzer() {}
|
||||
|
||||
bool IsOrig() const { return orig; }
|
||||
|
||||
virtual void ForwardPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
virtual void ForwardStream(int len, const u_char* data, bool orig);
|
||||
virtual void ForwardUndelivered(int seq, int len, bool orig);
|
||||
|
||||
SupportAnalyzer* Sibling() const { return sibling; }
|
||||
|
||||
protected:
|
||||
friend class Analyzer;
|
||||
|
||||
SupportAnalyzer() { }
|
||||
private:
|
||||
bool orig;
|
||||
|
||||
// Points to next support analyzer in chain. The list is managed by
|
||||
// parent analyzer.
|
||||
SupportAnalyzer* sibling;
|
||||
};
|
||||
|
||||
|
||||
class TransportLayerAnalyzer : public Analyzer {
|
||||
public:
|
||||
TransportLayerAnalyzer(AnalyzerTag::Tag tag, Connection* conn)
|
||||
: Analyzer(tag, conn) { pia = 0; }
|
||||
|
||||
virtual void Done();
|
||||
virtual bool IsReuse(double t, const u_char* pkt) = 0;
|
||||
|
||||
virtual void SetContentsFile(unsigned int direction, BroFile* f);
|
||||
virtual BroFile* GetContentsFile(unsigned int direction) const;
|
||||
|
||||
void SetPIA(PIA* arg_PIA) { pia = arg_PIA; }
|
||||
PIA* GetPIA() const { return pia; }
|
||||
|
||||
// Raises packet_contents event.
|
||||
void PacketContents(const u_char* data, int len);
|
||||
|
||||
protected:
|
||||
TransportLayerAnalyzer() { }
|
||||
|
||||
private:
|
||||
PIA* pia;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,57 +0,0 @@
|
|||
#ifndef ANALYZERTAGS_H
|
||||
#define ANALYZERTAGS_H
|
||||
|
||||
// Each kind of analyzer gets a tag. When adding an analyzer here, also adapt
|
||||
// the table of analyzers in Analyzer.cc.
|
||||
//
|
||||
// Using a namespace here is kind of a hack: ideally this would be in "class
|
||||
// Analyzer {...}". But then we'd have circular dependencies across the header
|
||||
// files.
|
||||
|
||||
#include "util.h"
|
||||
|
||||
typedef uint32 AnalyzerID;
|
||||
|
||||
namespace AnalyzerTag {
|
||||
enum Tag {
|
||||
Error = 0, // used as error code
|
||||
|
||||
// Analyzer in charge of protocol detection.
|
||||
PIA_TCP, PIA_UDP,
|
||||
|
||||
// Transport-layer analyzers.
|
||||
ICMP, TCP, UDP,
|
||||
|
||||
// Application-layer analyzers (hand-written).
|
||||
BitTorrent, BitTorrentTracker,
|
||||
DCE_RPC, DNS, Finger, FTP, Gnutella, HTTP, Ident, IRC,
|
||||
Login, NCP, NetbiosSSN, NFS, NTP, POP3, Portmapper, Rlogin,
|
||||
RPC, Rsh, SMB, SMTP, SSH,
|
||||
Telnet,
|
||||
|
||||
// Application-layer analyzers, binpac-generated.
|
||||
DHCP_BINPAC, DNS_TCP_BINPAC, DNS_UDP_BINPAC,
|
||||
HTTP_BINPAC, SSL, SYSLOG_BINPAC,
|
||||
Modbus,
|
||||
|
||||
// Decapsulation analyzers.
|
||||
AYIYA,
|
||||
SOCKS,
|
||||
Teredo,
|
||||
GTPv1,
|
||||
|
||||
// Other
|
||||
File, IRC_Data, FTP_Data, Backdoor, InterConn, SteppingStone, TCPStats,
|
||||
ConnSize,
|
||||
|
||||
// Support-analyzers
|
||||
Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP,
|
||||
Contents_NetbiosSSN, Contents_Rlogin, Contents_Rsh,
|
||||
Contents_DCE_RPC, Contents_SMB, Contents_RPC, Contents_NFS,
|
||||
FTP_ADAT,
|
||||
// End-marker.
|
||||
LastAnalyzer
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -82,9 +82,7 @@ int* Base64Converter::InitBase64Table(const string& alphabet)
|
|||
return base64_table;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Base64Converter::Base64Converter(Analyzer* arg_analyzer, const string& arg_alphabet)
|
||||
Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& arg_alphabet)
|
||||
{
|
||||
if ( arg_alphabet.size() > 0 )
|
||||
{
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "BroString.h"
|
||||
#include "Analyzer.h"
|
||||
#include "Reporter.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
// Maybe we should have a base class for generic decoders?
|
||||
class Base64Converter {
|
||||
|
@ -15,7 +16,7 @@ public:
|
|||
// <analyzer> is used for error reporting, and it should be zero when
|
||||
// the decoder is called by the built-in function decode_base64() or encode_base64().
|
||||
// Empty alphabet indicates the default base64 alphabet.
|
||||
Base64Converter(Analyzer* analyzer, const string& alphabet = "");
|
||||
Base64Converter(analyzer::Analyzer* analyzer, const string& alphabet = "");
|
||||
~Base64Converter();
|
||||
|
||||
// A note on Decode():
|
||||
|
@ -62,7 +63,7 @@ protected:
|
|||
int base64_after_padding;
|
||||
int* base64_table;
|
||||
int errored; // if true, we encountered an error - skip further processing
|
||||
Analyzer* analyzer;
|
||||
analyzer::Analyzer* analyzer;
|
||||
|
||||
};
|
||||
|
||||
|
|
314
src/BroDoc.cc
314
src/BroDoc.cc
|
@ -8,6 +8,9 @@
|
|||
#include "BroDoc.h"
|
||||
#include "BroDocObj.h"
|
||||
#include "util.h"
|
||||
#include "plugin/Manager.h"
|
||||
#include "analyzer/Manager.h"
|
||||
#include "analyzer/Component.h"
|
||||
|
||||
BroDoc::BroDoc(const std::string& rel, const std::string& abs)
|
||||
{
|
||||
|
@ -35,12 +38,14 @@ BroDoc::BroDoc(const std::string& rel, const std::string& abs)
|
|||
|
||||
downloadable_filename = source_filename;
|
||||
|
||||
#if 0
|
||||
size_t ext_pos = downloadable_filename.find(".bif.bro");
|
||||
if ( std::string::npos != ext_pos )
|
||||
downloadable_filename.erase(ext_pos + 4);
|
||||
#endif
|
||||
|
||||
reST_filename = doc_title;
|
||||
ext_pos = reST_filename.find(".bro");
|
||||
size_t ext_pos = reST_filename.find(".bro");
|
||||
|
||||
if ( std::string::npos == ext_pos )
|
||||
reST_filename += ".rst";
|
||||
|
@ -162,84 +167,77 @@ void BroDoc::SetPacketFilter(const std::string& s)
|
|||
packet_filter.clear();
|
||||
}
|
||||
|
||||
void BroDoc::AddPortAnalysis(const std::string& analyzer,
|
||||
const std::string& ports)
|
||||
{
|
||||
std::string reST_string = analyzer + "::\n" + ports + "\n\n";
|
||||
port_analysis.push_back(reST_string);
|
||||
}
|
||||
|
||||
void BroDoc::WriteDocFile() const
|
||||
{
|
||||
WriteToDoc(".. Automatically generated. Do not edit.\n\n");
|
||||
WriteToDoc(reST_file, ".. Automatically generated. Do not edit.\n\n");
|
||||
|
||||
WriteToDoc(":tocdepth: 3\n\n");
|
||||
WriteToDoc(reST_file, ":tocdepth: 3\n\n");
|
||||
|
||||
WriteSectionHeading(doc_title.c_str(), '=');
|
||||
WriteSectionHeading(reST_file, doc_title.c_str(), '=');
|
||||
|
||||
WriteStringList(".. bro:namespace:: %s\n", modules);
|
||||
WriteStringList(reST_file, ".. bro:namespace:: %s\n", modules);
|
||||
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(reST_file, "\n");
|
||||
|
||||
// WriteSectionHeading("Overview", '-');
|
||||
WriteStringList("%s\n", summary);
|
||||
// WriteSectionHeading(reST_file, "Overview", '-');
|
||||
WriteStringList(reST_file, "%s\n", summary);
|
||||
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(reST_file, "\n");
|
||||
|
||||
if ( ! modules.empty() )
|
||||
{
|
||||
WriteToDoc(":Namespace%s: ", (modules.size() > 1 ? "s" : ""));
|
||||
// WriteStringList(":bro:namespace:`%s`", modules);
|
||||
WriteStringList("``%s``, ", "``%s``", modules);
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(reST_file, ":Namespace%s: ", (modules.size() > 1 ? "s" : ""));
|
||||
// WriteStringList(reST_file, ":bro:namespace:`%s`", modules);
|
||||
WriteStringList(reST_file, "``%s``, ", "``%s``", modules);
|
||||
WriteToDoc(reST_file, "\n");
|
||||
}
|
||||
|
||||
if ( ! imports.empty() )
|
||||
{
|
||||
WriteToDoc(":Imports: ");
|
||||
WriteToDoc(reST_file, ":Imports: ");
|
||||
std::list<std::string>::const_iterator it;
|
||||
for ( it = imports.begin(); it != imports.end(); ++it )
|
||||
{
|
||||
if ( it != imports.begin() )
|
||||
WriteToDoc(", ");
|
||||
WriteToDoc(reST_file, ", ");
|
||||
|
||||
string pretty(*it);
|
||||
size_t pos = pretty.find("/index");
|
||||
if ( pos != std::string::npos && pos + 6 == pretty.size() )
|
||||
pretty = pretty.substr(0, pos);
|
||||
WriteToDoc(":doc:`%s </scripts/%s>`", pretty.c_str(), it->c_str());
|
||||
WriteToDoc(reST_file, ":doc:`%s </scripts/%s>`", pretty.c_str(), it->c_str());
|
||||
}
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(reST_file, "\n");
|
||||
}
|
||||
|
||||
WriteToDoc(":Source File: :download:`%s`\n",
|
||||
WriteToDoc(reST_file, ":Source File: :download:`%s`\n",
|
||||
downloadable_filename.c_str());
|
||||
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(reST_file, "\n");
|
||||
|
||||
WriteInterface("Summary", '~', '#', true, true);
|
||||
|
||||
if ( ! notices.empty() )
|
||||
WriteBroDocObjList(notices, "Notices", '#');
|
||||
WriteBroDocObjList(reST_file, notices, "Notices", '#');
|
||||
|
||||
if ( port_analysis.size() || packet_filter.size() )
|
||||
WriteSectionHeading("Configuration Changes", '#');
|
||||
WriteSectionHeading(reST_file, "Configuration Changes", '#');
|
||||
|
||||
if ( ! port_analysis.empty() )
|
||||
{
|
||||
WriteSectionHeading("Port Analysis", '^');
|
||||
WriteToDoc("Loading this script makes the following changes to "
|
||||
WriteSectionHeading(reST_file, "Port Analysis", '^');
|
||||
WriteToDoc(reST_file, "Loading this script makes the following changes to "
|
||||
":bro:see:`dpd_config`.\n\n");
|
||||
WriteStringList("%s, ", "%s", port_analysis);
|
||||
WriteStringList(reST_file, "%s, ", "%s", port_analysis);
|
||||
}
|
||||
|
||||
if ( ! packet_filter.empty() )
|
||||
{
|
||||
WriteSectionHeading("Packet Filter", '^');
|
||||
WriteToDoc("Loading this script makes the following changes to "
|
||||
WriteSectionHeading(reST_file, "Packet Filter", '^');
|
||||
WriteToDoc(reST_file, "Loading this script makes the following changes to "
|
||||
":bro:see:`capture_filters`.\n\n");
|
||||
WriteToDoc("Filters added::\n\n");
|
||||
WriteToDoc("%s\n", packet_filter.c_str());
|
||||
WriteToDoc(reST_file, "Filters added::\n\n");
|
||||
WriteToDoc(reST_file, "%s\n", packet_filter.c_str());
|
||||
}
|
||||
|
||||
WriteInterface("Detailed Interface", '~', '#', true, false);
|
||||
|
@ -265,23 +263,23 @@ void BroDoc::WriteDocFile() const
|
|||
void BroDoc::WriteInterface(const char* heading, char underline,
|
||||
char sub, bool isPublic, bool isShort) const
|
||||
{
|
||||
WriteSectionHeading(heading, underline);
|
||||
WriteBroDocObjList(options, isPublic, "Options", sub, isShort);
|
||||
WriteBroDocObjList(constants, isPublic, "Constants", sub, isShort);
|
||||
WriteBroDocObjList(state_vars, isPublic, "State Variables", sub, isShort);
|
||||
WriteBroDocObjList(types, isPublic, "Types", sub, isShort);
|
||||
WriteBroDocObjList(events, isPublic, "Events", sub, isShort);
|
||||
WriteBroDocObjList(hooks, isPublic, "Hooks", sub, isShort);
|
||||
WriteBroDocObjList(functions, isPublic, "Functions", sub, isShort);
|
||||
WriteBroDocObjList(redefs, isPublic, "Redefinitions", sub, isShort);
|
||||
WriteSectionHeading(reST_file, heading, underline);
|
||||
WriteBroDocObjList(reST_file, options, isPublic, "Options", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, constants, isPublic, "Constants", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, state_vars, isPublic, "State Variables", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, types, isPublic, "Types", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, events, isPublic, "Events", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, hooks, isPublic, "Hooks", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, functions, isPublic, "Functions", sub, isShort);
|
||||
WriteBroDocObjList(reST_file, redefs, isPublic, "Redefinitions", sub, isShort);
|
||||
}
|
||||
|
||||
void BroDoc::WriteStringList(const char* format, const char* last_format,
|
||||
const std::list<std::string>& l) const
|
||||
void BroDoc::WriteStringList(FILE* f, const char* format, const char* last_format,
|
||||
const std::list<std::string>& l)
|
||||
{
|
||||
if ( l.empty() )
|
||||
{
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(f, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -290,12 +288,12 @@ void BroDoc::WriteStringList(const char* format, const char* last_format,
|
|||
last--;
|
||||
|
||||
for ( it = l.begin(); it != last; ++it )
|
||||
WriteToDoc(format, it->c_str());
|
||||
WriteToDoc(f, format, it->c_str());
|
||||
|
||||
WriteToDoc(last_format, last->c_str());
|
||||
WriteToDoc(f, last_format, last->c_str());
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const
|
||||
void BroDoc::WriteBroDocObjTable(FILE* f, const BroDocObjList& l)
|
||||
{
|
||||
int max_id_col = 0;
|
||||
int max_com_col = 0;
|
||||
|
@ -315,38 +313,38 @@ void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const
|
|||
}
|
||||
|
||||
// Start table.
|
||||
WriteRepeatedChar('=', max_id_col);
|
||||
WriteToDoc(" ");
|
||||
WriteRepeatedChar(f, '=', max_id_col);
|
||||
WriteToDoc(f, " ");
|
||||
|
||||
if ( max_com_col == 0 )
|
||||
WriteToDoc("=");
|
||||
WriteToDoc(f, "=");
|
||||
else
|
||||
WriteRepeatedChar('=', max_com_col);
|
||||
WriteRepeatedChar(f, '=', max_com_col);
|
||||
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(f, "\n");
|
||||
|
||||
for ( it = l.begin(); it != l.end(); ++it )
|
||||
{
|
||||
if ( it != l.begin() )
|
||||
WriteToDoc("\n\n");
|
||||
(*it)->WriteReSTCompact(reST_file, max_id_col);
|
||||
WriteToDoc(f, "\n\n");
|
||||
(*it)->WriteReSTCompact(f, max_id_col);
|
||||
}
|
||||
|
||||
// End table.
|
||||
WriteToDoc("\n");
|
||||
WriteRepeatedChar('=', max_id_col);
|
||||
WriteToDoc(" ");
|
||||
WriteToDoc(f, "\n");
|
||||
WriteRepeatedChar(f, '=', max_id_col);
|
||||
WriteToDoc(f, " ");
|
||||
|
||||
if ( max_com_col == 0 )
|
||||
WriteToDoc("=");
|
||||
WriteToDoc(f, "=");
|
||||
else
|
||||
WriteRepeatedChar('=', max_com_col);
|
||||
WriteRepeatedChar(f, '=', max_com_col);
|
||||
|
||||
WriteToDoc("\n\n");
|
||||
WriteToDoc(f, "\n\n");
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
||||
const char* heading, char underline, bool isShort) const
|
||||
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic,
|
||||
const char* heading, char underline, bool isShort)
|
||||
{
|
||||
if ( l.empty() )
|
||||
return;
|
||||
|
@ -364,7 +362,7 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
|||
if ( it == l.end() )
|
||||
return;
|
||||
|
||||
WriteSectionHeading(heading, underline);
|
||||
WriteSectionHeading(f, heading, underline);
|
||||
|
||||
BroDocObjList filtered_list;
|
||||
|
||||
|
@ -375,13 +373,13 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
|||
}
|
||||
|
||||
if ( isShort )
|
||||
WriteBroDocObjTable(filtered_list);
|
||||
WriteBroDocObjTable(f, filtered_list);
|
||||
else
|
||||
WriteBroDocObjList(filtered_list);
|
||||
WriteBroDocObjList(f, filtered_list);
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic,
|
||||
const char* heading, char underline, bool isShort) const
|
||||
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic,
|
||||
const char* heading, char underline, bool isShort)
|
||||
{
|
||||
BroDocObjMap::const_iterator it;
|
||||
BroDocObjList l;
|
||||
|
@ -389,24 +387,24 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic,
|
|||
for ( it = m.begin(); it != m.end(); ++it )
|
||||
l.push_back(it->second);
|
||||
|
||||
WriteBroDocObjList(l, wantPublic, heading, underline, isShort);
|
||||
WriteBroDocObjList(f, l, wantPublic, heading, underline, isShort);
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjList(const BroDocObjList& l, const char* heading,
|
||||
char underline) const
|
||||
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading,
|
||||
char underline)
|
||||
{
|
||||
WriteSectionHeading(heading, underline);
|
||||
WriteBroDocObjList(l);
|
||||
WriteSectionHeading(f, heading, underline);
|
||||
WriteBroDocObjList(f, l);
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjList(const BroDocObjList& l) const
|
||||
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l)
|
||||
{
|
||||
for ( BroDocObjList::const_iterator it = l.begin(); it != l.end(); ++it )
|
||||
(*it)->WriteReST(reST_file);
|
||||
(*it)->WriteReST(f);
|
||||
}
|
||||
|
||||
void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading,
|
||||
char underline) const
|
||||
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading,
|
||||
char underline)
|
||||
{
|
||||
BroDocObjMap::const_iterator it;
|
||||
BroDocObjList l;
|
||||
|
@ -414,28 +412,28 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading,
|
|||
for ( it = m.begin(); it != m.end(); ++it )
|
||||
l.push_back(it->second);
|
||||
|
||||
WriteBroDocObjList(l, heading, underline);
|
||||
WriteBroDocObjList(f, l, heading, underline);
|
||||
}
|
||||
|
||||
void BroDoc::WriteToDoc(const char* format, ...) const
|
||||
void BroDoc::WriteToDoc(FILE* f, const char* format, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, format);
|
||||
vfprintf(reST_file, format, argp);
|
||||
vfprintf(f, format, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
void BroDoc::WriteSectionHeading(const char* heading, char underline) const
|
||||
void BroDoc::WriteSectionHeading(FILE* f, const char* heading, char underline)
|
||||
{
|
||||
WriteToDoc("%s\n", heading);
|
||||
WriteRepeatedChar(underline, strlen(heading));
|
||||
WriteToDoc("\n");
|
||||
WriteToDoc(f, "%s\n", heading);
|
||||
WriteRepeatedChar(f, underline, strlen(heading));
|
||||
WriteToDoc(f, "\n");
|
||||
}
|
||||
|
||||
void BroDoc::WriteRepeatedChar(char c, size_t n) const
|
||||
void BroDoc::WriteRepeatedChar(FILE* f, char c, size_t n)
|
||||
{
|
||||
for ( size_t i = 0; i < n; ++i )
|
||||
WriteToDoc("%c", c);
|
||||
WriteToDoc(f, "%c", c);
|
||||
}
|
||||
|
||||
void BroDoc::FreeBroDocObjPtrList(BroDocObjList& l)
|
||||
|
@ -457,3 +455,143 @@ void BroDoc::AddFunction(BroDocObj* o)
|
|||
else
|
||||
functions[o->Name()]->Combine(o);
|
||||
}
|
||||
|
||||
static void WritePluginSectionHeading(FILE* f, const plugin::Plugin* p)
|
||||
{
|
||||
string name = p->Name();
|
||||
|
||||
fprintf(f, "%s\n", name.c_str());
|
||||
for ( size_t i = 0; i < name.size(); ++i )
|
||||
fprintf(f, "-");
|
||||
fprintf(f, "\n\n");
|
||||
|
||||
fprintf(f, "%s\n\n", p->Description());
|
||||
}
|
||||
|
||||
static void WriteAnalyzerComponent(FILE* f, const analyzer::Component* c)
|
||||
{
|
||||
EnumType* atag = analyzer_mgr->GetTagEnumType();
|
||||
string tag = fmt("ANALYZER_%s", c->CanonicalName());
|
||||
|
||||
if ( atag->Lookup("Analyzer", tag.c_str()) < 0 )
|
||||
reporter->InternalError("missing analyzer tag for %s", tag.c_str());
|
||||
|
||||
fprintf(f, ":bro:enum:`Analyzer::%s`\n\n", tag.c_str());
|
||||
}
|
||||
|
||||
static void WritePluginComponents(FILE* f, const plugin::Plugin* p)
|
||||
{
|
||||
plugin::Plugin::component_list components = p->Components();
|
||||
plugin::Plugin::component_list::const_iterator it;
|
||||
|
||||
fprintf(f, "Components\n");
|
||||
fprintf(f, "++++++++++\n\n");
|
||||
|
||||
for ( it = components.begin(); it != components.end(); ++it )
|
||||
{
|
||||
switch ( (*it)->Type() ) {
|
||||
case plugin::component::ANALYZER:
|
||||
WriteAnalyzerComponent(f,
|
||||
dynamic_cast<const analyzer::Component*>(*it));
|
||||
break;
|
||||
case plugin::component::READER:
|
||||
reporter->InternalError("docs for READER component unimplemented");
|
||||
case plugin::component::WRITER:
|
||||
reporter->InternalError("docs for WRITER component unimplemented");
|
||||
default:
|
||||
reporter->InternalError("docs for unknown component unimplemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WritePluginBifItems(FILE* f, const plugin::Plugin* p,
|
||||
plugin::BifItem::Type t, const string& heading)
|
||||
{
|
||||
plugin::Plugin::bif_item_list bifitems = p->BifItems();
|
||||
plugin::Plugin::bif_item_list::iterator it = bifitems.begin();
|
||||
|
||||
while ( it != bifitems.end() )
|
||||
{
|
||||
if ( it->GetType() != t )
|
||||
it = bifitems.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if ( bifitems.empty() )
|
||||
return;
|
||||
|
||||
fprintf(f, "%s\n", heading.c_str());
|
||||
for ( size_t i = 0; i < heading.size(); ++i )
|
||||
fprintf(f, "+");
|
||||
fprintf(f, "\n\n");
|
||||
|
||||
for ( it = bifitems.begin(); it != bifitems.end(); ++it )
|
||||
{
|
||||
BroDocObj* o = doc_ids[it->GetID()];
|
||||
|
||||
if ( o )
|
||||
o->WriteReST(f);
|
||||
else
|
||||
reporter->Warning("No docs for ID: %s\n", it->GetID());
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteAnalyzerTagDefn(FILE* f, EnumType* e)
|
||||
{
|
||||
e = new CommentedEnumType(e);
|
||||
e->SetTypeID(copy_string("Analyzer::Tag"));
|
||||
|
||||
ID* dummy_id = new ID(copy_string("Analyzer::Tag"), SCOPE_GLOBAL, true);
|
||||
dummy_id->SetType(e);
|
||||
dummy_id->MakeType();
|
||||
|
||||
list<string>* r = new list<string>();
|
||||
r->push_back("Unique identifiers for protocol analyzers.");
|
||||
|
||||
BroDocObj bdo(dummy_id, r, true);
|
||||
|
||||
bdo.WriteReST(f);
|
||||
}
|
||||
|
||||
static bool IsAnalyzerPlugin(const plugin::Plugin* p)
|
||||
{
|
||||
plugin::Plugin::component_list components = p->Components();
|
||||
plugin::Plugin::component_list::const_iterator it;
|
||||
|
||||
for ( it = components.begin(); it != components.end(); ++it )
|
||||
if ( (*it)->Type() != plugin::component::ANALYZER )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CreateProtoAnalyzerDoc(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "w");
|
||||
|
||||
fprintf(f, "Protocol Analyzer Reference\n");
|
||||
fprintf(f, "===========================\n\n");
|
||||
|
||||
WriteAnalyzerTagDefn(f, analyzer_mgr->GetTagEnumType());
|
||||
|
||||
plugin::Manager::plugin_list plugins = plugin_mgr->Plugins();
|
||||
plugin::Manager::plugin_list::const_iterator it;
|
||||
|
||||
for ( it = plugins.begin(); it != plugins.end(); ++it )
|
||||
{
|
||||
if ( ! IsAnalyzerPlugin(*it) )
|
||||
continue;
|
||||
|
||||
WritePluginSectionHeading(f, *it);
|
||||
WritePluginComponents(f, *it);
|
||||
WritePluginBifItems(f, *it, plugin::BifItem::CONSTANT,
|
||||
"Options/Constants");
|
||||
WritePluginBifItems(f, *it, plugin::BifItem::GLOBAL, "Globals");
|
||||
WritePluginBifItems(f, *it, plugin::BifItem::TYPE, "Types");
|
||||
WritePluginBifItems(f, *it, plugin::BifItem::EVENT, "Events");
|
||||
WritePluginBifItems(f, *it, plugin::BifItem::FUNCTION, "Functions");
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
|
230
src/BroDoc.h
230
src/BroDoc.h
|
@ -81,15 +81,6 @@ public:
|
|||
*/
|
||||
void SetPacketFilter(const std::string& s);
|
||||
|
||||
/**
|
||||
* Schedules documentation of a given set of ports being associated
|
||||
* with a particular analyzer as a result of the current script
|
||||
* being loaded -- the way the "dpd_config" table is changed.
|
||||
* @param analyzer An analyzer that changed the "dpd_config" table.
|
||||
* @param ports The set of ports assigned to the analyzer in table.
|
||||
*/
|
||||
void AddPortAnalysis(const std::string& analyzer, const std::string& ports);
|
||||
|
||||
/**
|
||||
* Schedules documentation of a script option. An option is
|
||||
* defined as any variable in the script that is declared 'const'
|
||||
|
@ -242,7 +233,115 @@ public:
|
|||
return reST_filename.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::list<const BroDocObj*> BroDocObjList;
|
||||
typedef std::map<std::string, BroDocObj*> BroDocObjMap;
|
||||
|
||||
/**
|
||||
* Writes out a table of BroDocObj's to the reST document
|
||||
* @param f The file to write to.
|
||||
* @param l A list of BroDocObj pointers
|
||||
*/
|
||||
static void WriteBroDocObjTable(FILE* f, const BroDocObjList& l);
|
||||
|
||||
/**
|
||||
* Writes out given number of characters to reST document
|
||||
* @param f The file to write to.
|
||||
* @param c the character to write
|
||||
* @param n the number of characters to write
|
||||
*/
|
||||
static void WriteRepeatedChar(FILE* f, char c, size_t n);
|
||||
|
||||
/**
|
||||
* A wrapper to fprintf() that always uses the reST document
|
||||
* for the FILE* argument.
|
||||
* @param f The file to write to.
|
||||
* @param format A printf style format string.
|
||||
*/
|
||||
static void WriteToDoc(FILE* f, const char* format, ...);
|
||||
|
||||
/**
|
||||
* Writes out a list of strings to the reST document.
|
||||
* If the list is empty, prints a newline character.
|
||||
* @param f The file to write to.
|
||||
* @param format A printf style format string for elements of the list
|
||||
* except for the last one in the list
|
||||
* @param last_format A printf style format string to use for the last
|
||||
* element of the list
|
||||
* @param l A reference to a list of strings
|
||||
*/
|
||||
static void WriteStringList(FILE* f, const char* format, const char* last_format,
|
||||
const std::list<std::string>& l);
|
||||
|
||||
/**
|
||||
* @see WriteStringList(FILE* f, const char*, const char*,
|
||||
* const std::list<std::string>&>)
|
||||
*/
|
||||
static void WriteStringList(FILE* f, const char* format,
|
||||
const std::list<std::string>& l){
|
||||
WriteStringList(f, format, format, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param f The file to write to.
|
||||
* @param l A list of BroDocObj pointers
|
||||
* @param wantPublic If true, filter out objects that are not declared
|
||||
* in the global scope. If false, filter out those that are in
|
||||
* the global scope.
|
||||
* @param heading The title of the section to create in the reST doc.
|
||||
* @param underline The character to use to underline the reST
|
||||
* section heading.
|
||||
* @param isShort Whether to write the full documentation or a "short"
|
||||
* version (a single sentence)
|
||||
*/
|
||||
static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic,
|
||||
const char* heading, char underline,
|
||||
bool isShort);
|
||||
|
||||
/**
|
||||
* Wraps the BroDocObjMap into a BroDocObjList and the writes that list
|
||||
* to the reST document
|
||||
* @see WriteBroDocObjList(FILE* f, const BroDocObjList&, bool, const char*, char,
|
||||
bool)
|
||||
*/
|
||||
static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic,
|
||||
const char* heading, char underline,
|
||||
bool isShort);
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
* @param heading The title of the section to create in the reST doc.
|
||||
* @param underline The character to use to underline the reST
|
||||
* section heading.
|
||||
*/
|
||||
static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading,
|
||||
char underline);
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
*/
|
||||
static void WriteBroDocObjList(FILE* f, const BroDocObjList& l);
|
||||
|
||||
/**
|
||||
* Wraps the BroDocObjMap into a BroDocObjList and the writes that list
|
||||
* to the reST document
|
||||
* @see WriteBroDocObjList(FILE* f, const BroDocObjList&, const char*, char)
|
||||
*/
|
||||
static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading,
|
||||
char underline);
|
||||
|
||||
/**
|
||||
* Writes out a reST section heading
|
||||
* @param f The file to write to.
|
||||
* @param heading The title of the heading to create
|
||||
* @param underline The character to use to underline the section title
|
||||
* within the reST document
|
||||
*/
|
||||
static void WriteSectionHeading(FILE* f, const char* heading, char underline);
|
||||
|
||||
private:
|
||||
FILE* reST_file;
|
||||
std::string reST_filename;
|
||||
std::string source_filename; // points to the basename of source file
|
||||
|
@ -255,9 +354,6 @@ protected:
|
|||
std::list<std::string> imports;
|
||||
std::list<std::string> port_analysis;
|
||||
|
||||
typedef std::list<const BroDocObj*> BroDocObjList;
|
||||
typedef std::map<std::string, BroDocObj*> BroDocObjMap;
|
||||
|
||||
BroDocObjList options;
|
||||
BroDocObjList constants;
|
||||
BroDocObjList state_vars;
|
||||
|
@ -272,107 +368,6 @@ protected:
|
|||
|
||||
BroDocObjList all;
|
||||
|
||||
/**
|
||||
* Writes out a list of strings to the reST document.
|
||||
* If the list is empty, prints a newline character.
|
||||
* @param format A printf style format string for elements of the list
|
||||
* except for the last one in the list
|
||||
* @param last_format A printf style format string to use for the last
|
||||
* element of the list
|
||||
* @param l A reference to a list of strings
|
||||
*/
|
||||
void WriteStringList(const char* format, const char* last_format,
|
||||
const std::list<std::string>& l) const;
|
||||
|
||||
/**
|
||||
* @see WriteStringList(const char*, const char*,
|
||||
* const std::list<std::string>&>)
|
||||
*/
|
||||
void WriteStringList(const char* format,
|
||||
const std::list<std::string>& l) const
|
||||
{
|
||||
WriteStringList(format, format, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes out a table of BroDocObj's to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
*/
|
||||
void WriteBroDocObjTable(const BroDocObjList& l) const;
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
* @param wantPublic If true, filter out objects that are not declared
|
||||
* in the global scope. If false, filter out those that are in
|
||||
* the global scope.
|
||||
* @param heading The title of the section to create in the reST doc.
|
||||
* @param underline The character to use to underline the reST
|
||||
* section heading.
|
||||
* @param isShort Whether to write the full documentation or a "short"
|
||||
* version (a single sentence)
|
||||
*/
|
||||
void WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
||||
const char* heading, char underline,
|
||||
bool isShort) const;
|
||||
|
||||
/**
|
||||
* Wraps the BroDocObjMap into a BroDocObjList and the writes that list
|
||||
* to the reST document
|
||||
* @see WriteBroDocObjList(const BroDocObjList&, bool, const char*, char,
|
||||
bool)
|
||||
*/
|
||||
void WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic,
|
||||
const char* heading, char underline,
|
||||
bool isShort) const;
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
* @param heading The title of the section to create in the reST doc.
|
||||
* @param underline The character to use to underline the reST
|
||||
* section heading.
|
||||
*/
|
||||
void WriteBroDocObjList(const BroDocObjList& l, const char* heading,
|
||||
char underline) const;
|
||||
|
||||
/**
|
||||
* Writes out a list of BroDocObj objects to the reST document
|
||||
* @param l A list of BroDocObj pointers
|
||||
*/
|
||||
void WriteBroDocObjList(const BroDocObjList& l) const;
|
||||
|
||||
/**
|
||||
* Wraps the BroDocObjMap into a BroDocObjList and the writes that list
|
||||
* to the reST document
|
||||
* @see WriteBroDocObjList(const BroDocObjList&, const char*, char)
|
||||
*/
|
||||
void WriteBroDocObjList(const BroDocObjMap& m, const char* heading,
|
||||
char underline) const;
|
||||
|
||||
/**
|
||||
* A wrapper to fprintf() that always uses the reST document
|
||||
* for the FILE* argument.
|
||||
* @param format A printf style format string.
|
||||
*/
|
||||
void WriteToDoc(const char* format, ...) const;
|
||||
|
||||
/**
|
||||
* Writes out a reST section heading
|
||||
* @param heading The title of the heading to create
|
||||
* @param underline The character to use to underline the section title
|
||||
* within the reST document
|
||||
*/
|
||||
void WriteSectionHeading(const char* heading, char underline) const;
|
||||
|
||||
/**
|
||||
* Writes out given number of characters to reST document
|
||||
* @param c the character to write
|
||||
* @param n the number of characters to write
|
||||
*/
|
||||
void WriteRepeatedChar(char c, size_t n) const;
|
||||
|
||||
/**
|
||||
* Writes out the reST for either the script's public or private interface
|
||||
* @param heading The title of the interfaces section heading
|
||||
|
@ -387,7 +382,6 @@ protected:
|
|||
*/
|
||||
void WriteInterface(const char* heading, char underline, char subunderline,
|
||||
bool isPublic, bool isShort) const;
|
||||
private:
|
||||
|
||||
/**
|
||||
* Frees memory allocated to BroDocObj's objects in a given list.
|
||||
|
@ -413,4 +407,10 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes out plugin index documentation for all analyzer plugins.
|
||||
* @param filename the name of the file to write.
|
||||
*/
|
||||
void CreateProtoAnalyzerDoc(const char* filename);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "ID.h"
|
||||
#include "BroDocObj.h"
|
||||
|
||||
map<string, BroDocObj*> doc_ids = map<string, BroDocObj*>();
|
||||
|
||||
BroDocObj* BroDocObj::last = 0;
|
||||
|
||||
BroDocObj::BroDocObj(const ID* id, std::list<std::string>*& reST,
|
||||
|
@ -16,6 +18,7 @@ BroDocObj::BroDocObj(const ID* id, std::list<std::string>*& reST,
|
|||
is_fake_id = is_fake;
|
||||
use_role = 0;
|
||||
FormulateShortDesc();
|
||||
doc_ids[id->Name()] = this;
|
||||
}
|
||||
|
||||
BroDocObj::~BroDocObj()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "ID.h"
|
||||
|
||||
|
@ -134,4 +135,9 @@ protected:
|
|||
private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Map identifiers to their broxygen documentation objects.
|
||||
*/
|
||||
extern map<string, BroDocObj*> doc_ids;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,13 @@ include_directories(BEFORE
|
|||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
# This collects generated bif and pac files from subdirectories.
|
||||
set(bro_ALL_GENERATED_OUTPUTS CACHE INTERNAL "automatically generated files" FORCE)
|
||||
|
||||
# If TRUE, use CMake's object libraries for sub-directories instead of
|
||||
# static libraries. This requires CMake >= 2.8.8.
|
||||
set(bro_HAVE_OBJECT_LIBRARIES FALSE)
|
||||
|
||||
configure_file(version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c)
|
||||
configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h)
|
||||
|
||||
|
@ -100,52 +107,13 @@ target_link_libraries(bifcl)
|
|||
########################################################################
|
||||
## bifcl-dependent targets
|
||||
|
||||
# A macro to define a command that uses the BIF compiler to produce
|
||||
# C++ segments and Bro language declarations from .bif file
|
||||
# The outputs are appended to list ALL_BIF_OUTPUTS
|
||||
# Outputs that should be installed are appended to INSTALL_BIF_OUTPUTS
|
||||
macro(BIF_TARGET bifInput)
|
||||
get_bif_output_files(${bifInput} bifOutputs)
|
||||
add_custom_command(OUTPUT ${bifOutputs}
|
||||
COMMAND bifcl
|
||||
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${bifInput} || (rm -f ${bifOutputs} && exit 1)
|
||||
# In order be able to run bro from the build directory,
|
||||
# the generated bro script needs to be inside a
|
||||
# a directory tree named the same way it will be
|
||||
# referenced from an @load.
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
ARGS -E copy ${bifInput}.bro base/${bifInput}.bro
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
ARGS -E remove -f ${bifInput}.bro
|
||||
DEPENDS ${bifInput}
|
||||
DEPENDS bifcl
|
||||
COMMENT "[BIFCL] Processing ${bifInput}"
|
||||
)
|
||||
list(APPEND ALL_BIF_OUTPUTS ${bifOutputs})
|
||||
list(APPEND INSTALL_BIF_OUTPUTS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/base/${bifInput}.bro)
|
||||
endmacro(BIF_TARGET)
|
||||
|
||||
# returns a list of output files that bifcl will produce
|
||||
# for given input file in ${outputFileVar}
|
||||
macro(GET_BIF_OUTPUT_FILES inputFile outputFileVar)
|
||||
set(${outputFileVar}
|
||||
base/${inputFile}.bro
|
||||
${inputFile}.func_def
|
||||
${inputFile}.func_h
|
||||
${inputFile}.func_init
|
||||
${inputFile}.netvar_def
|
||||
${inputFile}.netvar_h
|
||||
${inputFile}.netvar_init
|
||||
)
|
||||
endmacro(GET_BIF_OUTPUT_FILES)
|
||||
include(BifCl)
|
||||
|
||||
set(BIF_SRCS
|
||||
bro.bif
|
||||
logging.bif
|
||||
input.bif
|
||||
event.bif
|
||||
file_analysis.bif
|
||||
const.bif
|
||||
types.bif
|
||||
strings.bif
|
||||
|
@ -153,74 +121,54 @@ set(BIF_SRCS
|
|||
)
|
||||
|
||||
foreach (bift ${BIF_SRCS})
|
||||
bif_target(${bift})
|
||||
bif_target(${bift} "standard")
|
||||
endforeach ()
|
||||
|
||||
########################################################################
|
||||
## BinPAC-dependent targets
|
||||
|
||||
include(BinPAC)
|
||||
|
||||
set(BINPAC_AUXSRC
|
||||
binpac.pac
|
||||
bro.pac
|
||||
binpac_bro.h
|
||||
${CMAKE_SOURCE_DIR}/src/binpac.pac
|
||||
${CMAKE_SOURCE_DIR}/src/bro.pac
|
||||
${CMAKE_SOURCE_DIR}/src/binpac_bro.h
|
||||
)
|
||||
|
||||
# A macro to define a command that uses the BinPac compiler to
|
||||
# produce C++ code that implements a protocol parser/analyzer
|
||||
# The outputs of the command are appended to list ALL_BINPAC_OUTPUTS
|
||||
# All arguments to this macro are appended to list ALL_BINPAC_INPUTS
|
||||
macro(BINPAC_TARGET pacFile)
|
||||
get_filename_component(basename ${pacFile} NAME_WE)
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc
|
||||
COMMAND ${BinPAC_EXE}
|
||||
ARGS -q -d ${CMAKE_CURRENT_BINARY_DIR}
|
||||
-I ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${pacFile}
|
||||
DEPENDS ${BinPAC_EXE} ${pacFile}
|
||||
${BINPAC_AUXSRC} ${ARGN}
|
||||
COMMENT "[BINPAC] Processing ${pacFile}"
|
||||
)
|
||||
list(APPEND ALL_BINPAC_INPUTS ${ARGV})
|
||||
list(APPEND ALL_BINPAC_OUTPUTS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc)
|
||||
endmacro(BINPAC_TARGET)
|
||||
|
||||
binpac_target(binpac-lib.pac)
|
||||
binpac_target(binpac_bro-lib.pac)
|
||||
list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}")
|
||||
|
||||
binpac_target(ayiya.pac
|
||||
ayiya-protocol.pac ayiya-analyzer.pac)
|
||||
binpac_target(bittorrent.pac
|
||||
bittorrent-protocol.pac bittorrent-analyzer.pac)
|
||||
binpac_target(dce_rpc.pac
|
||||
dce_rpc-protocol.pac dce_rpc-analyzer.pac epmapper.pac)
|
||||
binpac_target(dce_rpc_simple.pac
|
||||
dce_rpc-protocol.pac epmapper.pac)
|
||||
binpac_target(dhcp.pac
|
||||
dhcp-protocol.pac dhcp-analyzer.pac)
|
||||
binpac_target(dns.pac
|
||||
dns-protocol.pac dns-analyzer.pac)
|
||||
binpac_target(dns_tcp.pac
|
||||
dns.pac)
|
||||
binpac_target(gtpv1.pac
|
||||
gtpv1-protocol.pac gtpv1-analyzer.pac)
|
||||
binpac_target(http.pac
|
||||
http-protocol.pac http-analyzer.pac)
|
||||
binpac_target(ncp.pac)
|
||||
binpac_target(netflow.pac
|
||||
netflow-protocol.pac netflow-analyzer.pac)
|
||||
binpac_target(smb.pac
|
||||
smb-protocol.pac smb-pipe.pac smb-mailslot.pac)
|
||||
binpac_target(socks.pac
|
||||
socks-protocol.pac socks-analyzer.pac)
|
||||
binpac_target(ssl.pac
|
||||
ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac)
|
||||
binpac_target(syslog.pac
|
||||
syslog-protocol.pac syslog-analyzer.pac)
|
||||
binpac_target(modbus.pac
|
||||
modbus-protocol.pac modbus-analyzer.pac)
|
||||
binpac_target(binpac_bro-lib.pac)
|
||||
list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}")
|
||||
|
||||
########################################################################
|
||||
## Including subdirectories.
|
||||
########################################################################
|
||||
|
||||
set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE)
|
||||
set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE)
|
||||
|
||||
add_subdirectory(analyzer)
|
||||
add_subdirectory(file_analysis)
|
||||
|
||||
set(bro_SUBDIRS
|
||||
${bro_SUBDIR_LIBS}
|
||||
${bro_PLUGIN_LIBS}
|
||||
)
|
||||
|
||||
if ( NOT bro_HAVE_OBJECT_LIBRARIES )
|
||||
foreach (_plugin ${bro_PLUGIN_LIBS})
|
||||
string(REGEX REPLACE "plugin-" "" _plugin "${_plugin}")
|
||||
string(REGEX REPLACE "-" "_" _plugin "${_plugin}")
|
||||
set(_decl "namespace plugin { namespace ${_plugin} { class Plugin; extern Plugin __plugin; } };")
|
||||
set(_use "i += (size_t)(&(plugin::${_plugin}::__plugin));")
|
||||
set(__BRO_DECL_PLUGINS "${__BRO_DECL_PLUGINS}${_decl}\n")
|
||||
set(__BRO_USE_PLUGINS "${__BRO_USE_PLUGINS}${_use}\n")
|
||||
endforeach()
|
||||
|
||||
configure_file(plugins.cc.in ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
|
||||
set(PLUGIN_INIT ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
## bro target
|
||||
|
@ -240,7 +188,7 @@ endif ()
|
|||
macro(COLLECT_HEADERS _var)
|
||||
foreach (src ${ARGN})
|
||||
get_filename_component(ext ${src} EXT)
|
||||
if (${ext} STREQUAL ".cc" OR ${ext} STREQUAL ".c")
|
||||
if ("${ext}" STREQUAL ".cc" OR "${ext}" STREQUAL ".c")
|
||||
get_filename_component(base ${src} NAME_WE)
|
||||
get_filename_component(dir ${src} PATH)
|
||||
if (NOT "${dir}")
|
||||
|
@ -275,10 +223,8 @@ set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS
|
|||
set(bro_SRCS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.c
|
||||
${BIF_SRCS}
|
||||
${ALL_BIF_OUTPUTS}
|
||||
${BINPAC_AUXSRC}
|
||||
${ALL_BINPAC_INPUTS}
|
||||
${ALL_BINPAC_OUTPUTS}
|
||||
${BINPAC_OUTPUTS}
|
||||
${TRANSFORMED_BISON_OUTPUTS}
|
||||
${FLEX_RuleScanner_OUTPUTS}
|
||||
${FLEX_RuleScanner_INPUT}
|
||||
|
@ -290,19 +236,14 @@ set(bro_SRCS
|
|||
${FLEX_Scanner_INPUT}
|
||||
${BISON_Parser_INPUT}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
|
||||
${PLUGIN_INIT}
|
||||
main.cc
|
||||
net_util.cc
|
||||
util.cc
|
||||
module_util.cc
|
||||
Analyzer.cc
|
||||
Anon.cc
|
||||
ARP.cc
|
||||
Attr.cc
|
||||
AYIYA.cc
|
||||
BackDoor.cc
|
||||
Base64.cc
|
||||
BitTorrent.cc
|
||||
BitTorrentTracker.cc
|
||||
BPF_Program.cc
|
||||
BroDoc.cc
|
||||
BroDocObj.cc
|
||||
|
@ -312,14 +253,7 @@ set(bro_SRCS
|
|||
ChunkedIO.cc
|
||||
CompHash.cc
|
||||
Conn.cc
|
||||
ConnSizeAnalyzer.cc
|
||||
ContentLine.cc
|
||||
DCE_RPC.cc
|
||||
DFA.cc
|
||||
DHCP-binpac.cc
|
||||
DNS.cc
|
||||
DNS-binpac.cc
|
||||
DNS_Mgr.cc
|
||||
DbgBreakpoint.cc
|
||||
DbgHelp.cc
|
||||
DbgWatch.cc
|
||||
|
@ -329,48 +263,29 @@ set(bro_SRCS
|
|||
Desc.cc
|
||||
Dict.cc
|
||||
Discard.cc
|
||||
DPM.cc
|
||||
DNS_Mgr.cc
|
||||
EquivClass.cc
|
||||
Event.cc
|
||||
EventHandler.cc
|
||||
EventLauncher.cc
|
||||
EventRegistry.cc
|
||||
Expr.cc
|
||||
FTP.cc
|
||||
File.cc
|
||||
FileAnalyzer.cc
|
||||
Finger.cc
|
||||
FlowSrc.cc
|
||||
Frag.cc
|
||||
Frame.cc
|
||||
Func.cc
|
||||
Gnutella.cc
|
||||
GTPv1.cc
|
||||
HTTP.cc
|
||||
HTTP-binpac.cc
|
||||
Hash.cc
|
||||
ICMP.cc
|
||||
ID.cc
|
||||
Ident.cc
|
||||
IntSet.cc
|
||||
InterConn.cc
|
||||
IOSource.cc
|
||||
IP.cc
|
||||
IPAddr.cc
|
||||
IRC.cc
|
||||
List.cc
|
||||
Reporter.cc
|
||||
Login.cc
|
||||
MIME.cc
|
||||
Modbus.cc
|
||||
NCP.cc
|
||||
NFA.cc
|
||||
NFS.cc
|
||||
NTP.cc
|
||||
NVT.cc
|
||||
Net.cc
|
||||
NetVar.cc
|
||||
NetbiosSSN.cc
|
||||
Obj.cc
|
||||
OpaqueVal.cc
|
||||
OSFinger.cc
|
||||
|
@ -378,31 +293,20 @@ set(bro_SRCS
|
|||
PacketSort.cc
|
||||
PersistenceSerializer.cc
|
||||
PktSrc.cc
|
||||
PIA.cc
|
||||
PolicyFile.cc
|
||||
POP3.cc
|
||||
Portmap.cc
|
||||
PrefixTable.cc
|
||||
PriorityQueue.cc
|
||||
Queue.cc
|
||||
RandTest.cc
|
||||
RE.cc
|
||||
RPC.cc
|
||||
Reassem.cc
|
||||
RemoteSerializer.cc
|
||||
Rlogin.cc
|
||||
RSH.cc
|
||||
Rule.cc
|
||||
RuleAction.cc
|
||||
RuleCondition.cc
|
||||
RuleMatcher.cc
|
||||
ScriptAnaly.cc
|
||||
SmithWaterman.cc
|
||||
SMB.cc
|
||||
SMTP.cc
|
||||
SOCKS.cc
|
||||
SSH.cc
|
||||
SSL.cc
|
||||
Scope.cc
|
||||
SerializationFormat.cc
|
||||
SerialObj.cc
|
||||
|
@ -410,24 +314,14 @@ set(bro_SRCS
|
|||
Sessions.cc
|
||||
StateAccess.cc
|
||||
Stats.cc
|
||||
SteppingStone.cc
|
||||
Stmt.cc
|
||||
Syslog-binpac.cc
|
||||
TCP.cc
|
||||
TCP_Endpoint.cc
|
||||
TCP_Reassembler.cc
|
||||
Telnet.cc
|
||||
Teredo.cc
|
||||
Timer.cc
|
||||
Traverse.cc
|
||||
Trigger.cc
|
||||
TunnelEncapsulation.cc
|
||||
Type.cc
|
||||
UDP.cc
|
||||
Val.cc
|
||||
Var.cc
|
||||
XDR.cc
|
||||
ZIP.cc
|
||||
bsd-getopt-long.c
|
||||
bro_inet_ntop.c
|
||||
cq.c
|
||||
|
@ -461,29 +355,44 @@ set(bro_SRCS
|
|||
input/readers/Binary.cc
|
||||
input/readers/SQLite.cc
|
||||
|
||||
file_analysis/Manager.cc
|
||||
file_analysis/File.cc
|
||||
file_analysis/FileTimer.cc
|
||||
file_analysis/Analyzer.h
|
||||
file_analysis/AnalyzerSet.cc
|
||||
file_analysis/Extract.cc
|
||||
file_analysis/Hash.cc
|
||||
file_analysis/DataEvent.cc
|
||||
|
||||
3rdparty/sqlite3.c
|
||||
|
||||
plugin/Component.cc
|
||||
plugin/Manager.cc
|
||||
plugin/Plugin.cc
|
||||
plugin/Macros.h
|
||||
|
||||
nb_dns.c
|
||||
digest.h
|
||||
)
|
||||
|
||||
collect_headers(bro_HEADERS ${bro_SRCS})
|
||||
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
|
||||
|
||||
target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
||||
if ( bro_HAVE_OBJECT_LIBRARIES )
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_SUBDIRS})
|
||||
target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
||||
else ()
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
|
||||
target_link_libraries(bro ${bro_SUBDIRS} ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
||||
endif ()
|
||||
|
||||
install(TARGETS bro DESTINATION bin)
|
||||
install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base)
|
||||
|
||||
set(BRO_EXE bro
|
||||
CACHE STRING "Bro executable binary" FORCE)
|
||||
|
||||
# Target to create all the autogenerated files.
|
||||
add_custom_target(generate_outputs)
|
||||
add_dependencies(generate_outputs ${bro_ALL_GENERATED_OUTPUTS})
|
||||
|
||||
# Build __load__.bro files for plugins/*.bif.bro.
|
||||
bro_bif_create_loader(bif_loader_plugins ${CMAKE_BINARY_DIR}/scripts/base/bif/plugins)
|
||||
add_dependencies(bif_loader_plugins ${bro_SUBDIRS})
|
||||
add_dependencies(bro bif_loader_plugins)
|
||||
|
||||
# Install *.bif.bro.
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/scripts/base/bif DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base)
|
||||
|
||||
# Make clean removes the bif directory.
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/scripts/base/bif)
|
||||
|
||||
|
|
24
src/Conn.cc
24
src/Conn.cc
|
@ -11,9 +11,10 @@
|
|||
#include "Sessions.h"
|
||||
#include "Reporter.h"
|
||||
#include "Timer.h"
|
||||
#include "PIA.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
#include "binpac.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
|
||||
int arg_do_expire)
|
||||
|
@ -402,16 +403,21 @@ RecordVal* Connection::BuildConnVal()
|
|||
return conn_val;
|
||||
}
|
||||
|
||||
Analyzer* Connection::FindAnalyzer(AnalyzerID id)
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id)
|
||||
{
|
||||
return root_analyzer ? root_analyzer->FindChild(id) : 0;
|
||||
}
|
||||
|
||||
Analyzer* Connection::FindAnalyzer(AnalyzerTag::Tag tag)
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::Tag tag)
|
||||
{
|
||||
return root_analyzer ? root_analyzer->FindChild(tag) : 0;
|
||||
}
|
||||
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(const char* name)
|
||||
{
|
||||
return root_analyzer->FindChild(name);
|
||||
}
|
||||
|
||||
void Connection::AppendAddl(const char* str)
|
||||
{
|
||||
Unref(BuildConnVal());
|
||||
|
@ -540,7 +546,7 @@ Val* Connection::BuildVersionVal(const char* s, int len)
|
|||
}
|
||||
|
||||
int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||
Analyzer* analyzer)
|
||||
analyzer::Analyzer* analyzer)
|
||||
{
|
||||
if ( ! software_version_found && ! software_parse_error )
|
||||
return 1;
|
||||
|
@ -578,7 +584,7 @@ int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
|||
}
|
||||
|
||||
int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
||||
const char* full, int len, Analyzer* analyzer)
|
||||
const char* full, int len, analyzer::Analyzer* analyzer)
|
||||
{
|
||||
// Skip leading white space.
|
||||
while ( len && isspace(*full) )
|
||||
|
@ -602,7 +608,7 @@ int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
|
||||
void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name)
|
||||
{
|
||||
if ( ! f )
|
||||
return;
|
||||
|
@ -615,7 +621,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
|
|||
ConnectionEvent(f, analyzer, vl);
|
||||
}
|
||||
|
||||
void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
|
||||
void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2)
|
||||
{
|
||||
if ( ! f )
|
||||
{
|
||||
|
@ -634,7 +640,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
|
|||
ConnectionEvent(f, analyzer, vl);
|
||||
}
|
||||
|
||||
void Connection::ConnectionEvent(EventHandlerPtr f, Analyzer* a, val_list* vl)
|
||||
void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_list* vl)
|
||||
{
|
||||
if ( ! f )
|
||||
{
|
||||
|
@ -929,7 +935,7 @@ error:
|
|||
return false;
|
||||
}
|
||||
|
||||
void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
|
||||
void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia)
|
||||
{
|
||||
root_analyzer = analyzer;
|
||||
primary_PIA = pia;
|
||||
|
|
34
src/Conn.h
34
src/Conn.h
|
@ -11,19 +11,22 @@
|
|||
#include "Serializer.h"
|
||||
#include "PersistenceSerializer.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "AnalyzerTags.h"
|
||||
#include "IPAddr.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
class Connection;
|
||||
class ConnectionTimer;
|
||||
class NetSessions;
|
||||
class LoginConn;
|
||||
class RuleHdrTest;
|
||||
class Specific_RE_Matcher;
|
||||
class TransportLayerAnalyzer;
|
||||
class RuleEndpointState;
|
||||
|
||||
namespace analyzer { class TransportLayerAnalyzer; }
|
||||
|
||||
typedef enum {
|
||||
NUL_IN_LINE,
|
||||
SINGULAR_CR,
|
||||
|
@ -47,7 +50,7 @@ static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1,
|
|||
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
|
||||
}
|
||||
|
||||
class Analyzer;
|
||||
namespace analyzer { class Analyzer; }
|
||||
|
||||
class Connection : public BroObj {
|
||||
public:
|
||||
|
@ -102,8 +105,9 @@ public:
|
|||
|
||||
void FlipRoles();
|
||||
|
||||
Analyzer* FindAnalyzer(AnalyzerID id);
|
||||
Analyzer* FindAnalyzer(AnalyzerTag::Tag tag); // find first in tree.
|
||||
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
|
||||
analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree.
|
||||
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
|
||||
|
||||
TransportProto ConnTransport() const { return proto; }
|
||||
|
||||
|
@ -161,15 +165,15 @@ public:
|
|||
// Raises a software_version_found event based on the
|
||||
// given string (returns false if it's not parseable).
|
||||
int VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||
Analyzer* analyzer = 0);
|
||||
analyzer::Analyzer* analyzer = 0);
|
||||
|
||||
// Raises a software_unparsed_version_found event.
|
||||
int UnparsedVersionFoundEvent(const IPAddr& addr,
|
||||
const char* full_descr, int len, Analyzer* analyzer);
|
||||
const char* full_descr, int len, analyzer::Analyzer* analyzer);
|
||||
|
||||
void Event(EventHandlerPtr f, Analyzer* analyzer, const char* name = 0);
|
||||
void Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
||||
void ConnectionEvent(EventHandlerPtr f, Analyzer* analyzer,
|
||||
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name = 0);
|
||||
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
||||
void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer,
|
||||
val_list* vl);
|
||||
|
||||
void Weird(const char* name, const char* addl = "");
|
||||
|
@ -241,9 +245,9 @@ public:
|
|||
void DeleteTimer(double t);
|
||||
|
||||
// Sets the root of the analyzer tree as well as the primary PIA.
|
||||
void SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia);
|
||||
TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
||||
PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||
void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia);
|
||||
analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
||||
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||
|
||||
// Sets the transport protocol in use.
|
||||
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
|
||||
|
@ -314,8 +318,8 @@ protected:
|
|||
string history;
|
||||
uint32 hist_seen;
|
||||
|
||||
TransportLayerAnalyzer* root_analyzer;
|
||||
PIA* primary_PIA;
|
||||
analyzer::TransportLayerAnalyzer* root_analyzer;
|
||||
analyzer::pia::PIA* primary_PIA;
|
||||
|
||||
uint64 uid; // Globally unique connection ID.
|
||||
};
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include "DHCP-binpac.h"
|
||||
|
||||
DHCP_Analyzer_binpac::DHCP_Analyzer_binpac(Connection* conn)
|
||||
: Analyzer(AnalyzerTag::DHCP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DHCP::DHCP_Conn(this);
|
||||
}
|
||||
|
||||
DHCP_Analyzer_binpac::~DHCP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DHCP_Analyzer_binpac::Done()
|
||||
{
|
||||
Analyzer::Done();
|
||||
}
|
||||
|
||||
void DHCP_Analyzer_binpac::DeliverPacket(int len, const u_char* data,
|
||||
bool orig, int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef dhcp_binpac_h
|
||||
#define dhcp_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
|
||||
#include "dhcp_pac.h"
|
||||
|
||||
|
||||
class DHCP_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
DHCP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DHCP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DHCP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return dhcp_request && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::DHCP::DHCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,90 +0,0 @@
|
|||
#include "DNS-binpac.h"
|
||||
#include "TCP_Reassembler.h"
|
||||
|
||||
DNS_UDP_Analyzer_binpac::DNS_UDP_Analyzer_binpac(Connection* conn)
|
||||
: Analyzer(AnalyzerTag::DNS_UDP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DNS::DNS_Conn(this);
|
||||
did_session_done = 0;
|
||||
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
|
||||
network_time + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
|
||||
}
|
||||
|
||||
DNS_UDP_Analyzer_binpac::~DNS_UDP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::Done()
|
||||
{
|
||||
Analyzer::Done();
|
||||
|
||||
if ( ! did_session_done )
|
||||
Event(udp_session_done);
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::ExpireTimer(double t)
|
||||
{
|
||||
// The - 1.0 in the following is to allow 1 second for the
|
||||
// common case of a single request followed by a single reply,
|
||||
// so we don't needlessly set the timer twice in that case.
|
||||
if ( t - Conn()->LastTime() >= dns_session_timeout - 1.0 || terminating )
|
||||
{
|
||||
Event(connection_timeout);
|
||||
sessions->Remove(Conn());
|
||||
}
|
||||
else
|
||||
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
|
||||
t + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
|
||||
}
|
||||
|
||||
DNS_TCP_Analyzer_binpac::DNS_TCP_Analyzer_binpac(Connection* conn)
|
||||
: TCP_ApplicationAnalyzer(AnalyzerTag::DNS_TCP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DNS_on_TCP::DNS_TCP_Conn(this);
|
||||
}
|
||||
|
||||
DNS_TCP_Analyzer_binpac::~DNS_TCP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::Done()
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Done();
|
||||
|
||||
interp->FlowEOF(true);
|
||||
interp->FlowEOF(false);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::EndpointEOF(bool is_orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||
interp->FlowEOF(is_orig);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data,
|
||||
bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||
|
||||
assert(TCP());
|
||||
|
||||
if ( TCP()->IsPartial() || TCP()->HadGap(orig) )
|
||||
// punt-on-partial or stop-on-gap.
|
||||
return;
|
||||
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||
interp->NewGap(orig, len);
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef dns_binpac_h
|
||||
#define dns_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
|
||||
#include "dns_pac.h"
|
||||
|
||||
// FIXME: As the binpac analyer for DNS-TCP and DNS-UDP are currently
|
||||
// structured, we cannot directly combine them into one analyzer. Can we
|
||||
// change that easily? (Ideally, the TCP preprocessing would become a
|
||||
// support-analyzer as it is done for the traditional DNS analyzer.)
|
||||
|
||||
class DNS_UDP_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
DNS_UDP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DNS_UDP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DNS_UDP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
friend class AnalyzerTimer;
|
||||
void ExpireTimer(double t);
|
||||
|
||||
int did_session_done;
|
||||
|
||||
binpac::DNS::DNS_Conn* interp;
|
||||
};
|
||||
|
||||
#include "dns_tcp_pac.h"
|
||||
|
||||
class DNS_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
DNS_TCP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DNS_TCP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DNS_TCP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::DNS_on_TCP::DNS_TCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
407
src/DPM.cc
407
src/DPM.cc
|
@ -1,407 +0,0 @@
|
|||
#include "DPM.h"
|
||||
#include "PIA.h"
|
||||
#include "Hash.h"
|
||||
#include "ICMP.h"
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
#include "Val.h"
|
||||
#include "BackDoor.h"
|
||||
#include "InterConn.h"
|
||||
#include "SteppingStone.h"
|
||||
#include "ConnSizeAnalyzer.h"
|
||||
|
||||
|
||||
ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
||||
uint16 _resp_p, uint16 _proto)
|
||||
{
|
||||
if ( _orig == IPAddr(string("0.0.0.0")) )
|
||||
// don't use the IPv4 mapping, use the literal unspecified address
|
||||
// to indicate a wildcard
|
||||
orig = IPAddr(string("::"));
|
||||
else
|
||||
orig = _orig;
|
||||
resp = _resp;
|
||||
resp_p = _resp_p;
|
||||
proto = _proto;
|
||||
}
|
||||
|
||||
ExpectedConn::ExpectedConn(const ExpectedConn& c)
|
||||
{
|
||||
orig = c.orig;
|
||||
resp = c.resp;
|
||||
resp_p = c.resp_p;
|
||||
proto = c.proto;
|
||||
}
|
||||
|
||||
DPM::DPM()
|
||||
: active_analyzers(0), expected_conns_queue(AssignedAnalyzer::compare)
|
||||
{
|
||||
}
|
||||
|
||||
DPM::~DPM()
|
||||
{
|
||||
delete [] active_analyzers;
|
||||
}
|
||||
|
||||
void DPM::PreScriptInit()
|
||||
{
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
{
|
||||
// Create IDs ANALYZER_*.
|
||||
ID* id = install_ID(fmt("ANALYZER_%s",
|
||||
Analyzer::analyzer_configs[i].name),
|
||||
GLOBAL_MODULE_NAME, true, false);
|
||||
assert(id);
|
||||
id->SetVal(new Val(i, TYPE_COUNT));
|
||||
id->SetType(id->ID_Val()->Type()->Ref());
|
||||
}
|
||||
}
|
||||
|
||||
void DPM::PostScriptInit()
|
||||
{
|
||||
active_analyzers = new bool[int(AnalyzerTag::LastAnalyzer)];
|
||||
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
{
|
||||
if ( ! Analyzer::analyzer_configs[i].available )
|
||||
continue;
|
||||
|
||||
active_analyzers[i] = Analyzer::analyzer_configs[i].available();
|
||||
if ( active_analyzers[i] )
|
||||
AddConfig(Analyzer::analyzer_configs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void DPM::AddConfig(const Analyzer::Config& cfg)
|
||||
{
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
HeapLeakChecker::Disabler disabler;
|
||||
#endif
|
||||
|
||||
Val* index = new Val(cfg.tag, TYPE_COUNT);
|
||||
Val* v = dpd_config->Lookup(index);
|
||||
|
||||
#ifdef DEBUG
|
||||
ODesc desc;
|
||||
#endif
|
||||
if ( v )
|
||||
{
|
||||
RecordVal* cfg_record = v->AsRecordVal();
|
||||
Val* ports = cfg_record->Lookup(0);
|
||||
|
||||
if ( ports )
|
||||
{
|
||||
ListVal* plist = ports->AsTableVal()->ConvertToPureList();
|
||||
|
||||
for ( int i = 0; i< plist->Length(); ++i )
|
||||
{
|
||||
PortVal* port = plist->Index(i)->AsPortVal();
|
||||
|
||||
analyzer_map* ports =
|
||||
port->IsTCP() ? &tcp_ports : &udp_ports;
|
||||
|
||||
analyzer_map::iterator j =
|
||||
ports->find(port->Port());
|
||||
|
||||
if ( j == ports->end() )
|
||||
{
|
||||
tag_list* analyzers = new tag_list;
|
||||
analyzers->push_back(cfg.tag);
|
||||
ports->insert(analyzer_map::value_type(port->Port(), analyzers));
|
||||
}
|
||||
else
|
||||
j->second->push_back(cfg.tag);
|
||||
|
||||
#ifdef DEBUG
|
||||
port->Describe(&desc);
|
||||
desc.SP();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s analyzer active on port(s) %s", cfg.name, desc.Description());
|
||||
|
||||
Unref(index);
|
||||
}
|
||||
|
||||
AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn)
|
||||
{
|
||||
if ( ! expected_conns.Length() )
|
||||
return AnalyzerTag::Error;
|
||||
|
||||
ExpectedConn c(conn->OrigAddr(), conn->RespAddr(),
|
||||
ntohs(conn->RespPort()), proto);
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
|
||||
if ( ! a )
|
||||
{
|
||||
// Wildcard for originator.
|
||||
c.orig = IPAddr(string("::"));
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
if ( ! a )
|
||||
return AnalyzerTag::Error;
|
||||
|
||||
// We don't delete it here. It will be expired eventually.
|
||||
return a->analyzer;
|
||||
}
|
||||
|
||||
bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||
const u_char* data)
|
||||
{
|
||||
TCP_Analyzer* tcp = 0;
|
||||
UDP_Analyzer* udp = 0;
|
||||
ICMP_Analyzer* icmp = 0;
|
||||
TransportLayerAnalyzer* root = 0;
|
||||
AnalyzerTag::Tag expected = AnalyzerTag::Error;
|
||||
analyzer_map* ports = 0;
|
||||
PIA* pia = 0;
|
||||
bool analyzed = false;
|
||||
|
||||
switch ( proto ) {
|
||||
|
||||
case TRANSPORT_TCP:
|
||||
root = tcp = new TCP_Analyzer(conn);
|
||||
pia = new PIA_TCP(conn);
|
||||
expected = GetExpected(proto, conn);
|
||||
ports = &tcp_ports;
|
||||
DBG_DPD(conn, "activated TCP analyzer");
|
||||
break;
|
||||
|
||||
case TRANSPORT_UDP:
|
||||
root = udp = new UDP_Analyzer(conn);
|
||||
pia = new PIA_UDP(conn);
|
||||
expected = GetExpected(proto, conn);
|
||||
ports = &udp_ports;
|
||||
DBG_DPD(conn, "activated UDP analyzer");
|
||||
break;
|
||||
|
||||
case TRANSPORT_ICMP: {
|
||||
root = icmp = new ICMP_Analyzer(conn);
|
||||
DBG_DPD(conn, "activated ICMP analyzer");
|
||||
analyzed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reporter->InternalError("unknown protocol");
|
||||
}
|
||||
|
||||
if ( ! root )
|
||||
{
|
||||
DBG_DPD(conn, "cannot build analyzer tree");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Any scheduled analyzer?
|
||||
if ( expected != AnalyzerTag::Error )
|
||||
{
|
||||
Analyzer* analyzer =
|
||||
Analyzer::InstantiateAnalyzer(expected, conn);
|
||||
root->AddChildAnalyzer(analyzer, false);
|
||||
DBG_DPD_ARGS(conn, "activated %s analyzer as scheduled",
|
||||
Analyzer::GetTagName(expected));
|
||||
|
||||
// Hmm... Do we want *just* the expected analyzer, or all
|
||||
// other potential analyzers as well? For now we only take
|
||||
// the scheduled one.
|
||||
}
|
||||
|
||||
else
|
||||
{ // Let's see if it's a port we know.
|
||||
if ( ports && ! dpd_ignore_ports )
|
||||
{
|
||||
analyzer_map::const_iterator i =
|
||||
ports->find(ntohs(conn->RespPort()));
|
||||
|
||||
if ( i != ports->end() )
|
||||
{
|
||||
tag_list* analyzers = i->second;
|
||||
for ( tag_list::const_iterator j = analyzers->begin();
|
||||
j != analyzers->end(); j++ )
|
||||
{
|
||||
Analyzer* analyzer =
|
||||
Analyzer::InstantiateAnalyzer(*j, conn);
|
||||
|
||||
root->AddChildAnalyzer(analyzer, false);
|
||||
DBG_DPD_ARGS(conn, "activated %s analyzer due to port %d", Analyzer::GetTagName(*j), conn->RespPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( tcp )
|
||||
{
|
||||
// We have to decide whether to reassamble the stream.
|
||||
// We turn it on right away if we already have an app-layer
|
||||
// analyzer, reassemble_first_packets is true, or the user
|
||||
// asks us to do so. In all other cases, reassembly may
|
||||
// be turned on later by the TCP PIA.
|
||||
|
||||
bool reass = root->GetChildren().size() ||
|
||||
dpd_reassemble_first_packets ||
|
||||
tcp_content_deliver_all_orig ||
|
||||
tcp_content_deliver_all_resp;
|
||||
|
||||
if ( tcp_contents && ! reass )
|
||||
{
|
||||
PortVal dport(ntohs(conn->RespPort()), TRANSPORT_TCP);
|
||||
Val* result;
|
||||
|
||||
if ( ! reass )
|
||||
reass = tcp_content_delivery_ports_orig->Lookup(&dport);
|
||||
|
||||
if ( ! reass )
|
||||
reass = tcp_content_delivery_ports_resp->Lookup(&dport);
|
||||
}
|
||||
|
||||
if ( reass )
|
||||
tcp->EnableReassembly();
|
||||
|
||||
// Add a BackDoor analyzer if requested. This analyzer
|
||||
// can handle both reassembled and non-reassembled input.
|
||||
if ( BackDoor_Analyzer::Available() )
|
||||
{
|
||||
BackDoor_Analyzer* bd = new BackDoor_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
|
||||
// Add a InterConn analyzer if requested. This analyzer
|
||||
// can handle both reassembled and non-reassembled input.
|
||||
if ( InterConn_Analyzer::Available() )
|
||||
{
|
||||
InterConn_Analyzer* bd = new InterConn_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
|
||||
// Add a SteppingStone analyzer if requested. The port
|
||||
// should really not be hardcoded here, but as it can
|
||||
// handle non-reassembled data, it doesn't really fit into
|
||||
// our general framing ... Better would be to turn it
|
||||
// on *after* we discover we have interactive traffic.
|
||||
uint16 resp_port = ntohs(conn->RespPort());
|
||||
if ( SteppingStone_Analyzer::Available() &&
|
||||
(resp_port == 22 || resp_port == 23 || resp_port == 513) )
|
||||
{
|
||||
AddrVal src(conn->OrigAddr());
|
||||
if ( ! stp_skip_src->Lookup(&src) )
|
||||
{
|
||||
SteppingStone_Analyzer* bd =
|
||||
new SteppingStone_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Add TCPStats analyzer. This needs to see packets so
|
||||
// we cannot add it as a normal child.
|
||||
if ( TCPStats_Analyzer::Available() )
|
||||
tcp->AddChildPacketAnalyzer(new TCPStats_Analyzer(conn));
|
||||
|
||||
// Add ConnSize analyzer. Needs to see packets, not stream.
|
||||
if ( ConnSize_Analyzer::Available() )
|
||||
tcp->AddChildPacketAnalyzer(new ConnSize_Analyzer(conn));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( ConnSize_Analyzer::Available() )
|
||||
root->AddChildAnalyzer(new ConnSize_Analyzer(conn), false);
|
||||
}
|
||||
|
||||
if ( pia )
|
||||
root->AddChildAnalyzer(pia->AsAnalyzer(), false);
|
||||
|
||||
if ( root->GetChildren().size() )
|
||||
analyzed = true;
|
||||
|
||||
conn->SetRootAnalyzer(root, pia);
|
||||
root->Init();
|
||||
root->InitChildren();
|
||||
|
||||
if ( ! analyzed )
|
||||
conn->SetLifetime(non_analyzed_lifetime);
|
||||
|
||||
if ( expected != AnalyzerTag::Error )
|
||||
conn->Event(expected_connection_seen, 0,
|
||||
new Val(expected, TYPE_COUNT));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp,
|
||||
uint16 resp_p,
|
||||
TransportProto proto, AnalyzerTag::Tag analyzer,
|
||||
double timeout, void* cookie)
|
||||
{
|
||||
// Use the chance to see if the oldest entry is already expired.
|
||||
if ( expected_conns_queue.size() )
|
||||
{
|
||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
||||
if ( a->timeout < network_time )
|
||||
{
|
||||
if ( ! a->deleted )
|
||||
{
|
||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
expected_conns_queue.pop();
|
||||
|
||||
DBG_LOG(DBG_DPD, "Expired expected %s analyzer for %s",
|
||||
Analyzer::GetTagName(analyzer),
|
||||
fmt_conn_id(a->conn.orig, 0,
|
||||
a->conn.resp,
|
||||
a->conn.resp_p));
|
||||
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedConn c(orig, resp, resp_p, proto);
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
|
||||
if ( a )
|
||||
a->deleted = true;
|
||||
|
||||
a = new AssignedAnalyzer(c);
|
||||
|
||||
a->analyzer = analyzer;
|
||||
a->cookie = cookie;
|
||||
a->timeout = network_time + timeout;
|
||||
a->deleted = false;
|
||||
|
||||
expected_conns.Insert(key, a);
|
||||
expected_conns_queue.push(a);
|
||||
delete key;
|
||||
}
|
||||
|
||||
void DPM::Done()
|
||||
{
|
||||
// Clean up expected-connection table.
|
||||
while ( expected_conns_queue.size() )
|
||||
{
|
||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
||||
if ( ! a->deleted )
|
||||
{
|
||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
expected_conns_queue.pop();
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
131
src/DPM.h
131
src/DPM.h
|
@ -1,131 +0,0 @@
|
|||
// The central management unit for dynamic analyzer selection.
|
||||
|
||||
#ifndef DPM_H
|
||||
#define DPM_H
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "Dict.h"
|
||||
#include "net_util.h"
|
||||
|
||||
// DPM debug logging, which includes the connection id into the message.
|
||||
#ifdef DEBUG
|
||||
# define DBG_DPD(conn, txt) \
|
||||
DBG_LOG(DBG_DPD, "%s " txt, \
|
||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||
conn->RespAddr(), ntohs(conn->RespPort())));
|
||||
# define DBG_DPD_ARGS(conn, fmt, args...) \
|
||||
DBG_LOG(DBG_DPD, "%s " fmt, \
|
||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||
conn->RespAddr(), ntohs(conn->RespPort())), ##args);
|
||||
#else
|
||||
# define DBG_DPD(conn, txt)
|
||||
# define DBG_DPD_ARGS(conn, fmt, args...)
|
||||
#endif
|
||||
|
||||
// Map to assign expected connections to analyzers.
|
||||
class ExpectedConn {
|
||||
public:
|
||||
ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
||||
uint16 _resp_p, uint16 _proto);
|
||||
|
||||
ExpectedConn(const ExpectedConn& c);
|
||||
|
||||
IPAddr orig;
|
||||
IPAddr resp;
|
||||
uint16 resp_p;
|
||||
uint16 proto;
|
||||
};
|
||||
|
||||
// Associates an analyzer for an expected future connection.
|
||||
class AssignedAnalyzer {
|
||||
public:
|
||||
AssignedAnalyzer(const ExpectedConn& c)
|
||||
: conn(c)
|
||||
{
|
||||
}
|
||||
|
||||
ExpectedConn conn;
|
||||
AnalyzerTag::Tag analyzer;
|
||||
double timeout;
|
||||
void* cookie;
|
||||
bool deleted;
|
||||
|
||||
static bool compare(const AssignedAnalyzer* a1, const AssignedAnalyzer* a2)
|
||||
{ return a1->timeout > a2->timeout; }
|
||||
};
|
||||
|
||||
declare(PDict, AssignedAnalyzer);
|
||||
|
||||
class DPM {
|
||||
public:
|
||||
DPM();
|
||||
~DPM();
|
||||
|
||||
// Setup analyzer config.
|
||||
void PreScriptInit(); // To be called before scripts are parsed ...
|
||||
void PostScriptInit(); // ... and after.
|
||||
|
||||
// Given info about the first packet, build initial analyzer tree.
|
||||
//
|
||||
// It would be more flexible if we simply pass in the IP header
|
||||
// and then extract the information we need. However, when this
|
||||
// method is called from the session management, protocol and ports
|
||||
// have already been extracted there and it would be a waste to do
|
||||
// it again.
|
||||
//
|
||||
// Returns 0 if we can't build a tree (e.g., because the necessary
|
||||
// analyzers have not been converted to the DPM framework yet...)
|
||||
|
||||
bool BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||
const u_char* data);
|
||||
|
||||
// Schedules a particular analyzer for an upcoming connection.
|
||||
// 0 acts as a wildcard for orig. (Cookie is currently unused.
|
||||
// Eventually, we may pass it on to the analyzer).
|
||||
void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
||||
TransportProto proto, AnalyzerTag::Tag analyzer,
|
||||
double timeout, void* cookie);
|
||||
|
||||
// Activates signature matching for protocol detection. (Called when an
|
||||
// DPM signatures is found.)
|
||||
void ActivateSigs() { sigs_activated = true; }
|
||||
bool SigsActivated() const { return sigs_activated; }
|
||||
|
||||
void Done();
|
||||
|
||||
private:
|
||||
// Convert script-level config into internal data structures.
|
||||
void AddConfig(const Analyzer::Config& tag);
|
||||
|
||||
// Return analyzer if any has been scheduled with ExpectConnection()
|
||||
// AnalyzerTag::::Error if none.
|
||||
AnalyzerTag::Tag GetExpected(int proto, const Connection* conn);
|
||||
|
||||
// Mappings of destination port to analyzer.
|
||||
typedef list<AnalyzerTag::Tag> tag_list;
|
||||
typedef map<uint32, tag_list*> analyzer_map;
|
||||
analyzer_map tcp_ports;
|
||||
analyzer_map udp_ports;
|
||||
|
||||
// Array of bools indicating whether an analyzer is activated,
|
||||
// indexed by AnalyzerTag::Tag.
|
||||
bool* active_analyzers;
|
||||
|
||||
// True if signature-matching has been activated.
|
||||
bool sigs_activated;
|
||||
|
||||
PDict(AssignedAnalyzer) expected_conns;
|
||||
|
||||
typedef priority_queue<
|
||||
AssignedAnalyzer*,
|
||||
vector<AssignedAnalyzer*>,
|
||||
bool (*)(const AssignedAnalyzer*,
|
||||
const AssignedAnalyzer*)> conn_queue;
|
||||
conn_queue expected_conns_queue;
|
||||
};
|
||||
|
||||
extern DPM* dpm;
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@ enum DebugStream {
|
|||
DBG_STRING, // String code
|
||||
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
||||
DBG_MAINLOOP, // Main IOSource loop
|
||||
DBG_DPD, // Dynamic application detection framework
|
||||
DBG_ANALYZER, // Analyzer framework
|
||||
DBG_TM, // Time-machine packet input via Brocolli
|
||||
DBG_LOGGING, // Logging streams
|
||||
DBG_INPUT, // Input streams
|
||||
|
|
|
@ -13,7 +13,7 @@ int num_events_queued = 0;
|
|||
int num_events_dispatched = 0;
|
||||
|
||||
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
||||
SourceID arg_src, AnalyzerID arg_aid, TimerMgr* arg_mgr,
|
||||
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
||||
BroObj* arg_obj)
|
||||
{
|
||||
handler = arg_handler;
|
||||
|
|
16
src/Event.h
16
src/Event.h
|
@ -5,14 +5,16 @@
|
|||
|
||||
#include "EventRegistry.h"
|
||||
#include "Serializer.h"
|
||||
#include "AnalyzerTags.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
class EventMgr;
|
||||
|
||||
class Event : public BroObj {
|
||||
public:
|
||||
Event(EventHandlerPtr handler, val_list* args,
|
||||
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||
~Event();
|
||||
|
||||
|
@ -20,7 +22,7 @@ public:
|
|||
Event* NextEvent() const { return next_event; }
|
||||
|
||||
SourceID Source() const { return src; }
|
||||
AnalyzerID Analyzer() const { return aid; }
|
||||
analyzer::ID Analyzer() const { return aid; }
|
||||
TimerMgr* Mgr() const { return mgr; }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
|
@ -62,7 +64,7 @@ protected:
|
|||
EventHandlerPtr handler;
|
||||
val_list* args;
|
||||
SourceID src;
|
||||
AnalyzerID aid;
|
||||
analyzer::ID aid;
|
||||
TimerMgr* mgr;
|
||||
BroObj* obj;
|
||||
Event* next_event;
|
||||
|
@ -77,7 +79,7 @@ public:
|
|||
~EventMgr();
|
||||
|
||||
void QueueEvent(EventHandlerPtr h, val_list* vl,
|
||||
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0)
|
||||
{
|
||||
if ( h )
|
||||
|
@ -105,7 +107,7 @@ public:
|
|||
|
||||
// Returns the ID of the analyzer which raised the last event, or 0 if
|
||||
// non-analyzer event.
|
||||
AnalyzerID CurrentAnalyzer() const { return current_aid; }
|
||||
analyzer::ID CurrentAnalyzer() const { return current_aid; }
|
||||
|
||||
// Returns the timer mgr associated with the last raised event.
|
||||
TimerMgr* CurrentTimerMgr() const { return current_mgr; }
|
||||
|
@ -124,7 +126,7 @@ protected:
|
|||
Event* head;
|
||||
Event* tail;
|
||||
SourceID current_src;
|
||||
AnalyzerID current_aid;
|
||||
analyzer::ID current_aid;
|
||||
TimerMgr* current_mgr;
|
||||
RecordVal* src_val;
|
||||
bool draining;
|
||||
|
|
|
@ -10,7 +10,6 @@ EventHandler::EventHandler(const char* arg_name)
|
|||
used = false;
|
||||
local = 0;
|
||||
type = 0;
|
||||
group = 0;
|
||||
error_handler = false;
|
||||
enabled = true;
|
||||
}
|
||||
|
@ -19,7 +18,6 @@ EventHandler::~EventHandler()
|
|||
{
|
||||
Unref(local);
|
||||
delete [] name;
|
||||
delete [] group;
|
||||
}
|
||||
|
||||
EventHandler::operator bool() const
|
||||
|
|
|
@ -41,10 +41,6 @@ public:
|
|||
void SetErrorHandler() { error_handler = true; }
|
||||
bool ErrorHandler() { return error_handler; }
|
||||
|
||||
const char* Group() { return group; }
|
||||
void SetGroup(const char* arg_group)
|
||||
{ group = copy_string(arg_group); }
|
||||
|
||||
void SetEnable(bool arg_enable) { enabled = arg_enable; }
|
||||
|
||||
// We don't serialize the handler(s) itself here, but
|
||||
|
@ -54,7 +50,6 @@ public:
|
|||
|
||||
private:
|
||||
const char* name;
|
||||
const char* group;
|
||||
Func* local;
|
||||
FuncType* type;
|
||||
bool used; // this handler is indeed used somewhere
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "Val.h"
|
||||
#include "Analyzer.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
#include "EventLauncher.h"
|
||||
#include "Event.h"
|
||||
#include "NetVar.h"
|
||||
#include "Conn.h"
|
||||
|
||||
#include "event.bif.func_def"
|
||||
|
|
|
@ -80,20 +80,13 @@ void EventRegistry::PrintDebug()
|
|||
while ( (v = handlers.NextEntry(k, c)) )
|
||||
{
|
||||
delete k;
|
||||
fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(),
|
||||
v->LocalHandler()? "local" : "no");
|
||||
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
|
||||
v->LocalHandler()? "local" : "no",
|
||||
*v ? "active" : "not active"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void EventRegistry::SetGroup(const char* name, const char* group)
|
||||
{
|
||||
EventHandler* eh = Lookup(name);
|
||||
if ( ! eh )
|
||||
reporter->InternalError("unknown event handler in SetGroup()");
|
||||
|
||||
eh->SetGroup(group);
|
||||
}
|
||||
|
||||
void EventRegistry::SetErrorHandler(const char* name)
|
||||
{
|
||||
EventHandler* eh = Lookup(name);
|
||||
|
@ -103,18 +96,3 @@ void EventRegistry::SetErrorHandler(const char* name)
|
|||
eh->SetErrorHandler();
|
||||
}
|
||||
|
||||
void EventRegistry::EnableGroup(const char* group, bool enable)
|
||||
{
|
||||
IterCookie* c = handlers.InitForIteration();
|
||||
|
||||
HashKey* k;
|
||||
EventHandler* v;
|
||||
while ( (v = handlers.NextEntry(k, c)) )
|
||||
{
|
||||
delete k;
|
||||
|
||||
if ( v->Group() && strcmp(v->Group(), group) == 0 )
|
||||
v->SetEnable(enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,17 +26,11 @@ public:
|
|||
typedef PList(constchar) string_list;
|
||||
string_list* Match(RE_Matcher* pattern);
|
||||
|
||||
// Associates a group with the given event.
|
||||
void SetGroup(const char* name, const char* group);
|
||||
|
||||
// Marks a handler as handling errors. Error handler will not be called
|
||||
// recursively to avoid infinite loops in case they trigger an error
|
||||
// themselves.
|
||||
void SetErrorHandler(const char* name);
|
||||
|
||||
// Enable/disable all members of the group.
|
||||
void EnableGroup(const char* group, bool enable);
|
||||
|
||||
string_list* UnusedHandlers();
|
||||
string_list* UsedHandlers();
|
||||
void PrintDebug();
|
||||
|
|
30
src/Finger.h
30
src/Finger.h
|
@ -1,30 +0,0 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef finger_h
|
||||
#define finger_h
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
class ContentLine_Analyzer;
|
||||
|
||||
class Finger_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
Finger_Analyzer(Connection* conn);
|
||||
virtual ~Finger_Analyzer() {}
|
||||
|
||||
virtual void Done();
|
||||
// Line-based input.
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new Finger_Analyzer(conn); }
|
||||
|
||||
static bool Available() { return finger_request || finger_reply; }
|
||||
|
||||
protected:
|
||||
ContentLine_Analyzer* content_line_orig;
|
||||
ContentLine_Analyzer* content_line_resp;
|
||||
int did_deliver;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "FlowSrc.h"
|
||||
#include "Net.h"
|
||||
#include "netflow_pac.h"
|
||||
#include "analyzer/protocol/netflow/netflow_pac.h"
|
||||
#include <errno.h>
|
||||
|
||||
FlowSrc::FlowSrc()
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "Func.h"
|
||||
#include "Frame.h"
|
||||
#include "Var.h"
|
||||
#include "Login.h"
|
||||
#include "analyzer/protocol/login/Login.h"
|
||||
#include "Sessions.h"
|
||||
#include "RE.h"
|
||||
#include "Serializer.h"
|
||||
|
@ -553,18 +553,15 @@ void builtin_error(const char* msg, BroObj* arg)
|
|||
#include "input.bif.func_h"
|
||||
#include "reporter.bif.func_h"
|
||||
#include "strings.bif.func_h"
|
||||
#include "file_analysis.bif.func_h"
|
||||
|
||||
#include "bro.bif.func_def"
|
||||
#include "logging.bif.func_def"
|
||||
#include "input.bif.func_def"
|
||||
#include "reporter.bif.func_def"
|
||||
#include "strings.bif.func_def"
|
||||
#include "file_analysis.bif.func_def"
|
||||
|
||||
void init_builtin_funcs()
|
||||
{
|
||||
ftp_port = internal_type("ftp_port")->AsRecordType();
|
||||
bro_resources = internal_type("bro_resources")->AsRecordType();
|
||||
net_stats = internal_type("NetStats")->AsRecordType();
|
||||
matcher_stats = internal_type("matcher_stats")->AsRecordType();
|
||||
|
@ -576,7 +573,6 @@ void init_builtin_funcs()
|
|||
#include "input.bif.func_init"
|
||||
#include "reporter.bif.func_init"
|
||||
#include "strings.bif.func_init"
|
||||
#include "file_analysis.bif.func_init"
|
||||
|
||||
did_builtin_init = true;
|
||||
}
|
||||
|
|
1
src/H3.h
1
src/H3.h
|
@ -66,7 +66,6 @@ template<class T, int N> class H3 {
|
|||
T byte_lookup[N][H3_BYTE_RANGE];
|
||||
public:
|
||||
H3();
|
||||
~H3() { free(byte_lookup); }
|
||||
T operator()(const void* data, size_t size, size_t offset = 0) const
|
||||
{
|
||||
const unsigned char *p = static_cast<const unsigned char*>(data);
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
#include "HTTP-binpac.h"
|
||||
#include "TCP_Reassembler.h"
|
||||
|
||||
HTTP_Analyzer_binpac::HTTP_Analyzer_binpac(Connection *c)
|
||||
: TCP_ApplicationAnalyzer(AnalyzerTag::HTTP_BINPAC, c)
|
||||
{
|
||||
interp = new binpac::HTTP::HTTP_Conn(this);
|
||||
}
|
||||
|
||||
HTTP_Analyzer_binpac::~HTTP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::Done()
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Done();
|
||||
|
||||
interp->FlowEOF(true);
|
||||
interp->FlowEOF(false);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::EndpointEOF(bool is_orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||
interp->FlowEOF(is_orig);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||
|
||||
assert(TCP());
|
||||
|
||||
if ( TCP()->IsPartial() )
|
||||
// punt on partial.
|
||||
return;
|
||||
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||
interp->NewGap(orig, len);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef http_binpac_h
|
||||
#define http_binpac_h
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
#include "http_pac.h"
|
||||
|
||||
class HTTP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
HTTP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~HTTP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new HTTP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (http_request || http_reply) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::HTTP::HTTP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
16
src/ID.cc
16
src/ID.cc
|
@ -221,21 +221,7 @@ void ID::UpdateValAttrs()
|
|||
|
||||
if ( Type()->Tag() == TYPE_FUNC )
|
||||
{
|
||||
Attr* attr = attrs->FindAttr(ATTR_GROUP);
|
||||
|
||||
if ( attr )
|
||||
{
|
||||
Val* group = attr->AttrExpr()->ExprVal();
|
||||
if ( group )
|
||||
{
|
||||
if ( group->Type()->Tag() == TYPE_STRING )
|
||||
event_registry->SetGroup(Name(), group->AsString()->CheckString());
|
||||
else
|
||||
Error("&group attribute takes string");
|
||||
}
|
||||
}
|
||||
|
||||
attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
|
||||
Attr* attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
|
||||
|
||||
if ( attr )
|
||||
event_registry->SetErrorHandler(Name());
|
||||
|
|
1
src/ID.h
1
src/ID.h
|
@ -26,6 +26,7 @@ public:
|
|||
bool IsGlobal() const { return scope != SCOPE_FUNCTION; }
|
||||
|
||||
bool IsExport() const { return is_export; }
|
||||
void SetExport() { is_export = true; }
|
||||
|
||||
string ModuleName() const;
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include "IPAddr.h"
|
||||
#include "Reporter.h"
|
||||
#include "Conn.h"
|
||||
#include "DPM.h"
|
||||
#include "bro_inet_ntop.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0xff, 0xff };
|
||||
|
@ -44,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id)
|
|||
return new HashKey(&key, sizeof(key));
|
||||
}
|
||||
|
||||
HashKey* BuildExpectedConnHashKey(const ExpectedConn& c)
|
||||
{
|
||||
struct {
|
||||
in6_addr orig;
|
||||
in6_addr resp;
|
||||
uint16 resp_p;
|
||||
uint16 proto;
|
||||
} key;
|
||||
|
||||
key.orig = c.orig.in6;
|
||||
key.resp = c.resp.in6;
|
||||
key.resp_p = c.resp_p;
|
||||
key.proto = c.proto;
|
||||
|
||||
return new HashKey(&key, sizeof(key));
|
||||
}
|
||||
|
||||
void IPAddr::Mask(int top_bits_to_keep)
|
||||
{
|
||||
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "threading/SerialTypes.h"
|
||||
|
||||
struct ConnID;
|
||||
class ExpectedConn;
|
||||
namespace analyzer { class ExpectedConn; }
|
||||
|
||||
typedef in_addr in4_addr;
|
||||
|
||||
|
@ -363,7 +363,6 @@ public:
|
|||
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
||||
|
||||
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||
friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
|
||||
|
||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
||||
|
||||
|
@ -452,11 +451,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
|
|||
*/
|
||||
HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||
|
||||
/**
|
||||
* Returns a hash key for a given ExpectedConn instance. Passes ownership to caller.
|
||||
*/
|
||||
HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
|
||||
|
||||
/**
|
||||
* Class storing both IPv4 and IPv6 prefixes
|
||||
* (i.e., \c 192.168.1.1/16 and \c FD00::/8.
|
||||
|
|
58
src/Modbus.h
58
src/Modbus.h
|
@ -1,58 +0,0 @@
|
|||
#ifndef MODBUS_H
|
||||
#define MODBUS_H
|
||||
|
||||
#include "TCP.h"
|
||||
#include "modbus_pac.h"
|
||||
|
||||
class ModbusTCP_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
ModbusTCP_Analyzer(Connection* conn);
|
||||
virtual ~ModbusTCP_Analyzer();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new ModbusTCP_Analyzer(conn); }
|
||||
|
||||
// Put event names in this function
|
||||
static bool Available()
|
||||
{
|
||||
return modbus_message
|
||||
| modbus_exception
|
||||
| modbus_read_coils_request
|
||||
| modbus_read_coils_response
|
||||
| modbus_read_discrete_inputs_request
|
||||
| modbus_read_discrete_inputs_response
|
||||
| modbus_read_holding_registers_request
|
||||
| modbus_read_holding_registers_response
|
||||
| modbus_read_input_registers_request
|
||||
| modbus_read_input_registers_response
|
||||
| modbus_write_single_coil_request
|
||||
| modbus_write_single_coil_response
|
||||
| modbus_write_single_register_request
|
||||
| modbus_write_single_register_response
|
||||
| modbus_write_multiple_coils_request
|
||||
| modbus_write_multiple_coils_response
|
||||
| modbus_write_multiple_registers_request
|
||||
| modbus_write_multiple_registers_response
|
||||
| modbus_read_file_record_request
|
||||
| modbus_read_file_record_response
|
||||
| modbus_write_file_record_request
|
||||
| modbus_write_file_record_response
|
||||
| modbus_mask_write_register_request
|
||||
| modbus_mask_write_register_response
|
||||
| modbus_read_write_multiple_registers_request
|
||||
| modbus_read_write_multiple_registers_response
|
||||
| modbus_read_fifo_queue_request
|
||||
| modbus_read_fifo_queue_response;
|
||||
}
|
||||
|
||||
protected:
|
||||
binpac::ModbusTCP::ModbusTCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -94,7 +94,6 @@ RecordType* http_stats_rec;
|
|||
RecordType* http_message_stat;
|
||||
int truncate_http_URI;
|
||||
|
||||
int pm_request;
|
||||
RecordType* pm_mapping;
|
||||
TableType* pm_mappings;
|
||||
RecordType* pm_port_request;
|
||||
|
@ -209,7 +208,6 @@ TableType* irc_join_list;
|
|||
RecordType* irc_join_info;
|
||||
TableVal* irc_servers;
|
||||
|
||||
TableVal* dpd_config;
|
||||
int dpd_reassemble_first_packets;
|
||||
int dpd_buffer_size;
|
||||
int dpd_match_only_beginning;
|
||||
|
@ -251,7 +249,6 @@ OpaqueType* entropy_type;
|
|||
#include "logging.bif.netvar_def"
|
||||
#include "input.bif.netvar_def"
|
||||
#include "reporter.bif.netvar_def"
|
||||
#include "file_analysis.bif.netvar_def"
|
||||
|
||||
void init_event_handlers()
|
||||
{
|
||||
|
@ -319,7 +316,6 @@ void init_net_var()
|
|||
#include "logging.bif.netvar_init"
|
||||
#include "input.bif.netvar_init"
|
||||
#include "reporter.bif.netvar_init"
|
||||
#include "file_analysis.bif.netvar_init"
|
||||
|
||||
conn_id = internal_type("conn_id")->AsRecordType();
|
||||
endpoint = internal_type("endpoint")->AsRecordType();
|
||||
|
@ -423,14 +419,6 @@ void init_net_var()
|
|||
http_message_stat = internal_type("http_message_stat")->AsRecordType();
|
||||
truncate_http_URI = opt_internal_int("truncate_http_URI");
|
||||
|
||||
pm_request = pm_request_null || pm_request_set ||
|
||||
pm_request_unset || pm_request_getport ||
|
||||
pm_request_dump || pm_request_callit ||
|
||||
pm_attempt_null || pm_attempt_set ||
|
||||
pm_attempt_unset || pm_attempt_getport ||
|
||||
pm_attempt_dump || pm_attempt_callit ||
|
||||
pm_bad_port;
|
||||
|
||||
pm_mapping = internal_type("pm_mapping")->AsRecordType();
|
||||
pm_mappings = internal_type("pm_mappings")->AsTableType();
|
||||
pm_port_request = internal_type("pm_port_request")->AsRecordType();
|
||||
|
@ -526,7 +514,6 @@ void init_net_var()
|
|||
opt_internal_double("remote_trace_sync_interval");
|
||||
remote_trace_sync_peers = opt_internal_int("remote_trace_sync_peers");
|
||||
|
||||
dpd_config = internal_val("dpd_config")->AsTableVal();
|
||||
dpd_reassemble_first_packets =
|
||||
opt_internal_int("dpd_reassemble_first_packets");
|
||||
dpd_buffer_size = opt_internal_int("dpd_buffer_size");
|
||||
|
|
|
@ -97,7 +97,6 @@ extern RecordType* http_stats_rec;
|
|||
extern RecordType* http_message_stat;
|
||||
extern int truncate_http_URI;
|
||||
|
||||
extern int pm_request;
|
||||
extern RecordType* pm_mapping;
|
||||
extern TableType* pm_mappings;
|
||||
extern RecordType* pm_port_request;
|
||||
|
@ -213,7 +212,6 @@ extern TableType* irc_join_list;
|
|||
extern RecordType* irc_join_info;
|
||||
extern TableVal* irc_servers;
|
||||
|
||||
extern TableVal* dpd_config;
|
||||
extern int dpd_reassemble_first_packets;
|
||||
extern int dpd_buffer_size;
|
||||
extern int dpd_match_only_beginning;
|
||||
|
@ -262,6 +260,5 @@ extern void init_net_var();
|
|||
#include "logging.bif.netvar_h"
|
||||
#include "input.bif.netvar_h"
|
||||
#include "reporter.bif.netvar_h"
|
||||
#include "file_analysis.bif.netvar_h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,8 +8,9 @@ using std::string;
|
|||
#include "Conn.h"
|
||||
#include "Event.h"
|
||||
#include "NetVar.h"
|
||||
#include "DPM.h"
|
||||
#include "PIA.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
void RuleActionEvent::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
|
@ -34,42 +35,45 @@ void RuleActionEvent::PrintDebug()
|
|||
fprintf(stderr, " RuleActionEvent: |%s|\n", msg);
|
||||
}
|
||||
|
||||
RuleActionDPM::RuleActionDPM(const char* arg_analyzer)
|
||||
RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
|
||||
{
|
||||
string str(arg_analyzer);
|
||||
string::size_type pos = str.find(':');
|
||||
string arg = str.substr(0, pos);
|
||||
analyzer = Analyzer::GetTag(arg.c_str());
|
||||
analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
|
||||
|
||||
if ( ! analyzer )
|
||||
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
||||
|
||||
if ( pos != string::npos )
|
||||
{
|
||||
arg = str.substr(pos + 1);
|
||||
child_analyzer = Analyzer::GetTag(arg.c_str());
|
||||
child_analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
|
||||
|
||||
if ( ! child_analyzer )
|
||||
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
||||
}
|
||||
else
|
||||
child_analyzer = AnalyzerTag::Error;
|
||||
|
||||
if ( analyzer != AnalyzerTag::Error )
|
||||
dpm->ActivateSigs();
|
||||
child_analyzer = analyzer::Tag();
|
||||
}
|
||||
|
||||
void RuleActionDPM::PrintDebug()
|
||||
void RuleActionAnalyzer::PrintDebug()
|
||||
{
|
||||
if ( child_analyzer == AnalyzerTag::Error )
|
||||
fprintf(stderr, "|%s|\n", Analyzer::GetTagName(analyzer));
|
||||
if ( ! child_analyzer )
|
||||
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer));
|
||||
else
|
||||
fprintf(stderr, "|%s:%s|\n",
|
||||
Analyzer::GetTagName(analyzer),
|
||||
Analyzer::GetTagName(child_analyzer));
|
||||
analyzer_mgr->GetAnalyzerName(analyzer),
|
||||
analyzer_mgr->GetAnalyzerName(child_analyzer));
|
||||
}
|
||||
|
||||
|
||||
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
||||
if ( ! ChildAnalyzer() )
|
||||
{
|
||||
if ( ! Analyzer::IsAvailable(Analyzer()) )
|
||||
if ( ! analyzer_mgr->IsEnabled(Analyzer()) )
|
||||
return;
|
||||
|
||||
if ( state->PIA() )
|
||||
|
@ -77,7 +81,7 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( ! Analyzer::IsAvailable(ChildAnalyzer()) )
|
||||
if ( ! analyzer_mgr->IsEnabled(ChildAnalyzer()) )
|
||||
return;
|
||||
|
||||
// This is ugly and works only if there exists only one
|
||||
|
@ -90,13 +94,13 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
void RuleActionEnable::PrintDebug()
|
||||
{
|
||||
fprintf(stderr, " RuleActionEnable: ");
|
||||
RuleActionDPM::PrintDebug();
|
||||
RuleActionAnalyzer::PrintDebug();
|
||||
}
|
||||
|
||||
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
||||
if ( ! ChildAnalyzer() )
|
||||
{
|
||||
if ( state->PIA() )
|
||||
state->PIA()->DeactivateAnalyzer(Analyzer());
|
||||
|
@ -109,5 +113,5 @@ void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
void RuleActionDisable::PrintDebug()
|
||||
{
|
||||
fprintf(stderr, " RuleActionDisable: ");
|
||||
RuleActionDPM::PrintDebug();
|
||||
RuleActionAnalyzer::PrintDebug();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef ruleaction_h
|
||||
#define ruleaction_h
|
||||
|
||||
#include "AnalyzerTags.h"
|
||||
#include "BroString.h"
|
||||
#include "List.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
|
||||
class Rule;
|
||||
class RuleEndpointState;
|
||||
|
||||
|
@ -35,29 +36,27 @@ private:
|
|||
const char* msg;
|
||||
};
|
||||
|
||||
// Base class for DPM enable/disable actions.
|
||||
class RuleActionDPM : public RuleAction {
|
||||
// Base class for enable/disable actions.
|
||||
class RuleActionAnalyzer : public RuleAction {
|
||||
public:
|
||||
RuleActionDPM(const char* analyzer);
|
||||
RuleActionAnalyzer(const char* analyzer);
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) = 0;
|
||||
|
||||
virtual void PrintDebug();
|
||||
|
||||
AnalyzerTag::Tag Analyzer() const { return analyzer; }
|
||||
AnalyzerTag::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||
analyzer::Tag Analyzer() const { return analyzer; }
|
||||
analyzer::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||
|
||||
private:
|
||||
// FIXME: This is in fact an AnalyzerID but we can't include "Analyzer.h"
|
||||
// at this point due to circular dependenides. Fix that!
|
||||
AnalyzerTag::Tag analyzer;
|
||||
AnalyzerTag::Tag child_analyzer;
|
||||
analyzer::Tag analyzer;
|
||||
analyzer::Tag child_analyzer;
|
||||
};
|
||||
|
||||
class RuleActionEnable : public RuleActionDPM {
|
||||
class RuleActionEnable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionEnable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
||||
RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
|
@ -65,9 +64,9 @@ public:
|
|||
virtual void PrintDebug();
|
||||
};
|
||||
|
||||
class RuleActionDisable : public RuleActionDPM {
|
||||
class RuleActionDisable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionDisable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
||||
RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "RuleCondition.h"
|
||||
#include "TCP.h"
|
||||
#include "analyzer/protocol/tcp/TCP.h"
|
||||
#include "Scope.h"
|
||||
|
||||
static inline bool is_established(const TCP_Endpoint* e)
|
||||
static inline bool is_established(const analyzer::tcp::TCP_Endpoint* e)
|
||||
{
|
||||
// We more or less follow Snort here: an established session
|
||||
// is one for which the initial handshake has succeded (but we
|
||||
// add partial connections). The connection tear-down is part
|
||||
// of the connection.
|
||||
return e->state != TCP_ENDPOINT_INACTIVE &&
|
||||
e->state != TCP_ENDPOINT_SYN_SENT &&
|
||||
e->state != TCP_ENDPOINT_SYN_ACK_SENT;
|
||||
return e->state != analyzer::tcp::TCP_ENDPOINT_INACTIVE &&
|
||||
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_SENT &&
|
||||
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_ACK_SENT;
|
||||
}
|
||||
|
||||
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
||||
analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
||||
|
||||
if ( ! root || root->GetTag() != AnalyzerTag::TCP )
|
||||
if ( ! root || ! root->IsAnalyzer("TCP") )
|
||||
return false;
|
||||
|
||||
TCP_Analyzer* ta = static_cast<TCP_Analyzer*>(root);
|
||||
analyzer::tcp::TCP_Analyzer* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(root);
|
||||
|
||||
if ( tcpstates & STATE_STATELESS )
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "DFA.h"
|
||||
#include "NetVar.h"
|
||||
|
@ -159,9 +159,9 @@ void RuleHdrTest::PrintDebug()
|
|||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
RuleEndpointState::RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState::RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite,
|
||||
::PIA* arg_PIA)
|
||||
analyzer::pia::PIA* arg_PIA)
|
||||
{
|
||||
payload_size = -1;
|
||||
analyzer = arg_analyzer;
|
||||
|
@ -562,10 +562,10 @@ static inline bool compare(const vector<IPPrefix>& prefixes, const IPAddr& a,
|
|||
return false;
|
||||
}
|
||||
|
||||
RuleEndpointState* RuleMatcher::InitEndpoint(Analyzer* analyzer,
|
||||
RuleEndpointState* RuleMatcher::InitEndpoint(analyzer::Analyzer* analyzer,
|
||||
const IP_Hdr* ip, int caplen,
|
||||
RuleEndpointState* opposite,
|
||||
bool from_orig, PIA* pia)
|
||||
bool from_orig, analyzer::pia::PIA* pia)
|
||||
{
|
||||
RuleEndpointState* state =
|
||||
new RuleEndpointState(analyzer, from_orig, opposite, pia);
|
||||
|
@ -1300,8 +1300,8 @@ uint32 id_to_uint(const char* id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void RuleMatcherState::InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, PIA* pia)
|
||||
void RuleMatcherState::InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, analyzer::pia::PIA* pia)
|
||||
{
|
||||
if ( ! rule_matcher )
|
||||
return;
|
||||
|
|
|
@ -35,8 +35,10 @@ extern const char* current_rule_file;
|
|||
class RuleMatcher;
|
||||
extern RuleMatcher* rule_matcher;
|
||||
|
||||
class Analyzer;
|
||||
class PIA;
|
||||
namespace analyzer {
|
||||
namespace pia { class PIA; }
|
||||
class Analyzer;
|
||||
}
|
||||
|
||||
// RuleHdrTest and associated things:
|
||||
|
||||
|
@ -140,7 +142,7 @@ class RuleEndpointState {
|
|||
public:
|
||||
~RuleEndpointState();
|
||||
|
||||
Analyzer* GetAnalyzer() const { return analyzer; }
|
||||
analyzer::Analyzer* GetAnalyzer() const { return analyzer; }
|
||||
bool IsOrig() { return is_orig; }
|
||||
|
||||
// For flipping roles.
|
||||
|
@ -152,15 +154,15 @@ public:
|
|||
// Returns -1 if no chunk has been fed yet at all.
|
||||
int PayloadSize() { return payload_size; }
|
||||
|
||||
::PIA* PIA() const { return pia; }
|
||||
analyzer::pia::PIA* PIA() const { return pia; }
|
||||
|
||||
private:
|
||||
friend class RuleMatcher;
|
||||
|
||||
// Constructor is private; use RuleMatcher::InitEndpoint()
|
||||
// for creating an instance.
|
||||
RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite, ::PIA* arg_PIA);
|
||||
RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite, analyzer::pia::PIA* arg_PIA);
|
||||
|
||||
struct Matcher {
|
||||
RE_Match_State* state;
|
||||
|
@ -171,9 +173,9 @@ private:
|
|||
typedef PList(Matcher) matcher_list;
|
||||
|
||||
bool is_orig;
|
||||
Analyzer* analyzer;
|
||||
analyzer::Analyzer* analyzer;
|
||||
RuleEndpointState* opposite;
|
||||
::PIA* pia;
|
||||
analyzer::pia::PIA* pia;
|
||||
|
||||
matcher_list matchers;
|
||||
rule_hdr_test_list hdr_tests;
|
||||
|
@ -207,8 +209,8 @@ public:
|
|||
// the given packet (which should be the first packet encountered for
|
||||
// this endpoint). If the matching is triggered by an PIA, a pointer to
|
||||
// it needs to be given.
|
||||
RuleEndpointState* InitEndpoint(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, RuleEndpointState* opposite, bool is_orig, PIA* pia);
|
||||
RuleEndpointState* InitEndpoint(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, RuleEndpointState* opposite, bool is_orig, analyzer::pia::PIA* pia);
|
||||
|
||||
// Finish matching for this stream.
|
||||
void FinishEndpoint(RuleEndpointState* state);
|
||||
|
@ -310,8 +312,8 @@ public:
|
|||
{ delete orig_match_state; delete resp_match_state; }
|
||||
|
||||
// ip may be nil.
|
||||
void InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, PIA* pia = 0);
|
||||
void InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, analyzer::pia::PIA* pia = 0);
|
||||
|
||||
// bol/eol should be set to false for type Rule::PAYLOAD; they're
|
||||
// deduced automatically.
|
||||
|
|
26
src/SSH.h
26
src/SSH.h
|
@ -1,26 +0,0 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef ssh_h
|
||||
#define ssh_h
|
||||
|
||||
#include "TCP.h"
|
||||
#include "ContentLine.h"
|
||||
|
||||
class SSH_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
SSH_Analyzer(Connection* conn);
|
||||
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new SSH_Analyzer(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return ssh_client_version || ssh_server_version; }
|
||||
|
||||
private:
|
||||
ContentLine_Analyzer* orig;
|
||||
ContentLine_Analyzer* resp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,22 +16,25 @@
|
|||
#include "Reporter.h"
|
||||
#include "OSFinger.h"
|
||||
|
||||
#include "ICMP.h"
|
||||
#include "UDP.h"
|
||||
#include "analyzer/protocol/icmp/ICMP.h"
|
||||
#include "analyzer/protocol/udp/UDP.h"
|
||||
|
||||
#include "DNS-binpac.h"
|
||||
#include "HTTP-binpac.h"
|
||||
|
||||
#include "SteppingStone.h"
|
||||
#include "BackDoor.h"
|
||||
#include "InterConn.h"
|
||||
#include "analyzer/protocol/stepping-stone/SteppingStone.h"
|
||||
#include "analyzer/protocol/stepping-stone/events.bif.h"
|
||||
#include "analyzer/protocol/backdoor/BackDoor.h"
|
||||
#include "analyzer/protocol/backdoor/events.bif.h"
|
||||
#include "analyzer/protocol/interconn/InterConn.h"
|
||||
#include "analyzer/protocol/interconn/events.bif.h"
|
||||
#include "analyzer/protocol/arp/ARP.h"
|
||||
#include "analyzer/protocol/arp/events.bif.h"
|
||||
#include "Discard.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "DPM.h"
|
||||
|
||||
#include "PacketSort.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
// These represent NetBIOS services on ephemeral ports. They're numbered
|
||||
// so that we can use a single int to hold either an actual TCP/UDP server
|
||||
// port or one of these.
|
||||
|
@ -104,7 +107,7 @@ NetSessions::NetSessions()
|
|||
fragments.SetDeleteFunc(bro_obj_delete_func);
|
||||
|
||||
if ( stp_correlate_pair )
|
||||
stp_manager = new SteppingStoneManager();
|
||||
stp_manager = new analyzer::stepping_stone::SteppingStoneManager();
|
||||
else
|
||||
stp_manager = 0;
|
||||
|
||||
|
@ -143,7 +146,7 @@ NetSessions::NetSessions()
|
|||
pkt_profiler = 0;
|
||||
|
||||
if ( arp_request || arp_reply || bad_arp )
|
||||
arp_analyzer = new ARP_Analyzer();
|
||||
arp_analyzer = new analyzer::arp::ARP_Analyzer();
|
||||
else
|
||||
arp_analyzer = 0;
|
||||
}
|
||||
|
@ -256,7 +259,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0);
|
||||
}
|
||||
|
||||
else if ( ARP_Analyzer::IsARP(pkt, hdr_size) )
|
||||
else if ( analyzer::arp::ARP_Analyzer::IsARP(pkt, hdr_size) )
|
||||
{
|
||||
if ( arp_analyzer )
|
||||
arp_analyzer->NextPacket(t, hdr, pkt, hdr_size);
|
||||
|
@ -523,7 +526,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
const struct icmp* icmpp = (const struct icmp *) data;
|
||||
|
||||
id.src_port = icmpp->icmp_type;
|
||||
id.dst_port = ICMP4_counterpart(icmpp->icmp_type,
|
||||
id.dst_port = analyzer::icmp::ICMP4_counterpart(icmpp->icmp_type,
|
||||
icmpp->icmp_code,
|
||||
id.is_one_way);
|
||||
|
||||
|
@ -539,7 +542,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
const struct icmp* icmpp = (const struct icmp *) data;
|
||||
|
||||
id.src_port = icmpp->icmp_type;
|
||||
id.dst_port = ICMP6_counterpart(icmpp->icmp_type,
|
||||
id.dst_port = analyzer::icmp::ICMP6_counterpart(icmpp->icmp_type,
|
||||
icmpp->icmp_code,
|
||||
id.is_one_way);
|
||||
|
||||
|
@ -964,12 +967,12 @@ void NetSessions::Remove(Connection* c)
|
|||
{
|
||||
c->CancelTimers();
|
||||
|
||||
TCP_Analyzer* ta = (TCP_Analyzer*) c->GetRootAnalyzer();
|
||||
analyzer::tcp::TCP_Analyzer* ta = (analyzer::tcp::TCP_Analyzer*) c->GetRootAnalyzer();
|
||||
if ( ta && c->ConnTransport() == TRANSPORT_TCP )
|
||||
{
|
||||
assert(ta->GetTag() == AnalyzerTag::TCP);
|
||||
TCP_Endpoint* to = ta->Orig();
|
||||
TCP_Endpoint* tr = ta->Resp();
|
||||
assert(ta->IsAnalyzer("TCP"));
|
||||
analyzer::tcp::TCP_Endpoint* to = ta->Orig();
|
||||
analyzer::tcp::TCP_Endpoint* tr = ta->Resp();
|
||||
|
||||
tcp_stats.StateLeft(to->state, tr->state);
|
||||
}
|
||||
|
@ -1178,7 +1181,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
|||
|
||||
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
|
||||
conn->SetTransport(tproto);
|
||||
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
||||
analyzer_mgr->BuildInitialAnalyzerTree(conn);
|
||||
|
||||
bool external = conn->IsExternal();
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
#include "Dict.h"
|
||||
#include "CompHash.h"
|
||||
#include "IP.h"
|
||||
#include "ARP.h"
|
||||
#include "Frag.h"
|
||||
#include "PacketFilter.h"
|
||||
#include "Stats.h"
|
||||
#include "NetVar.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
#include "analyzer/protocol/tcp/Stats.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
struct pcap_pkthdr;
|
||||
|
@ -26,11 +27,12 @@ declare(PDict,Connection);
|
|||
declare(PDict,FragReassembler);
|
||||
|
||||
class Discarder;
|
||||
class SteppingStoneManager;
|
||||
class PacketFilter;
|
||||
|
||||
class PacketSortElement;
|
||||
|
||||
namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } }
|
||||
namespace analyzer { namespace arp { class ARP_Analyzer; } }
|
||||
|
||||
struct SessionStats {
|
||||
int num_TCP_conns;
|
||||
int num_UDP_conns;
|
||||
|
@ -127,7 +129,7 @@ public:
|
|||
|
||||
void ExpireTimerMgrs();
|
||||
|
||||
SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
||||
analyzer::stepping_stone::SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
||||
|
||||
unsigned int CurrentConnections()
|
||||
{
|
||||
|
@ -183,7 +185,7 @@ public:
|
|||
unsigned int ConnectionMemoryUsage();
|
||||
unsigned int ConnectionMemoryUsageConnVals();
|
||||
unsigned int MemoryAllocation();
|
||||
TCPStateStats tcp_stats; // keeps statistics on TCP states
|
||||
analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states
|
||||
|
||||
protected:
|
||||
friend class RemoteSerializer;
|
||||
|
@ -255,9 +257,9 @@ protected:
|
|||
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
|
||||
IPTunnelMap ip_tunnels;
|
||||
|
||||
ARP_Analyzer* arp_analyzer;
|
||||
analyzer::arp::ARP_Analyzer* arp_analyzer;
|
||||
|
||||
SteppingStoneManager* stp_manager;
|
||||
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
||||
Discarder* discarder;
|
||||
PacketFilter* packet_filter;
|
||||
OSFingerprint* SYN_OS_Fingerprinter;
|
||||
|
|
78
src/Stats.cc
78
src/Stats.cc
|
@ -389,84 +389,6 @@ void SegmentProfiler::Report()
|
|||
reporter->SegmentProfile(name, loc, dtime, dmem);
|
||||
}
|
||||
|
||||
|
||||
TCPStateStats::TCPStateStats()
|
||||
{
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j )
|
||||
state_cnt[i][j] = 0;
|
||||
}
|
||||
|
||||
void TCPStateStats::ChangeState(EndpointState o_prev, EndpointState o_now,
|
||||
EndpointState r_prev, EndpointState r_now)
|
||||
{
|
||||
--state_cnt[o_prev][r_prev];
|
||||
++state_cnt[o_now][r_now];
|
||||
}
|
||||
|
||||
void TCPStateStats::FlipState(EndpointState orig, EndpointState resp)
|
||||
{
|
||||
--state_cnt[orig][resp];
|
||||
++state_cnt[resp][orig];
|
||||
}
|
||||
|
||||
unsigned int TCPStateStats::NumStatePartial() const
|
||||
{
|
||||
unsigned int sum = 0;
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
{
|
||||
sum += state_cnt[TCP_ENDPOINT_PARTIAL][i];
|
||||
sum += state_cnt[i][TCP_ENDPOINT_PARTIAL];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void TCPStateStats::PrintStats(BroFile* file, const char* prefix)
|
||||
{
|
||||
file->Write(prefix);
|
||||
file->Write(" Inact. Syn. SA Part. Est. Fin. Rst.\n");
|
||||
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
{
|
||||
file->Write(prefix);
|
||||
|
||||
switch ( i ) {
|
||||
#define STATE_STRING(state, str) \
|
||||
case state: \
|
||||
file->Write(str); \
|
||||
break;
|
||||
|
||||
STATE_STRING(TCP_ENDPOINT_INACTIVE, "Inact.");
|
||||
STATE_STRING(TCP_ENDPOINT_SYN_SENT, "Syn. ");
|
||||
STATE_STRING(TCP_ENDPOINT_SYN_ACK_SENT, "SA ");
|
||||
STATE_STRING(TCP_ENDPOINT_PARTIAL, "Part. ");
|
||||
STATE_STRING(TCP_ENDPOINT_ESTABLISHED, "Est. ");
|
||||
STATE_STRING(TCP_ENDPOINT_CLOSED, "Fin. ");
|
||||
STATE_STRING(TCP_ENDPOINT_RESET, "Rst. ");
|
||||
|
||||
}
|
||||
|
||||
file->Write(" ");
|
||||
|
||||
for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j )
|
||||
{
|
||||
unsigned int n = state_cnt[i][j];
|
||||
if ( n > 0 )
|
||||
{
|
||||
char buf[32];
|
||||
safe_snprintf(buf, sizeof(buf), "%-8d", state_cnt[i][j]);
|
||||
file->Write(buf);
|
||||
}
|
||||
else
|
||||
file->Write(" ");
|
||||
}
|
||||
|
||||
file->Write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PacketProfiler::PacketProfiler(unsigned int mode, double freq,
|
||||
BroFile* arg_file)
|
||||
{
|
||||
|
|
64
src/Stats.h
64
src/Stats.h
|
@ -7,9 +7,6 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "TCP_Endpoint.h"
|
||||
|
||||
|
||||
// Object called by SegmentProfiler when it is done and reports its
|
||||
// cumulative CPU/memory statistics.
|
||||
class SegmentStatsReporter {
|
||||
|
@ -121,67 +118,6 @@ extern uint64 tot_ack_bytes;
|
|||
extern uint64 tot_gap_events;
|
||||
extern uint64 tot_gap_bytes;
|
||||
|
||||
|
||||
// A TCPStateStats object tracks the distribution of TCP states for
|
||||
// the currently active connections.
|
||||
class TCPStateStats {
|
||||
public:
|
||||
TCPStateStats();
|
||||
~TCPStateStats() { }
|
||||
|
||||
void ChangeState(EndpointState o_prev, EndpointState o_now,
|
||||
EndpointState r_prev, EndpointState r_now);
|
||||
void FlipState(EndpointState orig, EndpointState resp);
|
||||
|
||||
void StateEntered (EndpointState o_state, EndpointState r_state)
|
||||
{ ++state_cnt[o_state][r_state]; }
|
||||
void StateLeft (EndpointState o_state, EndpointState r_state)
|
||||
{ --state_cnt[o_state][r_state]; }
|
||||
|
||||
unsigned int Cnt(EndpointState state) const
|
||||
{ return Cnt(state, state); }
|
||||
unsigned int Cnt(EndpointState state1, EndpointState state2) const
|
||||
{ return state_cnt[state1][state2]; }
|
||||
|
||||
unsigned int NumStateEstablished() const
|
||||
{ return Cnt(TCP_ENDPOINT_ESTABLISHED); }
|
||||
unsigned int NumStateHalfClose() const
|
||||
{ // corresponds to S2,S3
|
||||
return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_CLOSED) +
|
||||
Cnt(TCP_ENDPOINT_CLOSED, TCP_ENDPOINT_ESTABLISHED);
|
||||
}
|
||||
unsigned int NumStateHalfRst() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_RESET) +
|
||||
Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_ESTABLISHED);
|
||||
}
|
||||
unsigned int NumStateClosed() const
|
||||
{ return Cnt(TCP_ENDPOINT_CLOSED); }
|
||||
unsigned int NumStateRequest() const
|
||||
{
|
||||
assert(Cnt(TCP_ENDPOINT_INACTIVE, TCP_ENDPOINT_SYN_SENT)==0);
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_INACTIVE);
|
||||
}
|
||||
unsigned int NumStateSuccRequest() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_SYN_ACK_SENT) +
|
||||
Cnt(TCP_ENDPOINT_SYN_ACK_SENT, TCP_ENDPOINT_SYN_SENT);
|
||||
}
|
||||
unsigned int NumStateRstRequest() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_RESET) +
|
||||
Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_SYN_SENT);
|
||||
}
|
||||
unsigned int NumStateInactive() const
|
||||
{ return Cnt(TCP_ENDPOINT_INACTIVE); }
|
||||
unsigned int NumStatePartial() const;
|
||||
|
||||
void PrintStats(BroFile* file, const char* prefix);
|
||||
|
||||
private:
|
||||
unsigned int state_cnt[TCP_ENDPOINT_RESET+1][TCP_ENDPOINT_RESET+1];
|
||||
};
|
||||
|
||||
class PacketProfiler {
|
||||
public:
|
||||
PacketProfiler(unsigned int mode, double freq, BroFile* arg_file);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef Syslog_binpac_h
|
||||
#define Syslog_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
|
||||
#include "syslog_pac.h"
|
||||
|
||||
class Syslog_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
Syslog_Analyzer_binpac(Connection* conn);
|
||||
virtual ~Syslog_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new Syslog_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return syslog_message; }
|
||||
|
||||
protected:
|
||||
friend class AnalyzerTimer;
|
||||
void ExpireTimer(double t);
|
||||
|
||||
int did_session_done;
|
||||
|
||||
binpac::Syslog::Syslog_Conn* interp;
|
||||
};
|
||||
|
||||
// #include "Syslog_tcp_pac.h"
|
||||
//
|
||||
//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
//public:
|
||||
// Syslog_TCP_Analyzer_binpac(Connection* conn);
|
||||
// virtual ~Syslog_TCP_Analyzer_binpac();
|
||||
//
|
||||
// virtual void Done();
|
||||
// virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
// virtual void Undelivered(int seq, int len, bool orig);
|
||||
// virtual void EndpointEOF(TCP_Reassembler* endp);
|
||||
//
|
||||
// static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
// { return new Syslog_TCP_Analyzer_binpac(conn); }
|
||||
//
|
||||
// static bool Available()
|
||||
// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; }
|
||||
//
|
||||
//protected:
|
||||
// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp;
|
||||
//};
|
||||
//
|
||||
#endif
|
10
src/Type.cc
10
src/Type.cc
|
@ -1334,6 +1334,16 @@ EnumType::EnumType(const string& arg_name)
|
|||
counter = 0;
|
||||
}
|
||||
|
||||
EnumType::EnumType(EnumType* e)
|
||||
: BroType(TYPE_ENUM)
|
||||
{
|
||||
name = e->name;
|
||||
counter = e->counter;
|
||||
|
||||
for ( NameMap::iterator it = e->names.begin(); it != e->names.end(); ++it )
|
||||
names[copy_string(it->first)] = it->second;
|
||||
}
|
||||
|
||||
EnumType::~EnumType()
|
||||
{
|
||||
for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter )
|
||||
|
|
|
@ -523,6 +523,7 @@ protected:
|
|||
class EnumType : public BroType {
|
||||
public:
|
||||
EnumType(const string& arg_name);
|
||||
EnumType(EnumType* e);
|
||||
~EnumType();
|
||||
|
||||
// The value of this name is next internal counter value, starting
|
||||
|
@ -567,6 +568,7 @@ protected:
|
|||
class CommentedEnumType: public EnumType {
|
||||
public:
|
||||
CommentedEnumType(const string& arg_name) : EnumType(arg_name) {}
|
||||
CommentedEnumType(EnumType* e) : EnumType(e) {}
|
||||
~CommentedEnumType();
|
||||
|
||||
void DescribeReST(ODesc* d) const;
|
||||
|
|
|
@ -1049,6 +1049,11 @@ StringVal::StringVal(const char* s) : Val(TYPE_STRING)
|
|||
val.string_val = new BroString(s);
|
||||
}
|
||||
|
||||
StringVal::StringVal(const string& s) : Val(TYPE_STRING)
|
||||
{
|
||||
val.string_val = new BroString(s.c_str());
|
||||
}
|
||||
|
||||
StringVal* StringVal::ToUpper()
|
||||
{
|
||||
val.string_val->ToUpper();
|
||||
|
|
|
@ -608,6 +608,7 @@ class StringVal : public Val {
|
|||
public:
|
||||
StringVal(BroString* s);
|
||||
StringVal(const char* s);
|
||||
StringVal(const string& s);
|
||||
StringVal(int length, const char* s);
|
||||
|
||||
Val* SizeVal() const
|
||||
|
|
|
@ -156,6 +156,12 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
|||
|
||||
if ( do_init )
|
||||
{
|
||||
if ( c == INIT_NONE && dt == VAR_REDEF && t->IsTable() &&
|
||||
init && init->Tag() == EXPR_ASSIGN )
|
||||
// e.g. 'redef foo["x"] = 1' is missing an init class, but the
|
||||
// intention clearly isn't to overwrite entire existing table val.
|
||||
c = INIT_EXTRA;
|
||||
|
||||
if ( (c == INIT_EXTRA && id->FindAttr(ATTR_ADD_FUNC)) ||
|
||||
(c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) )
|
||||
// Just apply the function.
|
||||
|
|
|
@ -1,191 +1,45 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "PIA.h"
|
||||
#include "Event.h"
|
||||
#include "Manager.h"
|
||||
|
||||
#include "AYIYA.h"
|
||||
#include "BackDoor.h"
|
||||
#include "BitTorrent.h"
|
||||
#include "BitTorrentTracker.h"
|
||||
#include "Finger.h"
|
||||
#include "InterConn.h"
|
||||
#include "NTP.h"
|
||||
#include "HTTP.h"
|
||||
#include "HTTP-binpac.h"
|
||||
#include "ICMP.h"
|
||||
#include "SteppingStone.h"
|
||||
#include "IRC.h"
|
||||
#include "SMTP.h"
|
||||
#include "FTP.h"
|
||||
#include "FileAnalyzer.h"
|
||||
#include "DNS.h"
|
||||
#include "DNS-binpac.h"
|
||||
#include "DHCP-binpac.h"
|
||||
#include "Telnet.h"
|
||||
#include "Rlogin.h"
|
||||
#include "RSH.h"
|
||||
#include "DCE_RPC.h"
|
||||
#include "Gnutella.h"
|
||||
#include "Ident.h"
|
||||
#include "Modbus.h"
|
||||
#include "NCP.h"
|
||||
#include "NetbiosSSN.h"
|
||||
#include "SMB.h"
|
||||
#include "NFS.h"
|
||||
#include "Portmap.h"
|
||||
#include "POP3.h"
|
||||
#include "SOCKS.h"
|
||||
#include "SSH.h"
|
||||
#include "SSL.h"
|
||||
#include "Syslog-binpac.h"
|
||||
#include "Teredo.h"
|
||||
#include "ConnSizeAnalyzer.h"
|
||||
#include "GTPv1.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
#include "../Event.h"
|
||||
|
||||
// Keep same order here as in AnalyzerTag definition!
|
||||
const Analyzer::Config Analyzer::analyzer_configs[] = {
|
||||
{ AnalyzerTag::Error, "<ERROR>", 0, 0, 0, false },
|
||||
namespace analyzer {
|
||||
|
||||
{ AnalyzerTag::PIA_TCP, "PIA_TCP", PIA_TCP::InstantiateAnalyzer,
|
||||
PIA_TCP::Available, 0, false },
|
||||
{ AnalyzerTag::PIA_UDP, "PIA_UDP", PIA_UDP::InstantiateAnalyzer,
|
||||
PIA_UDP::Available, 0, false },
|
||||
class AnalyzerTimer : public Timer {
|
||||
public:
|
||||
AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type);
|
||||
|
||||
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
|
||||
ICMP_Analyzer::Available, 0, false },
|
||||
virtual ~AnalyzerTimer();
|
||||
|
||||
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
|
||||
TCP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::UDP, "UDP", UDP_Analyzer::InstantiateAnalyzer,
|
||||
UDP_Analyzer::Available, 0, false },
|
||||
void Dispatch(double t, int is_expire);
|
||||
|
||||
{ AnalyzerTag::BitTorrent, "BITTORRENT",
|
||||
BitTorrent_Analyzer::InstantiateAnalyzer,
|
||||
BitTorrent_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::BitTorrentTracker, "BITTORRENTTRACKER",
|
||||
BitTorrentTracker_Analyzer::InstantiateAnalyzer,
|
||||
BitTorrentTracker_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::DCE_RPC, "DCE_RPC",
|
||||
DCE_RPC_Analyzer::InstantiateAnalyzer,
|
||||
DCE_RPC_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::DNS, "DNS", DNS_Analyzer::InstantiateAnalyzer,
|
||||
DNS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Finger, "FINGER", Finger_Analyzer::InstantiateAnalyzer,
|
||||
Finger_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::FTP, "FTP", FTP_Analyzer::InstantiateAnalyzer,
|
||||
FTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Gnutella, "GNUTELLA",
|
||||
Gnutella_Analyzer::InstantiateAnalyzer,
|
||||
Gnutella_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::HTTP, "HTTP", HTTP_Analyzer::InstantiateAnalyzer,
|
||||
HTTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Ident, "IDENT", Ident_Analyzer::InstantiateAnalyzer,
|
||||
Ident_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::IRC, "IRC", IRC_Analyzer::InstantiateAnalyzer,
|
||||
IRC_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Login, "LOGIN", 0, 0, 0, false }, // just a base class
|
||||
{ AnalyzerTag::NCP, "NCP", NCP_Analyzer::InstantiateAnalyzer,
|
||||
NCP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NetbiosSSN, "NetbiosSSN",
|
||||
NetbiosSSN_Analyzer::InstantiateAnalyzer,
|
||||
NetbiosSSN_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NFS, "NFS", NFS_Analyzer::InstantiateAnalyzer,
|
||||
NFS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NTP, "NTP", NTP_Analyzer::InstantiateAnalyzer,
|
||||
NTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::POP3, "POP3", POP3_Analyzer::InstantiateAnalyzer,
|
||||
POP3_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Portmapper, "PORTMAPPER",
|
||||
Portmapper_Analyzer::InstantiateAnalyzer,
|
||||
Portmapper_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Rlogin, "RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer,
|
||||
Rlogin_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::RPC, "RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Rsh, "RSH", Rsh_Analyzer::InstantiateAnalyzer,
|
||||
Rsh_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SMB, "SMB", SMB_Analyzer::InstantiateAnalyzer,
|
||||
SMB_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SMTP, "SMTP", SMTP_Analyzer::InstantiateAnalyzer,
|
||||
SMTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SSH, "SSH", SSH_Analyzer::InstantiateAnalyzer,
|
||||
SSH_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Telnet, "TELNET", Telnet_Analyzer::InstantiateAnalyzer,
|
||||
Telnet_Analyzer::Available, 0, false },
|
||||
protected:
|
||||
AnalyzerTimer() {}
|
||||
|
||||
{ AnalyzerTag::DHCP_BINPAC, "DHCP_BINPAC",
|
||||
DHCP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DHCP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::DNS_TCP_BINPAC, "DNS_TCP_BINPAC",
|
||||
DNS_TCP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DNS_TCP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::DNS_UDP_BINPAC, "DNS_UDP_BINPAC",
|
||||
DNS_UDP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DNS_UDP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::HTTP_BINPAC, "HTTP_BINPAC",
|
||||
HTTP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
HTTP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::SSL, "SSL",
|
||||
SSL_Analyzer::InstantiateAnalyzer,
|
||||
SSL_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC",
|
||||
Syslog_Analyzer_binpac::InstantiateAnalyzer,
|
||||
Syslog_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::Modbus, "MODBUS",
|
||||
ModbusTCP_Analyzer::InstantiateAnalyzer,
|
||||
ModbusTCP_Analyzer::Available, 0, false },
|
||||
void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
|
||||
|
||||
{ AnalyzerTag::AYIYA, "AYIYA",
|
||||
AYIYA_Analyzer::InstantiateAnalyzer,
|
||||
AYIYA_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SOCKS, "SOCKS",
|
||||
SOCKS_Analyzer::InstantiateAnalyzer,
|
||||
SOCKS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Teredo, "TEREDO",
|
||||
Teredo_Analyzer::InstantiateAnalyzer,
|
||||
Teredo_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::GTPv1, "GTPV1",
|
||||
GTPv1_Analyzer::InstantiateAnalyzer,
|
||||
GTPv1_Analyzer::Available, 0, false },
|
||||
|
||||
{ AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer,
|
||||
File_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::IRC_Data, "IRC_DATA", IRC_Data::InstantiateAnalyzer,
|
||||
IRC_Data::Available, 0, false },
|
||||
{ AnalyzerTag::FTP_Data, "FTP_DATA", FTP_Data::InstantiateAnalyzer,
|
||||
FTP_Data::Available, 0, false },
|
||||
{ AnalyzerTag::Backdoor, "BACKDOOR",
|
||||
BackDoor_Analyzer::InstantiateAnalyzer,
|
||||
BackDoor_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::InterConn, "INTERCONN",
|
||||
InterConn_Analyzer::InstantiateAnalyzer,
|
||||
InterConn_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SteppingStone, "STEPPINGSTONE",
|
||||
SteppingStone_Analyzer::InstantiateAnalyzer,
|
||||
SteppingStone_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::TCPStats, "TCPSTATS",
|
||||
TCPStats_Analyzer::InstantiateAnalyzer,
|
||||
TCPStats_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::ConnSize, "CONNSIZE",
|
||||
ConnSize_Analyzer::InstantiateAnalyzer,
|
||||
ConnSize_Analyzer::Available, 0, false },
|
||||
|
||||
{ AnalyzerTag::Contents, "CONTENTS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::ContentLine, "CONTENTLINE", 0, 0, 0, false },
|
||||
{ AnalyzerTag::NVT, "NVT", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Zip, "ZIP", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_DNS, "CONTENTS_DNS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NetbiosSSN, "CONTENTS_NETBIOSSSN", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NCP, "CONTENTS_NCP", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_Rlogin, "CONTENTS_Rlogin", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_Rsh, "CONTENTS_RSH", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_DCE_RPC, "CONTENTS_DCE_RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_SMB, "CONTENTS_SMB", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_RPC, "CONTENTS_RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NFS, "CONTENTS_NFS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::FTP_ADAT, "FTP_ADAT", 0, 0, 0, false },
|
||||
Analyzer* analyzer;
|
||||
analyzer_timer_func timer;
|
||||
int do_expire;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using namespace analyzer;
|
||||
|
||||
AnalyzerTimer::AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type)
|
||||
: Timer(arg_t, arg_type)
|
||||
{
|
||||
Init(arg_analyzer, arg_timer, arg_do_expire);
|
||||
}
|
||||
|
||||
AnalyzerTimer::~AnalyzerTimer()
|
||||
{
|
||||
analyzer->RemoveTimer(this);
|
||||
|
@ -216,36 +70,53 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
|||
Ref(analyzer->Conn());
|
||||
}
|
||||
|
||||
AnalyzerID Analyzer::id_counter = 0;;
|
||||
analyzer::ID Analyzer::id_counter = 0;;
|
||||
|
||||
Analyzer* Analyzer::InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c)
|
||||
const char* Analyzer::GetAnalyzerName() const
|
||||
{
|
||||
Analyzer* a = analyzer_configs[tag].factory(c);
|
||||
assert(a);
|
||||
return a;
|
||||
assert(tag);
|
||||
return analyzer_mgr->GetAnalyzerName(tag);
|
||||
}
|
||||
|
||||
const char* Analyzer::GetTagName(AnalyzerTag::Tag tag)
|
||||
void Analyzer::SetAnalyzerTag(const Tag& arg_tag)
|
||||
{
|
||||
return analyzer_configs[tag].name;
|
||||
assert(! tag || tag == arg_tag);
|
||||
tag = arg_tag;
|
||||
}
|
||||
|
||||
AnalyzerTag::Tag Analyzer::GetTag(const char* name)
|
||||
bool Analyzer::IsAnalyzer(const char* name)
|
||||
{
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
if ( strcasecmp(analyzer_configs[i].name, name) == 0 )
|
||||
return analyzer_configs[i].tag;
|
||||
|
||||
return AnalyzerTag::Error;
|
||||
assert(tag);
|
||||
return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0;
|
||||
}
|
||||
|
||||
// Used in debugging output.
|
||||
static string fmt_analyzer(Analyzer* a)
|
||||
{
|
||||
return string(a->GetTagName()) + fmt("[%d]", a->GetID());
|
||||
return string(a->GetAnalyzerName()) + fmt("[%d]", a->GetID());
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(AnalyzerTag::Tag arg_tag, Connection* arg_conn)
|
||||
Analyzer::Analyzer(const char* name, Connection* conn)
|
||||
{
|
||||
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
||||
|
||||
if ( ! tag )
|
||||
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name);
|
||||
|
||||
CtorInit(tag, conn);
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(const Tag& tag, Connection* conn)
|
||||
{
|
||||
CtorInit(tag, conn);
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(Connection* conn)
|
||||
{
|
||||
CtorInit(Tag(), conn);
|
||||
}
|
||||
|
||||
void Analyzer::CtorInit(const Tag& arg_tag, Connection* arg_conn)
|
||||
{
|
||||
// Don't Ref conn here to avoid circular ref'ing. It can't be deleted
|
||||
// before us.
|
||||
|
@ -355,11 +226,6 @@ void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq,
|
|||
}
|
||||
}
|
||||
|
||||
const char* Analyzer::GetTagName() const
|
||||
{
|
||||
return GetTagName(tag);
|
||||
}
|
||||
|
||||
void Analyzer::NextStream(int len, const u_char* data, bool is_orig)
|
||||
{
|
||||
if ( skip )
|
||||
|
@ -514,7 +380,7 @@ void Analyzer::ForwardEndOfData(bool orig)
|
|||
|
||||
void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
||||
{
|
||||
if ( HasChildAnalyzer(analyzer->GetTag()) )
|
||||
if ( HasChildAnalyzer(analyzer->GetAnalyzerTag()) )
|
||||
{
|
||||
analyzer->Done();
|
||||
delete analyzer;
|
||||
|
@ -533,16 +399,19 @@ void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
|||
if ( init )
|
||||
analyzer->Init();
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s added child %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s added child %s",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::AddChildAnalyzer(AnalyzerTag::Tag analyzer)
|
||||
Analyzer* Analyzer::AddChildAnalyzer(Tag analyzer)
|
||||
{
|
||||
if ( ! HasChildAnalyzer(analyzer) )
|
||||
{
|
||||
Analyzer* a = InstantiateAnalyzer(analyzer, conn);
|
||||
Analyzer* a = analyzer_mgr->InstantiateAnalyzer(analyzer, conn);
|
||||
|
||||
if ( a )
|
||||
AddChildAnalyzer(a);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -554,7 +423,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
|||
LOOP_OVER_CHILDREN(i)
|
||||
if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s disabling child %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s disabling child %s",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||
// We just flag it as being removed here but postpone
|
||||
// actually doing that to later. Otherwise, we'd need
|
||||
|
@ -567,12 +436,12 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
|||
}
|
||||
}
|
||||
|
||||
void Analyzer::RemoveChildAnalyzer(AnalyzerID id)
|
||||
void Analyzer::RemoveChildAnalyzer(ID id)
|
||||
{
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s disabling child %s", GetTagName(), id,
|
||||
DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName(), id,
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||
// See comment above.
|
||||
(*i)->removing = true;
|
||||
|
@ -580,7 +449,7 @@ void Analyzer::RemoveChildAnalyzer(AnalyzerID id)
|
|||
}
|
||||
}
|
||||
|
||||
bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
|
||||
bool Analyzer::HasChildAnalyzer(Tag tag)
|
||||
{
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
if ( (*i)->tag == tag )
|
||||
|
@ -593,7 +462,7 @@ bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
|
|||
return false;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
||||
Analyzer* Analyzer::FindChild(ID arg_id)
|
||||
{
|
||||
if ( id == arg_id )
|
||||
return this;
|
||||
|
@ -608,7 +477,7 @@ Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
||||
Analyzer* Analyzer::FindChild(Tag arg_tag)
|
||||
{
|
||||
if ( tag == arg_tag )
|
||||
return this;
|
||||
|
@ -623,6 +492,12 @@ Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(const char* name)
|
||||
{
|
||||
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
||||
return tag ? FindChild(tag) : 0;
|
||||
}
|
||||
|
||||
void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||
{
|
||||
Analyzer* child = *i;
|
||||
|
@ -636,7 +511,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
|||
child->removing = false;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s deleted child %s 3",
|
||||
DBG_LOG(DBG_ANALYZER, "%s deleted child %s 3",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str());
|
||||
|
||||
children.erase(i);
|
||||
|
@ -645,9 +520,9 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
|||
|
||||
void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||
{
|
||||
if ( HasSupportAnalyzer(analyzer->GetTag(), analyzer->IsOrig()) )
|
||||
if ( HasSupportAnalyzer(analyzer->GetAnalyzerTag(), analyzer->IsOrig()) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s already has %s %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s already has %s %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -675,7 +550,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
|
||||
analyzer->Init();
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s added %s support %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s added %s support %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -699,7 +574,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
else
|
||||
*head = s->sibling;
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s removed support %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s removed support %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -711,7 +586,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
return;
|
||||
}
|
||||
|
||||
bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
|
||||
bool Analyzer::HasSupportAnalyzer(Tag tag, bool orig)
|
||||
{
|
||||
SupportAnalyzer* s = orig ? orig_supporters : resp_supporters;
|
||||
for ( ; s; s = s->sibling )
|
||||
|
@ -724,33 +599,33 @@ bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
|
|||
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||
int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||
DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
|
||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||
}
|
||||
|
||||
void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s DeliverStream(%d, %s) [%s%s]",
|
||||
DBG_LOG(DBG_ANALYZER, "%s DeliverStream(%d, %s) [%s%s]",
|
||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F",
|
||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||
}
|
||||
|
||||
void Analyzer::Undelivered(int seq, int len, bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s Undelivered(%d, %d, %s)",
|
||||
DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)",
|
||||
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
|
||||
}
|
||||
|
||||
void Analyzer::EndOfData(bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s EndOfData(%s)",
|
||||
DBG_LOG(DBG_ANALYZER, "%s EndOfData(%s)",
|
||||
fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
|
||||
}
|
||||
|
||||
void Analyzer::FlipRoles()
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s FlipRoles()");
|
||||
DBG_LOG(DBG_ANALYZER, "%s FlipRoles()");
|
||||
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
(*i)->FlipRoles();
|
||||
|
@ -774,9 +649,12 @@ void Analyzer::ProtocolConfirmation()
|
|||
if ( protocol_confirmed )
|
||||
return;
|
||||
|
||||
EnumVal* tval = tag.AsEnumVal();
|
||||
Ref(tval);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(tag, TYPE_COUNT));
|
||||
vl->append(tval);
|
||||
vl->append(new Val(id, TYPE_COUNT));
|
||||
|
||||
// We immediately raise the event so that the analyzer can quickly
|
||||
|
@ -802,9 +680,12 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
|
|||
else
|
||||
r = new StringVal(reason);
|
||||
|
||||
EnumVal* tval = tag.AsEnumVal();
|
||||
Ref(tval);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(tag, TYPE_COUNT));
|
||||
vl->append(tval);
|
||||
vl->append(new Val(id, TYPE_COUNT));
|
||||
vl->append(r);
|
||||
|
||||
|
@ -876,6 +757,31 @@ void Analyzer::UpdateConnVal(RecordVal *conn_val)
|
|||
(*i)->UpdateConnVal(conn_val);
|
||||
}
|
||||
|
||||
RecordVal* Analyzer::BuildConnVal()
|
||||
{
|
||||
return conn->BuildConnVal();
|
||||
}
|
||||
|
||||
void Analyzer::Event(EventHandlerPtr f, const char* name)
|
||||
{
|
||||
conn->Event(f, this, name);
|
||||
}
|
||||
|
||||
void Analyzer::Event(EventHandlerPtr f, Val* v1, Val* v2)
|
||||
{
|
||||
conn->Event(f, this, v1, v2);
|
||||
}
|
||||
|
||||
void Analyzer::ConnectionEvent(EventHandlerPtr f, val_list* vl)
|
||||
{
|
||||
conn->ConnectionEvent(f, this, vl);
|
||||
}
|
||||
|
||||
void Analyzer::Weird(const char* name, const char* addl)
|
||||
{
|
||||
conn->Weird(name, addl);
|
||||
}
|
||||
|
||||
void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
|
||||
int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
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