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
|
2.1-675 | 2013-06-02 20:03:19 -0700
|
||||||
|
|
||||||
* Fix a compiler warning. (Robin Sommer)
|
* 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);
|
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
|
- The new file analysis framework moves most of the processing of file
|
||||||
content from script-land into the core, where it belongs. Much of
|
content from script-land into the core, where it belongs. See
|
||||||
this is an internal change, the framework comes with the following
|
doc/file-analysis.rst for more information.
|
||||||
user-visibible functionality (some of that was already available
|
|
||||||
before, but done differently):
|
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.]
|
[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
|
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
|
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']
|
objects = self.env.domaindata['bro']['objects']
|
||||||
key = (self.objtype, name)
|
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,
|
self.env.warn(self.env.docname,
|
||||||
'duplicate description of %s %s, ' %
|
'duplicate description of %s %s, ' %
|
||||||
(self.objtype, name) +
|
(self.objtype, name) +
|
||||||
|
@ -150,6 +151,12 @@ class BroEnum(BroGeneric):
|
||||||
#self.indexnode['entries'].append(('single', indextext,
|
#self.indexnode['entries'].append(('single', indextext,
|
||||||
# targetname, targetname))
|
# targetname, targetname))
|
||||||
m = sig.split()
|
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 m[1] == "Notice::Type":
|
||||||
if 'notices' not in self.env.domaindata['bro']:
|
if 'notices' not in self.env.domaindata['bro']:
|
||||||
self.env.domaindata['bro']['notices'] = []
|
self.env.domaindata['bro']['notices'] = []
|
||||||
|
|
|
@ -10,7 +10,7 @@ File Analysis
|
||||||
script-layer depending on which network protocol was involved in the
|
script-layer depending on which network protocol was involved in the
|
||||||
file transfer. Scripts written to analyze files over one protocol
|
file transfer. Scripts written to analyze files over one protocol
|
||||||
would have to be copied and modified to fit other protocols. The
|
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
|
presentation of file-related information. The information regarding
|
||||||
the protocol involved in transporting a file over the network is
|
the protocol involved in transporting a file over the network is
|
||||||
still available, but it no longer has to dictate how one organizes
|
still available, but it no longer has to dictate how one organizes
|
||||||
|
|
|
@ -46,7 +46,7 @@ Script Reference
|
||||||
scripts/packages
|
scripts/packages
|
||||||
scripts/index
|
scripts/index
|
||||||
scripts/builtins
|
scripts/builtins
|
||||||
scripts/bifs
|
scripts/proto-analyzers
|
||||||
|
|
||||||
Other Bro Components
|
Other Bro Components
|
||||||
--------------------
|
--------------------
|
||||||
|
|
|
@ -15,11 +15,11 @@ endif ()
|
||||||
#
|
#
|
||||||
# srcDir: the directory which contains broInput
|
# srcDir: the directory which contains broInput
|
||||||
# broInput: the file name of a bro policy script, any path prefix of this
|
# 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.
|
# documentation will be placed.
|
||||||
# group: optional name of group that the script documentation will belong to.
|
# 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
|
# If this is not given, the group is automatically set to any path portion
|
||||||
# the group is automatically by any path portion of the broInput argument.
|
# of the broInput argument.
|
||||||
#
|
#
|
||||||
# In addition to adding the makefile target, several CMake variables are set:
|
# 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(sumTextSrc ${absSrcPath})
|
||||||
set(ogSourceFile ${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)
|
if (NOT relDstDir)
|
||||||
set(docName "${basename}")
|
set(docName "${basename}")
|
||||||
|
@ -70,8 +64,6 @@ macro(REST_TARGET srcDir broInput)
|
||||||
|
|
||||||
if (NOT "${ARGN}" STREQUAL "")
|
if (NOT "${ARGN}" STREQUAL "")
|
||||||
set(group ${ARGN})
|
set(group ${ARGN})
|
||||||
elseif (${extension} STREQUAL ".bif.bro")
|
|
||||||
set(group bifs)
|
|
||||||
elseif (relDstDir)
|
elseif (relDstDir)
|
||||||
set(group ${relDstDir}/index)
|
set(group ${relDstDir}/index)
|
||||||
# add package index to master package list if not already in it
|
# 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.
|
# Schedule Bro scripts for which to generate documentation.
|
||||||
include(DocSourcesList.cmake)
|
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
|
# create temporary list of all docs to include in the master policy/index file
|
||||||
file(WRITE ${MASTER_POLICY_INDEX} "${MASTER_POLICY_INDEX_TEXT}")
|
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-default.bro internal)
|
||||||
rest_target(${psd} base/init-bare.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}/scripts base/bif/analyzer.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/const.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/bro.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/event.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/const.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/file_analysis.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/event.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/input.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/file_analysis.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/logging.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/input.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/reporter.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/logging.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/strings.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ARP.events.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/types.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/main.bro)
|
||||||
rest_target(${psd} base/frameworks/cluster/nodes/manager.bro)
|
rest_target(${psd} base/frameworks/cluster/nodes/manager.bro)
|
||||||
rest_target(${psd} base/frameworks/cluster/nodes/proxy.bro)
|
rest_target(${psd} base/frameworks/cluster/nodes/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/main.bro)
|
||||||
rest_target(${psd} policy/integration/barnyard2/types.bro)
|
rest_target(${psd} policy/integration/barnyard2/types.bro)
|
||||||
rest_target(${psd} policy/integration/collective-intel/main.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/app-metrics.bro)
|
||||||
rest_target(${psd} policy/misc/capture-loss.bro)
|
rest_target(${psd} policy/misc/capture-loss.bro)
|
||||||
rest_target(${psd} policy/misc/detect-traceroute/main.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,
|
443/tcp, 562/tcp,
|
||||||
} &redef;
|
} &redef;
|
||||||
|
|
||||||
# redefinitions of "dpd_config" are self-documenting and
|
|
||||||
# go into the generated doc's "Port Analysis" section
|
event bro_init()
|
||||||
redef dpd_config += {
|
{
|
||||||
[ANALYZER_SSL] = [$ports = example_ports]
|
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, example_ports);
|
||||||
};
|
}
|
||||||
|
|
||||||
# redefinitions of "Notice::Type" are self-documenting, but
|
# redefinitions of "Notice::Type" are self-documenting, but
|
||||||
# more information can be supplied in two different ways
|
# more information can be supplied in two different ways
|
||||||
|
|
|
@ -67,12 +67,12 @@ sourcedir=${thisdir}/../..
|
||||||
|
|
||||||
echo "$statictext" > $outfile
|
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
|
for file in $bifs
|
||||||
do
|
do
|
||||||
f=${file:2}.bro
|
f=${file:2}
|
||||||
echo "rest_target(\${CMAKE_BINARY_DIR}/src base/$f)" >> $outfile
|
echo "rest_target(\${CMAKE_BINARY_DIR}/scripts base/$f)" >> $outfile
|
||||||
done
|
done
|
||||||
|
|
||||||
scriptfiles=`( cd ${sourcedir}/scripts && find . -name \*\.bro | sort )`
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ export {
|
||||||
analyzer: string &log;
|
analyzer: string &log;
|
||||||
## The textual reason for the analysis failure.
|
## The textual reason for the analysis failure.
|
||||||
failure_reason: string &log;
|
failure_reason: string &log;
|
||||||
|
|
||||||
## Disabled analyzer IDs. This is only for internal tracking
|
## Disabled analyzer IDs. This is only for internal tracking
|
||||||
## so as to not attempt to disable analyzers multiple times.
|
## so as to not attempt to disable analyzers multiple times.
|
||||||
disabled_aids: set[count];
|
disabled_aids: set[count];
|
||||||
};
|
};
|
||||||
|
|
||||||
## Ignore violations which go this many bytes into the connection.
|
## Ignore violations which go this many bytes into the connection.
|
||||||
## Set to 0 to never ignore protocol violations.
|
## Set to 0 to never ignore protocol violations.
|
||||||
const ignore_violations_after = 10 * 1024 &redef;
|
const ignore_violations_after = 10 * 1024 &redef;
|
||||||
|
@ -41,41 +41,30 @@ redef record connection += {
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(DPD::LOG, [$columns=Info]);
|
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 )
|
if ( fmt("-%s",analyzer) in c$service )
|
||||||
delete c$service[fmt("-%s", analyzer)];
|
delete c$service[fmt("-%s", analyzer)];
|
||||||
|
|
||||||
add c$service[analyzer];
|
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
|
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
|
# If the service hasn't been confirmed yet, don't generate a log message
|
||||||
# for the protocol violation.
|
# for the protocol violation.
|
||||||
if ( analyzer !in c$service )
|
if ( analyzer !in c$service )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete c$service[analyzer];
|
delete c$service[analyzer];
|
||||||
add c$service[fmt("-%s", analyzer)];
|
add c$service[fmt("-%s", analyzer)];
|
||||||
|
|
||||||
local info: Info;
|
local info: Info;
|
||||||
info$ts=network_time();
|
info$ts=network_time();
|
||||||
info$uid=c$uid;
|
info$uid=c$uid;
|
||||||
|
@ -86,7 +75,7 @@ event protocol_violation(c: connection, atype: count, aid: count,
|
||||||
c$dpd = info;
|
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 )
|
if ( !c?$dpd || aid in c$dpd$disabled_aids )
|
||||||
return;
|
return;
|
||||||
|
@ -94,13 +83,13 @@ event protocol_violation(c: connection, atype: count, aid: count, reason: string
|
||||||
local size = c$orig$size + c$resp$size;
|
local size = c$orig$size + c$resp$size;
|
||||||
if ( ignore_violations_after > 0 && size > ignore_violations_after )
|
if ( ignore_violations_after > 0 && size > ignore_violations_after )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# Disable the analyzer that raised the last core-generated event.
|
# Disable the analyzer that raised the last core-generated event.
|
||||||
disable_analyzer(c$id, aid);
|
disable_analyzer(c$id, aid);
|
||||||
add c$dpd$disabled_aids[aid];
|
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
|
reason: string) &priority=-5
|
||||||
{
|
{
|
||||||
if ( c?$dpd )
|
if ( c?$dpd )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
##! An interface for driving the analysis of files, possibly independent of
|
##! An interface for driving the analysis of files, possibly independent of
|
||||||
##! any network protocol over which they're transported.
|
##! 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/frameworks/logging
|
||||||
@load base/utils/site
|
@load base/utils/site
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ export {
|
||||||
|
|
||||||
## A table that can be used to disable file analysis completely for
|
## A table that can be used to disable file analysis completely for
|
||||||
## any files transferred over given network protocol analyzers.
|
## 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
|
## The salt concatenated to unique file handle strings generated by
|
||||||
## :bro:see:`get_file_handle` before hashing them in to a file id
|
## :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
|
## A file analyis input stream type used to forward input data to the
|
||||||
## file analysis framework.
|
## file analysis framework.
|
||||||
type AnalysisDescription: record {
|
type AnalysisDescription: record {
|
||||||
|
|
||||||
## String that allows the reader to find the source.
|
## String that allows the reader to find the source.
|
||||||
## For `READER_ASCII`, this is the filename.
|
## For `READER_ASCII`, this is the filename.
|
||||||
source: string;
|
source: string;
|
||||||
|
@ -186,7 +185,7 @@ export {
|
||||||
global end_of_data: event(name: string, source:string);
|
global end_of_data: event(name: string, source:string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@load base/input.bif
|
@load base/bif/input.bif
|
||||||
|
|
||||||
|
|
||||||
module Input;
|
module Input;
|
||||||
|
|
|
@ -6,4 +6,12 @@ export {
|
||||||
## Separator between input records.
|
## Separator between input records.
|
||||||
## Please note that the separator has to be exactly one character long
|
## Please note that the separator has to be exactly one character long
|
||||||
const record_separator = "\n" &redef;
|
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.
|
# We keep a script-level copy of all filters so that we can manipulate them.
|
||||||
global filters: table[ID, string] of Filter;
|
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;
|
module Log;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
##! Note that this framework deals with the handling of internally generated
|
##! Note that this framework deals with the handling of internally generated
|
||||||
##! reporter messages, for the interface in to actually creating interface
|
##! reporter messages, for the interface in to actually creating interface
|
||||||
##! into actually creating reporter messages from the scripting layer, use
|
##! 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;
|
module Reporter;
|
||||||
|
|
||||||
|
|
|
@ -83,19 +83,17 @@ export {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ayiya_ports = { 5072/udp };
|
const ayiya_ports = { 5072/udp };
|
||||||
redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] };
|
|
||||||
|
|
||||||
const teredo_ports = { 3544/udp };
|
const teredo_ports = { 3544/udp };
|
||||||
redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] };
|
|
||||||
|
|
||||||
const gtpv1_ports = { 2152/udp, 2123/udp };
|
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 };
|
redef likely_server_ports += { ayiya_ports, teredo_ports, gtpv1_ports };
|
||||||
|
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(Tunnel::LOG, [$columns=Info]);
|
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)
|
function register_all(ecv: EncapsulatingConnVector)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@load base/const.bif
|
@load base/bif/const.bif.bro
|
||||||
@load base/types.bif
|
@load base/bif/types.bif
|
||||||
|
|
||||||
# Type declarations
|
# Type declarations
|
||||||
|
|
||||||
|
@ -222,17 +222,6 @@ type endpoint_stats: record {
|
||||||
endian_type: count;
|
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;
|
module Tunnel;
|
||||||
export {
|
export {
|
||||||
## Records the identity of an encapsulating parent of a tunneled connection.
|
## 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.
|
# Prototypes of Bro built-in functions.
|
||||||
@load base/strings.bif
|
@load base/bif/strings.bif
|
||||||
@load base/bro.bif
|
@load base/bif/bro.bif
|
||||||
@load base/reporter.bif
|
@load base/bif/reporter.bif
|
||||||
|
|
||||||
## Deprecated. This is superseded by the new logging framework.
|
## Deprecated. This is superseded by the new logging framework.
|
||||||
global log_file_name: function(tag: string): string &redef;
|
global log_file_name: function(tag: string): string &redef;
|
||||||
|
@ -2723,7 +2712,7 @@ export {
|
||||||
}
|
}
|
||||||
module GLOBAL;
|
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.
|
## BPF filter the user has set via the -f command line options. Empty if none.
|
||||||
const cmd_line_bpf_filter = "" &redef;
|
const cmd_line_bpf_filter = "" &redef;
|
||||||
|
@ -2913,34 +2902,11 @@ const remote_trace_sync_peers = 0 &redef;
|
||||||
## consistency check.
|
## consistency check.
|
||||||
const remote_check_sync_consistency = F &redef;
|
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
|
## Reassemble the beginning of all TCP connections before doing
|
||||||
## signature-matching. Enabling this provides more accurate matching at the
|
## signature-matching. Enabling this provides more accurate matching at the
|
||||||
## expensive of CPU cycles.
|
## expensive of CPU cycles.
|
||||||
##
|
##
|
||||||
## .. bro:see:: dpd_config dpd_buffer_size
|
## .. bro:see:: dpd_buffer_size
|
||||||
## dpd_match_only_beginning dpd_ignore_ports
|
## dpd_match_only_beginning dpd_ignore_ports
|
||||||
##
|
##
|
||||||
## .. note:: Despite the name, this option affects *all* signature matching, not
|
## .. 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
|
## activated afterwards. Then only analyzers that can deal with partial
|
||||||
## connections will be able to analyze the session.
|
## 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
|
## dpd_ignore_ports
|
||||||
const dpd_buffer_size = 1024 &redef;
|
const dpd_buffer_size = 1024 &redef;
|
||||||
|
|
||||||
## If true, stops signature matching if dpd_buffer_size has been reached.
|
## If true, stops signature matching if dpd_buffer_size has been reached.
|
||||||
##
|
##
|
||||||
## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size
|
## .. 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
|
## .. note:: Despite the name, this option affects *all* signature matching, not
|
||||||
## only signatures used for dynamic protocol detection.
|
## only signatures used for dynamic protocol detection.
|
||||||
const dpd_match_only_beginning = T &redef;
|
const dpd_match_only_beginning = T &redef;
|
||||||
|
|
||||||
## If true, don't consider any ports for deciding which protocol analyzer to
|
## 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
|
## .. 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;
|
const dpd_ignore_ports = F &redef;
|
||||||
|
|
||||||
## Ports which the core considers being likely used by servers. For ports in
|
## 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.
|
## connection if it misses the initial handshake.
|
||||||
const likely_server_ports: set[port] &redef;
|
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.
|
## Per-incident timer managers are drained after this amount of inactivity.
|
||||||
const timer_mgr_inactivity_timeout = 1 min &redef;
|
const timer_mgr_inactivity_timeout = 1 min &redef;
|
||||||
|
|
||||||
|
@ -3095,10 +3054,12 @@ module GLOBAL;
|
||||||
## Number of bytes per packet to capture from live interfaces.
|
## Number of bytes per packet to capture from live interfaces.
|
||||||
const snaplen = 8192 &redef;
|
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.
|
# BiFs and script-land defined types.
|
||||||
@load base/frameworks/logging
|
@load base/frameworks/logging
|
||||||
|
|
||||||
@load base/frameworks/input
|
@load base/frameworks/input
|
||||||
|
@load base/frameworks/analyzer
|
||||||
@load base/frameworks/files
|
@load base/frameworks/files
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# loaded in base/init-bare.bro
|
# loaded in base/init-bare.bro
|
||||||
#@load base/frameworks/logging
|
#@load base/frameworks/logging
|
||||||
@load base/frameworks/notice
|
@load base/frameworks/notice
|
||||||
|
@load base/frameworks/analyzer
|
||||||
@load base/frameworks/dpd
|
@load base/frameworks/dpd
|
||||||
@load base/frameworks/signatures
|
@load base/frameworks/signatures
|
||||||
@load base/frameworks/packet-filter
|
@load base/frameworks/packet-filter
|
||||||
|
|
|
@ -6,9 +6,9 @@ module Conn;
|
||||||
export {
|
export {
|
||||||
## Define inactivity timeouts by the service detected being used over
|
## Define inactivity timeouts by the service detected being used over
|
||||||
## the connection.
|
## 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.
|
# For interactive services, allow longer periods of inactivity.
|
||||||
[[ANALYZER_SSH, ANALYZER_FTP]] = 1 hrs,
|
[[Analyzer::ANALYZER_SSH, Analyzer::ANALYZER_FTP]] = 1 hrs,
|
||||||
} &redef;
|
} &redef;
|
||||||
|
|
||||||
## Define inactivity timeouts based on common protocol ports.
|
## 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 )
|
if ( atype in analyzer_inactivity_timeouts )
|
||||||
set_inactivity_timeout(c$id, analyzer_inactivity_timeouts[atype]);
|
set_inactivity_timeout(c$id, analyzer_inactivity_timeouts[atype]);
|
||||||
|
|
|
@ -130,19 +130,13 @@ redef capture_filters += {
|
||||||
["netbios-ns"] = "udp port 137",
|
["netbios-ns"] = "udp port 137",
|
||||||
};
|
};
|
||||||
|
|
||||||
const dns_ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
const ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||||
redef dpd_config += { [ANALYZER_DNS] = [$ports = dns_ports] };
|
redef likely_server_ports += { 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 };
|
|
||||||
|
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(DNS::LOG, [$columns=Info, $ev=log_dns]);
|
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
|
function new_session(c: connection, trans_id: count): Info
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
##! The logging this script does is primarily focused on logging FTP commands
|
##! The logging this script does is primarily focused on logging FTP commands
|
||||||
##! along with metadata. For example, if files are transferred, the argument
|
##! along with metadata. For example, if files are transferred, the argument
|
||||||
##! will take on the full path that the client is at along with the requested
|
##! will take on the full path that the client is at along with the requested
|
||||||
##! file name.
|
##! file name.
|
||||||
|
|
||||||
@load ./utils-commands
|
@load ./utils-commands
|
||||||
|
@ -13,16 +13,16 @@ module FTP;
|
||||||
export {
|
export {
|
||||||
## The FTP protocol logging stream identifier.
|
## The FTP protocol logging stream identifier.
|
||||||
redef enum Log::ID += { LOG };
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
## List of commands that should have their command/response pairs logged.
|
## List of commands that should have their command/response pairs logged.
|
||||||
const logged_commands = {
|
const logged_commands = {
|
||||||
"APPE", "DELE", "RETR", "STOR", "STOU", "ACCT", "PORT", "PASV", "EPRT",
|
"APPE", "DELE", "RETR", "STOR", "STOU", "ACCT", "PORT", "PASV", "EPRT",
|
||||||
"EPSV"
|
"EPSV"
|
||||||
} &redef;
|
} &redef;
|
||||||
|
|
||||||
## This setting changes if passwords used in FTP sessions are captured or not.
|
## This setting changes if passwords used in FTP sessions are captured or not.
|
||||||
const default_capture_password = F &redef;
|
const default_capture_password = F &redef;
|
||||||
|
|
||||||
## User IDs that can be considered "anonymous".
|
## User IDs that can be considered "anonymous".
|
||||||
const guest_ids = { "anonymous", "ftp", "ftpuser", "guest" } &redef;
|
const guest_ids = { "anonymous", "ftp", "ftpuser", "guest" } &redef;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export {
|
||||||
## The port at which the acceptor is listening for the data connection.
|
## The port at which the acceptor is listening for the data connection.
|
||||||
resp_p: port &log;
|
resp_p: port &log;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Info: record {
|
type Info: record {
|
||||||
## Time when the command was sent.
|
## Time when the command was sent.
|
||||||
ts: time &log;
|
ts: time &log;
|
||||||
|
@ -53,12 +53,12 @@ export {
|
||||||
command: string &log &optional;
|
command: string &log &optional;
|
||||||
## Argument for the command if one is given.
|
## Argument for the command if one is given.
|
||||||
arg: string &log &optional;
|
arg: string &log &optional;
|
||||||
|
|
||||||
## Libmagic "sniffed" file type if the command indicates a file transfer.
|
## Libmagic "sniffed" file type if the command indicates a file transfer.
|
||||||
mime_type: string &log &optional;
|
mime_type: string &log &optional;
|
||||||
## Size of the file if the command indicates a file transfer.
|
## Size of the file if the command indicates a file transfer.
|
||||||
file_size: count &log &optional;
|
file_size: count &log &optional;
|
||||||
|
|
||||||
## Reply code from the server in response to the command.
|
## Reply code from the server in response to the command.
|
||||||
reply_code: count &log &optional;
|
reply_code: count &log &optional;
|
||||||
## Reply message from the server in response to the command.
|
## Reply message from the server in response to the command.
|
||||||
|
@ -74,31 +74,31 @@ export {
|
||||||
## more concrete is discovered that the existing but unknown
|
## more concrete is discovered that the existing but unknown
|
||||||
## directory is ok to use.
|
## directory is ok to use.
|
||||||
cwd: string &default=".";
|
cwd: string &default=".";
|
||||||
|
|
||||||
## Command that is currently waiting for a response.
|
## Command that is currently waiting for a response.
|
||||||
cmdarg: CmdArg &optional;
|
cmdarg: CmdArg &optional;
|
||||||
## Queue for commands that have been sent but not yet responded to
|
## Queue for commands that have been sent but not yet responded to
|
||||||
## are tracked here.
|
## are tracked here.
|
||||||
pending_commands: PendingCmds;
|
pending_commands: PendingCmds;
|
||||||
|
|
||||||
## Indicates if the session is in active or passive mode.
|
## Indicates if the session is in active or passive mode.
|
||||||
passive: bool &default=F;
|
passive: bool &default=F;
|
||||||
|
|
||||||
## Determines if the password will be captured for this request.
|
## Determines if the password will be captured for this request.
|
||||||
capture_password: bool &default=default_capture_password;
|
capture_password: bool &default=default_capture_password;
|
||||||
};
|
};
|
||||||
|
|
||||||
## This record is to hold a parsed FTP reply code. For example, for the
|
## This record is to hold a parsed FTP reply code. For example, for the
|
||||||
## 201 status code, the digits would be parsed as: x->2, y->0, z=>1.
|
## 201 status code, the digits would be parsed as: x->2, y->0, z=>1.
|
||||||
type ReplyCode: record {
|
type ReplyCode: record {
|
||||||
x: count;
|
x: count;
|
||||||
y: count;
|
y: count;
|
||||||
z: count;
|
z: count;
|
||||||
};
|
};
|
||||||
|
|
||||||
## Parse FTP reply codes into the three constituent single digit values.
|
## Parse FTP reply codes into the three constituent single digit values.
|
||||||
global parse_ftp_reply_code: function(code: count): ReplyCode;
|
global parse_ftp_reply_code: function(code: count): ReplyCode;
|
||||||
|
|
||||||
## Event that can be handled to access the :bro:type:`FTP::Info`
|
## Event that can be handled to access the :bro:type:`FTP::Info`
|
||||||
## record as it is sent on to the logging framework.
|
## record as it is sent on to the logging framework.
|
||||||
global log_ftp: event(rec: Info);
|
global log_ftp: event(rec: Info);
|
||||||
|
@ -111,11 +111,10 @@ redef record connection += {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Configure DPD
|
# Configure DPD
|
||||||
const ports = { 21/tcp, 2811/tcp } &redef; # 2811/tcp is GridFTP.
|
|
||||||
redef capture_filters += { ["ftp"] = "port 21 and port 2811" };
|
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.
|
# Establish the variable for tracking expected connections.
|
||||||
global ftp_data_expected: table[addr, port] of Info &read_expire=5mins;
|
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
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(FTP::LOG, [$columns=Info, $ev=log_ftp]);
|
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
|
## A set of commands where the argument can be expected to refer
|
||||||
|
@ -166,7 +166,7 @@ function set_ftp_session(c: connection)
|
||||||
s$uid=c$uid;
|
s$uid=c$uid;
|
||||||
s$id=c$id;
|
s$id=c$id;
|
||||||
c$ftp=s;
|
c$ftp=s;
|
||||||
|
|
||||||
# Add a shim command so the server can respond with some init response.
|
# Add a shim command so the server can respond with some init response.
|
||||||
add_pending_cmd(c$ftp$pending_commands, "<init>", "");
|
add_pending_cmd(c$ftp$pending_commands, "<init>", "");
|
||||||
}
|
}
|
||||||
|
@ -178,13 +178,13 @@ function ftp_message(s: Info)
|
||||||
# or it's a deliberately logged command.
|
# or it's a deliberately logged command.
|
||||||
if ( |s$tags| > 0 || (s?$cmdarg && s$cmdarg$cmd in logged_commands) )
|
if ( |s$tags| > 0 || (s?$cmdarg && s$cmdarg$cmd in logged_commands) )
|
||||||
{
|
{
|
||||||
if ( s?$password &&
|
if ( s?$password &&
|
||||||
! s$capture_password &&
|
! s$capture_password &&
|
||||||
to_lower(s$user) !in guest_ids )
|
to_lower(s$user) !in guest_ids )
|
||||||
{
|
{
|
||||||
s$password = "<hidden>";
|
s$password = "<hidden>";
|
||||||
}
|
}
|
||||||
|
|
||||||
local arg = s$cmdarg$arg;
|
local arg = s$cmdarg$arg;
|
||||||
if ( s$cmdarg$cmd in file_cmds )
|
if ( s$cmdarg$cmd in file_cmds )
|
||||||
{
|
{
|
||||||
|
@ -194,7 +194,7 @@ function ftp_message(s: Info)
|
||||||
|
|
||||||
arg = fmt("ftp://%s%s", addr_to_uri(s$id$resp_h), comp_path);
|
arg = fmt("ftp://%s%s", addr_to_uri(s$id$resp_h), comp_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
s$ts=s$cmdarg$ts;
|
s$ts=s$cmdarg$ts;
|
||||||
s$command=s$cmdarg$cmd;
|
s$command=s$cmdarg$cmd;
|
||||||
if ( arg == "" )
|
if ( arg == "" )
|
||||||
|
@ -204,9 +204,9 @@ function ftp_message(s: Info)
|
||||||
|
|
||||||
Log::write(FTP::LOG, s);
|
Log::write(FTP::LOG, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
# The MIME and file_size fields are specific to file transfer commands
|
# The MIME and file_size fields are specific to file transfer commands
|
||||||
# and may not be used in all commands so they need reset to "blank"
|
# and may not be used in all commands so they need reset to "blank"
|
||||||
# values after logging.
|
# values after logging.
|
||||||
delete s$mime_type;
|
delete s$mime_type;
|
||||||
delete s$file_size;
|
delete s$file_size;
|
||||||
|
@ -221,8 +221,8 @@ function add_expected_data_channel(s: Info, chan: ExpectedDataChannel)
|
||||||
s$passive = chan$passive;
|
s$passive = chan$passive;
|
||||||
s$data_channel = chan;
|
s$data_channel = chan;
|
||||||
ftp_data_expected[chan$resp_h, chan$resp_p] = s;
|
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);
|
5mins);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ftp_request(c: connection, command: string, arg: string) &priority=5
|
event ftp_request(c: connection, command: string, arg: string) &priority=5
|
||||||
|
@ -237,19 +237,19 @@ event ftp_request(c: connection, command: string, arg: string) &priority=5
|
||||||
remove_pending_cmd(c$ftp$pending_commands, c$ftp$cmdarg);
|
remove_pending_cmd(c$ftp$pending_commands, c$ftp$cmdarg);
|
||||||
ftp_message(c$ftp);
|
ftp_message(c$ftp);
|
||||||
}
|
}
|
||||||
|
|
||||||
local id = c$id;
|
local id = c$id;
|
||||||
set_ftp_session(c);
|
set_ftp_session(c);
|
||||||
|
|
||||||
# Queue up the new command and argument
|
# Queue up the new command and argument
|
||||||
add_pending_cmd(c$ftp$pending_commands, command, arg);
|
add_pending_cmd(c$ftp$pending_commands, command, arg);
|
||||||
|
|
||||||
if ( command == "USER" )
|
if ( command == "USER" )
|
||||||
c$ftp$user = arg;
|
c$ftp$user = arg;
|
||||||
|
|
||||||
else if ( command == "PASS" )
|
else if ( command == "PASS" )
|
||||||
c$ftp$password = arg;
|
c$ftp$password = arg;
|
||||||
|
|
||||||
else if ( command == "PORT" || command == "EPRT" )
|
else if ( command == "PORT" || command == "EPRT" )
|
||||||
{
|
{
|
||||||
local data = (command == "PORT") ?
|
local data = (command == "PORT") ?
|
||||||
|
@ -277,7 +277,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
||||||
|
|
||||||
# TODO: figure out what to do with continued FTP response (not used much)
|
# TODO: figure out what to do with continued FTP response (not used much)
|
||||||
if ( cont_resp ) return;
|
if ( cont_resp ) return;
|
||||||
|
|
||||||
# TODO: do some sort of generic clear text login processing here.
|
# TODO: do some sort of generic clear text login processing here.
|
||||||
local response_xyz = parse_ftp_reply_code(code);
|
local response_xyz = parse_ftp_reply_code(code);
|
||||||
#if ( response_xyz$x == 2 && # successful
|
#if ( response_xyz$x == 2 && # successful
|
||||||
|
@ -293,17 +293,17 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
||||||
# if that's given as well which would be more correct.
|
# if that's given as well which would be more correct.
|
||||||
c$ftp$file_size = extract_count(msg);
|
c$ftp$file_size = extract_count(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
# PASV and EPSV processing
|
# PASV and EPSV processing
|
||||||
else if ( (code == 227 || code == 229) &&
|
else if ( (code == 227 || code == 229) &&
|
||||||
(c$ftp$cmdarg$cmd == "PASV" || c$ftp$cmdarg$cmd == "EPSV") )
|
(c$ftp$cmdarg$cmd == "PASV" || c$ftp$cmdarg$cmd == "EPSV") )
|
||||||
{
|
{
|
||||||
local data = (code == 227) ? parse_ftp_pasv(msg) : parse_ftp_epsv(msg);
|
local data = (code == 227) ? parse_ftp_pasv(msg) : parse_ftp_epsv(msg);
|
||||||
|
|
||||||
if ( data$valid )
|
if ( data$valid )
|
||||||
{
|
{
|
||||||
c$ftp$passive=T;
|
c$ftp$passive=T;
|
||||||
|
|
||||||
if ( code == 229 && data$h == [::] )
|
if ( code == 229 && data$h == [::] )
|
||||||
data$h = c$id$resp_h;
|
data$h = c$id$resp_h;
|
||||||
|
|
||||||
|
@ -327,9 +327,9 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
||||||
else if ( c$ftp$cmdarg$cmd == "PWD" || c$ftp$cmdarg$cmd == "XPWD" )
|
else if ( c$ftp$cmdarg$cmd == "PWD" || c$ftp$cmdarg$cmd == "XPWD" )
|
||||||
c$ftp$cwd = extract_path(msg);
|
c$ftp$cwd = extract_path(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
# In case there are multiple commands queued, go ahead and remove the
|
# In case there are multiple commands queued, go ahead and remove the
|
||||||
# command here and log because we can't do the normal processing pipeline
|
# command here and log because we can't do the normal processing pipeline
|
||||||
# to wait for a new command before logging the command/response pair.
|
# to wait for a new command before logging the command/response pair.
|
||||||
if ( |c$ftp$pending_commands| > 1 )
|
if ( |c$ftp$pending_commands| > 1 )
|
||||||
{
|
{
|
||||||
|
@ -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;
|
local id = c$id;
|
||||||
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
||||||
|
@ -361,7 +361,7 @@ event connection_reused(c: connection) &priority=5
|
||||||
if ( "ftp-data" in c$service )
|
if ( "ftp-data" in c$service )
|
||||||
c$ftp_data_reuse = T;
|
c$ftp_data_reuse = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
event connection_state_remove(c: connection) &priority=-5
|
event connection_state_remove(c: connection) &priority=-5
|
||||||
{
|
{
|
||||||
if ( c$ftp_data_reuse ) return;
|
if ( c$ftp_data_reuse ) return;
|
||||||
|
|
|
@ -127,29 +127,26 @@ redef record connection += {
|
||||||
http_state: State &optional;
|
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.
|
# 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 += {
|
redef capture_filters += {
|
||||||
["http"] = "tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888)"
|
["http"] = "tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888)"
|
||||||
};
|
};
|
||||||
|
|
||||||
redef likely_server_ports += {
|
const ports = {
|
||||||
80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3138/tcp,
|
80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3128/tcp,
|
||||||
8000/tcp, 8080/tcp, 8888/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
|
function code_in_range(c: count, min: count, max: count) : bool
|
||||||
{
|
{
|
||||||
return c >= min && c <= max;
|
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_name = argument;
|
||||||
c$irc$dcc_file_size = size;
|
c$irc$dcc_file_size = size;
|
||||||
local p = count_to_port(dest_port, tcp);
|
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;
|
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;
|
local id = c$id;
|
||||||
if ( [id$resp_h, id$resp_p] in dcc_expected_transfers )
|
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" };
|
redef capture_filters += { ["irc-6669"] = "port 6669" };
|
||||||
|
|
||||||
# DPD configuration.
|
# DPD configuration.
|
||||||
const irc_ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
const ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||||
redef dpd_config += { [ANALYZER_IRC] = [$ports = irc_ports] };
|
redef likely_server_ports += { ports };
|
||||||
|
|
||||||
redef likely_server_ports += { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
|
||||||
|
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(IRC::LOG, [$columns=Info, $ev=irc_log]);
|
Log::create_stream(IRC::LOG, [$columns=Info, $ev=irc_log]);
|
||||||
|
Analyzer::register_for_ports(Analyzer::ANALYZER_IRC, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
function new_session(c: connection): Info
|
function new_session(c: connection): Info
|
||||||
|
|
|
@ -31,12 +31,14 @@ redef record connection += {
|
||||||
|
|
||||||
# Configure DPD and the packet filter.
|
# Configure DPD and the packet filter.
|
||||||
redef capture_filters += { ["modbus"] = "tcp port 502" };
|
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
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(Modbus::LOG, [$columns=Info, $ev=log_modbus]);
|
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
|
event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool) &priority=5
|
||||||
|
|
|
@ -74,9 +74,6 @@ export {
|
||||||
const mail_path_capture = ALL_HOSTS &redef;
|
const mail_path_capture = ALL_HOSTS &redef;
|
||||||
|
|
||||||
global log_smtp: event(rec: Info);
|
global log_smtp: event(rec: Info);
|
||||||
|
|
||||||
## Configure the default ports for SMTP analysis.
|
|
||||||
const ports = { 25/tcp, 587/tcp } &redef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redef record connection += {
|
redef record connection += {
|
||||||
|
@ -86,13 +83,14 @@ redef record connection += {
|
||||||
|
|
||||||
# Configure DPD
|
# Configure DPD
|
||||||
redef capture_filters += { ["smtp"] = "tcp port 25 or tcp port 587" };
|
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
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(SMTP::LOG, [$columns=SMTP::Info, $ev=log_smtp]);
|
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
|
function find_address_in_smtp_header(header: string): string
|
||||||
|
|
|
@ -34,9 +34,13 @@ export {
|
||||||
global log_socks: event(rec: Info);
|
global log_socks: event(rec: Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ports = { 1080/tcp };
|
||||||
|
redef likely_server_ports += { ports };
|
||||||
|
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]);
|
Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]);
|
||||||
|
Analyzer::register_for_ports(Analyzer::ANALYZER_SOCKS, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
redef record connection += {
|
redef record connection += {
|
||||||
|
@ -45,7 +49,6 @@ redef record connection += {
|
||||||
|
|
||||||
# Configure DPD
|
# Configure DPD
|
||||||
redef capture_filters += { ["socks"] = "tcp port 1080" };
|
redef capture_filters += { ["socks"] = "tcp port 1080" };
|
||||||
redef dpd_config += { [ANALYZER_SOCKS] = [$ports = set(1080/tcp)] };
|
|
||||||
redef likely_server_ports += { 1080/tcp };
|
redef likely_server_ports += { 1080/tcp };
|
||||||
|
|
||||||
function set_session(c: connection, version: count)
|
function set_session(c: connection, version: count)
|
||||||
|
|
|
@ -71,10 +71,11 @@ export {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configure DPD and the packet filter
|
# 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 += {
|
redef record connection += {
|
||||||
ssh: Info &optional;
|
ssh: Info &optional;
|
||||||
|
@ -83,6 +84,7 @@ redef record connection += {
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]);
|
Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]);
|
||||||
|
Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_session(c: connection)
|
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.
|
# Responder must have sent fewer than 40 packets.
|
||||||
c$resp$num_pkts < 40 &&
|
c$resp$num_pkts < 40 &&
|
||||||
# If there was a content gap we can't reliably do this heuristic.
|
# 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.
|
# Only "normal" connections can count.
|
||||||
#c$conn?$conn_state && c$conn$conn_state in valid_states )
|
#c$conn?$conn_state && c$conn$conn_state in valid_states )
|
||||||
{
|
{
|
||||||
|
@ -176,6 +178,7 @@ event ssh_watcher(c: connection)
|
||||||
if ( ! connection_exists(id) )
|
if ( ! connection_exists(id) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
lookup_connection(c$id);
|
||||||
check_ssh_connection(c, F);
|
check_ssh_connection(c, F);
|
||||||
if ( ! c$ssh$done )
|
if ( ! c$ssh$done )
|
||||||
schedule +15secs { ssh_watcher(c) };
|
schedule +15secs { ssh_watcher(c) };
|
||||||
|
|
|
@ -94,11 +94,6 @@ redef record Info += {
|
||||||
delay_tokens: set[string] &optional;
|
delay_tokens: set[string] &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
event bro_init() &priority=5
|
|
||||||
{
|
|
||||||
Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]);
|
|
||||||
}
|
|
||||||
|
|
||||||
redef capture_filters += {
|
redef capture_filters += {
|
||||||
["ssl"] = "tcp port 443",
|
["ssl"] = "tcp port 443",
|
||||||
["nntps"] = "tcp port 563",
|
["nntps"] = "tcp port 563",
|
||||||
|
@ -117,23 +112,15 @@ redef capture_filters += {
|
||||||
const ports = {
|
const ports = {
|
||||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
||||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
||||||
};
|
} &redef;
|
||||||
|
|
||||||
redef dpd_config += {
|
redef likely_server_ports += { ports };
|
||||||
[[ANALYZER_SSL]] = [$ports = ports]
|
|
||||||
};
|
|
||||||
|
|
||||||
redef likely_server_ports += {
|
event bro_init() &priority=5
|
||||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
{
|
||||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]);
|
||||||
};
|
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, ports);
|
||||||
|
}
|
||||||
# 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;
|
|
||||||
|
|
||||||
function set_session(c: connection)
|
function set_session(c: connection)
|
||||||
{
|
{
|
||||||
|
@ -144,26 +131,17 @@ function set_session(c: connection)
|
||||||
|
|
||||||
function delay_log(info: Info, token: string)
|
function delay_log(info: Info, token: string)
|
||||||
{
|
{
|
||||||
info$delay_tokens = set();
|
if ( ! info?$delay_tokens )
|
||||||
|
info$delay_tokens = set();
|
||||||
add info$delay_tokens[token];
|
add info$delay_tokens[token];
|
||||||
|
|
||||||
log_delay_queue[log_delay_queue_head] = info;
|
|
||||||
++log_delay_queue_head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function undelay_log(info: Info, token: string)
|
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];
|
delete info$delay_tokens[token];
|
||||||
}
|
}
|
||||||
|
|
||||||
global log_record: function(info: Info);
|
|
||||||
|
|
||||||
event delay_logging(info: Info)
|
|
||||||
{
|
|
||||||
log_record(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
function log_record(info: Info)
|
function log_record(info: Info)
|
||||||
{
|
{
|
||||||
if ( ! info?$delay_tokens || |info$delay_tokens| == 0 )
|
if ( ! info?$delay_tokens || |info$delay_tokens| == 0 )
|
||||||
|
@ -172,26 +150,14 @@ function log_record(info: Info)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( unused_index in log_delay_queue )
|
when ( |info$delay_tokens| == 0 )
|
||||||
{
|
{
|
||||||
if ( log_delay_queue_head == log_delay_queue_tail )
|
log_record(info);
|
||||||
return;
|
}
|
||||||
if ( |log_delay_queue[log_delay_queue_tail]$delay_tokens| > 0 )
|
timeout max_log_delay
|
||||||
{
|
{
|
||||||
if ( info$ts + max_log_delay > network_time() )
|
Reporter::info(fmt("SSL delay tokens not released in time (%s tokens remaining)",
|
||||||
{
|
|info$delay_tokens|));
|
||||||
schedule 1sec { delay_logging(info) };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,28 +254,16 @@ event ssl_established(c: connection) &priority=-5
|
||||||
finish(c);
|
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.
|
# 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;
|
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
|
reason: string) &priority=5
|
||||||
{
|
{
|
||||||
if ( c?$ssl )
|
if ( c?$ssl )
|
||||||
finish(c);
|
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" };
|
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 += {
|
redef record connection += {
|
||||||
syslog: Info &optional;
|
syslog: Info &optional;
|
||||||
|
@ -39,6 +38,7 @@ redef record connection += {
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(Syslog::LOG, [$columns=Info]);
|
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
|
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 };
|
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.
|
# A couple of ports commonly used for benign HTTP servers.
|
||||||
|
|
||||||
# For now we want to see everything.
|
# For now we want to see everything.
|
||||||
|
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING,
|
# [Analyzer::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, 8081/tcp] = OUTGOING,
|
||||||
#
|
#
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
||||||
# [ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella
|
# [Analyzer::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, 6348/tcp] = BOTH, # Gnutella
|
||||||
} &redef;
|
} &redef;
|
||||||
|
|
||||||
# Set of analyzers for which we suppress Server_Found notices
|
# 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
|
# log files, this also saves memory because for these we don't
|
||||||
# need to remember which servers we already have reported, which
|
# need to remember which servers we already have reported, which
|
||||||
# for some can be a lot.
|
# for some can be a lot.
|
||||||
const suppress_servers: set [count] = {
|
const suppress_servers: set [Analyzer::Tag] = {
|
||||||
# ANALYZER_HTTP
|
# Analyzer::ANALYZER_HTTP
|
||||||
} &redef;
|
} &redef;
|
||||||
|
|
||||||
# We consider a connection to use a protocol X if the analyzer for X
|
# 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
|
# Entry point for other analyzers to report that they recognized
|
||||||
# a certain (sub-)protocol.
|
# a certain (sub-)protocol.
|
||||||
global found_protocol: function(c: connection, analyzer: count,
|
global found_protocol: function(c: connection, analyzer: Analyzer::Tag,
|
||||||
protocol: string);
|
protocol: string);
|
||||||
|
|
||||||
# Table keeping reported (server, port, analyzer) tuples (and their
|
# Table keeping reported (server, port, analyzer) tuples (and their
|
||||||
|
@ -70,7 +70,7 @@ export {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Table that tracks currently active dynamic analyzers per connection.
|
# 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.
|
# Table of reports by other analyzers about the protocol used in a connection.
|
||||||
global protocols: table[conn_id] of set[string];
|
global protocols: table[conn_id] of set[string];
|
||||||
|
@ -80,7 +80,7 @@ type protocol : record {
|
||||||
sub: string; # "sub-protocols" reported by other sources
|
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 = "";
|
local str = "";
|
||||||
if ( c$id in protocols )
|
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;
|
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
|
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;
|
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 )
|
if ( d == BOTH )
|
||||||
return;
|
return;
|
||||||
|
@ -113,7 +113,7 @@ function do_notice(c: connection, a: count, d: dir)
|
||||||
|
|
||||||
NOTICE([$note=Protocol_Found,
|
NOTICE([$note=Protocol_Found,
|
||||||
$msg=fmt("%s %s on port %s", id_string(c$id), s, c$id$resp_p),
|
$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
|
# We report multiple Server_Found's per host if we find a new
|
||||||
# sub-protocol.
|
# sub-protocol.
|
||||||
|
@ -129,7 +129,7 @@ function do_notice(c: connection, a: count, d: dir)
|
||||||
NOTICE([$note=Server_Found,
|
NOTICE([$note=Server_Found,
|
||||||
$msg=fmt("%s: %s server on port %s%s", c$id$resp_h, s,
|
$msg=fmt("%s: %s server on port %s%s", c$id$resp_h, s,
|
||||||
c$id$resp_p, (known ? " (update)" : "")),
|
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 )
|
if ( ! known )
|
||||||
servers[c$id$resp_h, c$id$resp_p, p$a] = set();
|
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);
|
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.
|
# 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;
|
return;
|
||||||
|
|
||||||
if ( c$id in conns )
|
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.
|
# Don't report anything running on a well-known port.
|
||||||
if ( analyzer in dpd_config &&
|
if ( c$id$resp_p in Analyzer::registered_ports(atype) )
|
||||||
c$id$resp_p in dpd_config[analyzer]$ports )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( c$id !in protocols )
|
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
|
reason: string) &priority=4
|
||||||
{
|
{
|
||||||
if ( ! c?$dpd ) return;
|
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 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);
|
known_services_done(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
@load integration/barnyard2/types.bro
|
@load integration/barnyard2/types.bro
|
||||||
@load integration/collective-intel/__load__.bro
|
@load integration/collective-intel/__load__.bro
|
||||||
@load integration/collective-intel/main.bro
|
@load integration/collective-intel/main.bro
|
||||||
@load misc/analysis-groups.bro
|
|
||||||
@load misc/app-metrics.bro
|
@load misc/app-metrics.bro
|
||||||
@load misc/capture-loss.bro
|
@load misc/capture-loss.bro
|
||||||
@load misc/detect-traceroute/__load__.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;
|
return base64_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& arg_alphabet)
|
||||||
|
|
||||||
Base64Converter::Base64Converter(Analyzer* arg_analyzer, const string& arg_alphabet)
|
|
||||||
{
|
{
|
||||||
if ( arg_alphabet.size() > 0 )
|
if ( arg_alphabet.size() > 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "BroString.h"
|
#include "BroString.h"
|
||||||
#include "Analyzer.h"
|
#include "Reporter.h"
|
||||||
|
#include "analyzer/Analyzer.h"
|
||||||
|
|
||||||
// Maybe we should have a base class for generic decoders?
|
// Maybe we should have a base class for generic decoders?
|
||||||
class Base64Converter {
|
class Base64Converter {
|
||||||
|
@ -15,7 +16,7 @@ public:
|
||||||
// <analyzer> is used for error reporting, and it should be zero when
|
// <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().
|
// the decoder is called by the built-in function decode_base64() or encode_base64().
|
||||||
// Empty alphabet indicates the default base64 alphabet.
|
// Empty alphabet indicates the default base64 alphabet.
|
||||||
Base64Converter(Analyzer* analyzer, const string& alphabet = "");
|
Base64Converter(analyzer::Analyzer* analyzer, const string& alphabet = "");
|
||||||
~Base64Converter();
|
~Base64Converter();
|
||||||
|
|
||||||
// A note on Decode():
|
// A note on Decode():
|
||||||
|
@ -62,7 +63,7 @@ protected:
|
||||||
int base64_after_padding;
|
int base64_after_padding;
|
||||||
int* base64_table;
|
int* base64_table;
|
||||||
int errored; // if true, we encountered an error - skip further processing
|
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 "BroDoc.h"
|
||||||
#include "BroDocObj.h"
|
#include "BroDocObj.h"
|
||||||
#include "util.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)
|
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;
|
downloadable_filename = source_filename;
|
||||||
|
|
||||||
|
#if 0
|
||||||
size_t ext_pos = downloadable_filename.find(".bif.bro");
|
size_t ext_pos = downloadable_filename.find(".bif.bro");
|
||||||
if ( std::string::npos != ext_pos )
|
if ( std::string::npos != ext_pos )
|
||||||
downloadable_filename.erase(ext_pos + 4);
|
downloadable_filename.erase(ext_pos + 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
reST_filename = doc_title;
|
reST_filename = doc_title;
|
||||||
ext_pos = reST_filename.find(".bro");
|
size_t ext_pos = reST_filename.find(".bro");
|
||||||
|
|
||||||
if ( std::string::npos == ext_pos )
|
if ( std::string::npos == ext_pos )
|
||||||
reST_filename += ".rst";
|
reST_filename += ".rst";
|
||||||
|
@ -162,84 +167,77 @@ void BroDoc::SetPacketFilter(const std::string& s)
|
||||||
packet_filter.clear();
|
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
|
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", '-');
|
// WriteSectionHeading(reST_file, "Overview", '-');
|
||||||
WriteStringList("%s\n", summary);
|
WriteStringList(reST_file, "%s\n", summary);
|
||||||
|
|
||||||
WriteToDoc("\n");
|
WriteToDoc(reST_file, "\n");
|
||||||
|
|
||||||
if ( ! modules.empty() )
|
if ( ! modules.empty() )
|
||||||
{
|
{
|
||||||
WriteToDoc(":Namespace%s: ", (modules.size() > 1 ? "s" : ""));
|
WriteToDoc(reST_file, ":Namespace%s: ", (modules.size() > 1 ? "s" : ""));
|
||||||
// WriteStringList(":bro:namespace:`%s`", modules);
|
// WriteStringList(reST_file, ":bro:namespace:`%s`", modules);
|
||||||
WriteStringList("``%s``, ", "``%s``", modules);
|
WriteStringList(reST_file, "``%s``, ", "``%s``", modules);
|
||||||
WriteToDoc("\n");
|
WriteToDoc(reST_file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! imports.empty() )
|
if ( ! imports.empty() )
|
||||||
{
|
{
|
||||||
WriteToDoc(":Imports: ");
|
WriteToDoc(reST_file, ":Imports: ");
|
||||||
std::list<std::string>::const_iterator it;
|
std::list<std::string>::const_iterator it;
|
||||||
for ( it = imports.begin(); it != imports.end(); ++it )
|
for ( it = imports.begin(); it != imports.end(); ++it )
|
||||||
{
|
{
|
||||||
if ( it != imports.begin() )
|
if ( it != imports.begin() )
|
||||||
WriteToDoc(", ");
|
WriteToDoc(reST_file, ", ");
|
||||||
|
|
||||||
string pretty(*it);
|
string pretty(*it);
|
||||||
size_t pos = pretty.find("/index");
|
size_t pos = pretty.find("/index");
|
||||||
if ( pos != std::string::npos && pos + 6 == pretty.size() )
|
if ( pos != std::string::npos && pos + 6 == pretty.size() )
|
||||||
pretty = pretty.substr(0, pos);
|
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());
|
downloadable_filename.c_str());
|
||||||
|
|
||||||
WriteToDoc("\n");
|
WriteToDoc(reST_file, "\n");
|
||||||
|
|
||||||
WriteInterface("Summary", '~', '#', true, true);
|
WriteInterface("Summary", '~', '#', true, true);
|
||||||
|
|
||||||
if ( ! notices.empty() )
|
if ( ! notices.empty() )
|
||||||
WriteBroDocObjList(notices, "Notices", '#');
|
WriteBroDocObjList(reST_file, notices, "Notices", '#');
|
||||||
|
|
||||||
if ( port_analysis.size() || packet_filter.size() )
|
if ( port_analysis.size() || packet_filter.size() )
|
||||||
WriteSectionHeading("Configuration Changes", '#');
|
WriteSectionHeading(reST_file, "Configuration Changes", '#');
|
||||||
|
|
||||||
if ( ! port_analysis.empty() )
|
if ( ! port_analysis.empty() )
|
||||||
{
|
{
|
||||||
WriteSectionHeading("Port Analysis", '^');
|
WriteSectionHeading(reST_file, "Port Analysis", '^');
|
||||||
WriteToDoc("Loading this script makes the following changes to "
|
WriteToDoc(reST_file, "Loading this script makes the following changes to "
|
||||||
":bro:see:`dpd_config`.\n\n");
|
":bro:see:`dpd_config`.\n\n");
|
||||||
WriteStringList("%s, ", "%s", port_analysis);
|
WriteStringList(reST_file, "%s, ", "%s", port_analysis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! packet_filter.empty() )
|
if ( ! packet_filter.empty() )
|
||||||
{
|
{
|
||||||
WriteSectionHeading("Packet Filter", '^');
|
WriteSectionHeading(reST_file, "Packet Filter", '^');
|
||||||
WriteToDoc("Loading this script makes the following changes to "
|
WriteToDoc(reST_file, "Loading this script makes the following changes to "
|
||||||
":bro:see:`capture_filters`.\n\n");
|
":bro:see:`capture_filters`.\n\n");
|
||||||
WriteToDoc("Filters added::\n\n");
|
WriteToDoc(reST_file, "Filters added::\n\n");
|
||||||
WriteToDoc("%s\n", packet_filter.c_str());
|
WriteToDoc(reST_file, "%s\n", packet_filter.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteInterface("Detailed Interface", '~', '#', true, false);
|
WriteInterface("Detailed Interface", '~', '#', true, false);
|
||||||
|
@ -265,23 +263,23 @@ void BroDoc::WriteDocFile() const
|
||||||
void BroDoc::WriteInterface(const char* heading, char underline,
|
void BroDoc::WriteInterface(const char* heading, char underline,
|
||||||
char sub, bool isPublic, bool isShort) const
|
char sub, bool isPublic, bool isShort) const
|
||||||
{
|
{
|
||||||
WriteSectionHeading(heading, underline);
|
WriteSectionHeading(reST_file, heading, underline);
|
||||||
WriteBroDocObjList(options, isPublic, "Options", sub, isShort);
|
WriteBroDocObjList(reST_file, options, isPublic, "Options", sub, isShort);
|
||||||
WriteBroDocObjList(constants, isPublic, "Constants", sub, isShort);
|
WriteBroDocObjList(reST_file, constants, isPublic, "Constants", sub, isShort);
|
||||||
WriteBroDocObjList(state_vars, isPublic, "State Variables", sub, isShort);
|
WriteBroDocObjList(reST_file, state_vars, isPublic, "State Variables", sub, isShort);
|
||||||
WriteBroDocObjList(types, isPublic, "Types", sub, isShort);
|
WriteBroDocObjList(reST_file, types, isPublic, "Types", sub, isShort);
|
||||||
WriteBroDocObjList(events, isPublic, "Events", sub, isShort);
|
WriteBroDocObjList(reST_file, events, isPublic, "Events", sub, isShort);
|
||||||
WriteBroDocObjList(hooks, isPublic, "Hooks", sub, isShort);
|
WriteBroDocObjList(reST_file, hooks, isPublic, "Hooks", sub, isShort);
|
||||||
WriteBroDocObjList(functions, isPublic, "Functions", sub, isShort);
|
WriteBroDocObjList(reST_file, functions, isPublic, "Functions", sub, isShort);
|
||||||
WriteBroDocObjList(redefs, isPublic, "Redefinitions", sub, isShort);
|
WriteBroDocObjList(reST_file, redefs, isPublic, "Redefinitions", sub, isShort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BroDoc::WriteStringList(const char* format, const char* last_format,
|
void BroDoc::WriteStringList(FILE* f, const char* format, const char* last_format,
|
||||||
const std::list<std::string>& l) const
|
const std::list<std::string>& l)
|
||||||
{
|
{
|
||||||
if ( l.empty() )
|
if ( l.empty() )
|
||||||
{
|
{
|
||||||
WriteToDoc("\n");
|
WriteToDoc(f, "\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,12 +288,12 @@ void BroDoc::WriteStringList(const char* format, const char* last_format,
|
||||||
last--;
|
last--;
|
||||||
|
|
||||||
for ( it = l.begin(); it != last; ++it )
|
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_id_col = 0;
|
||||||
int max_com_col = 0;
|
int max_com_col = 0;
|
||||||
|
@ -315,38 +313,38 @@ void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start table.
|
// Start table.
|
||||||
WriteRepeatedChar('=', max_id_col);
|
WriteRepeatedChar(f, '=', max_id_col);
|
||||||
WriteToDoc(" ");
|
WriteToDoc(f, " ");
|
||||||
|
|
||||||
if ( max_com_col == 0 )
|
if ( max_com_col == 0 )
|
||||||
WriteToDoc("=");
|
WriteToDoc(f, "=");
|
||||||
else
|
else
|
||||||
WriteRepeatedChar('=', max_com_col);
|
WriteRepeatedChar(f, '=', max_com_col);
|
||||||
|
|
||||||
WriteToDoc("\n");
|
WriteToDoc(f, "\n");
|
||||||
|
|
||||||
for ( it = l.begin(); it != l.end(); ++it )
|
for ( it = l.begin(); it != l.end(); ++it )
|
||||||
{
|
{
|
||||||
if ( it != l.begin() )
|
if ( it != l.begin() )
|
||||||
WriteToDoc("\n\n");
|
WriteToDoc(f, "\n\n");
|
||||||
(*it)->WriteReSTCompact(reST_file, max_id_col);
|
(*it)->WriteReSTCompact(f, max_id_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
// End table.
|
// End table.
|
||||||
WriteToDoc("\n");
|
WriteToDoc(f, "\n");
|
||||||
WriteRepeatedChar('=', max_id_col);
|
WriteRepeatedChar(f, '=', max_id_col);
|
||||||
WriteToDoc(" ");
|
WriteToDoc(f, " ");
|
||||||
|
|
||||||
if ( max_com_col == 0 )
|
if ( max_com_col == 0 )
|
||||||
WriteToDoc("=");
|
WriteToDoc(f, "=");
|
||||||
else
|
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,
|
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic,
|
||||||
const char* heading, char underline, bool isShort) const
|
const char* heading, char underline, bool isShort)
|
||||||
{
|
{
|
||||||
if ( l.empty() )
|
if ( l.empty() )
|
||||||
return;
|
return;
|
||||||
|
@ -364,7 +362,7 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
||||||
if ( it == l.end() )
|
if ( it == l.end() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WriteSectionHeading(heading, underline);
|
WriteSectionHeading(f, heading, underline);
|
||||||
|
|
||||||
BroDocObjList filtered_list;
|
BroDocObjList filtered_list;
|
||||||
|
|
||||||
|
@ -375,13 +373,13 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isShort )
|
if ( isShort )
|
||||||
WriteBroDocObjTable(filtered_list);
|
WriteBroDocObjTable(f, filtered_list);
|
||||||
else
|
else
|
||||||
WriteBroDocObjList(filtered_list);
|
WriteBroDocObjList(f, filtered_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic,
|
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic,
|
||||||
const char* heading, char underline, bool isShort) const
|
const char* heading, char underline, bool isShort)
|
||||||
{
|
{
|
||||||
BroDocObjMap::const_iterator it;
|
BroDocObjMap::const_iterator it;
|
||||||
BroDocObjList l;
|
BroDocObjList l;
|
||||||
|
@ -389,24 +387,24 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic,
|
||||||
for ( it = m.begin(); it != m.end(); ++it )
|
for ( it = m.begin(); it != m.end(); ++it )
|
||||||
l.push_back(it->second);
|
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,
|
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading,
|
||||||
char underline) const
|
char underline)
|
||||||
{
|
{
|
||||||
WriteSectionHeading(heading, underline);
|
WriteSectionHeading(f, heading, underline);
|
||||||
WriteBroDocObjList(l);
|
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 )
|
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,
|
void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading,
|
||||||
char underline) const
|
char underline)
|
||||||
{
|
{
|
||||||
BroDocObjMap::const_iterator it;
|
BroDocObjMap::const_iterator it;
|
||||||
BroDocObjList l;
|
BroDocObjList l;
|
||||||
|
@ -414,28 +412,28 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading,
|
||||||
for ( it = m.begin(); it != m.end(); ++it )
|
for ( it = m.begin(); it != m.end(); ++it )
|
||||||
l.push_back(it->second);
|
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_list argp;
|
||||||
va_start(argp, format);
|
va_start(argp, format);
|
||||||
vfprintf(reST_file, format, argp);
|
vfprintf(f, format, argp);
|
||||||
va_end(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);
|
WriteToDoc(f, "%s\n", heading);
|
||||||
WriteRepeatedChar(underline, strlen(heading));
|
WriteRepeatedChar(f, underline, strlen(heading));
|
||||||
WriteToDoc("\n");
|
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 )
|
for ( size_t i = 0; i < n; ++i )
|
||||||
WriteToDoc("%c", c);
|
WriteToDoc(f, "%c", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BroDoc::FreeBroDocObjPtrList(BroDocObjList& l)
|
void BroDoc::FreeBroDocObjPtrList(BroDocObjList& l)
|
||||||
|
@ -457,3 +455,143 @@ void BroDoc::AddFunction(BroDocObj* o)
|
||||||
else
|
else
|
||||||
functions[o->Name()]->Combine(o);
|
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);
|
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
|
* Schedules documentation of a script option. An option is
|
||||||
* defined as any variable in the script that is declared 'const'
|
* defined as any variable in the script that is declared 'const'
|
||||||
|
@ -242,7 +233,115 @@ public:
|
||||||
return reST_filename.c_str();
|
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;
|
FILE* reST_file;
|
||||||
std::string reST_filename;
|
std::string reST_filename;
|
||||||
std::string source_filename; // points to the basename of source file
|
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> imports;
|
||||||
std::list<std::string> port_analysis;
|
std::list<std::string> port_analysis;
|
||||||
|
|
||||||
typedef std::list<const BroDocObj*> BroDocObjList;
|
|
||||||
typedef std::map<std::string, BroDocObj*> BroDocObjMap;
|
|
||||||
|
|
||||||
BroDocObjList options;
|
BroDocObjList options;
|
||||||
BroDocObjList constants;
|
BroDocObjList constants;
|
||||||
BroDocObjList state_vars;
|
BroDocObjList state_vars;
|
||||||
|
@ -272,107 +368,6 @@ protected:
|
||||||
|
|
||||||
BroDocObjList all;
|
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
|
* Writes out the reST for either the script's public or private interface
|
||||||
* @param heading The title of the interfaces section heading
|
* @param heading The title of the interfaces section heading
|
||||||
|
@ -387,7 +382,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
void WriteInterface(const char* heading, char underline, char subunderline,
|
void WriteInterface(const char* heading, char underline, char subunderline,
|
||||||
bool isPublic, bool isShort) const;
|
bool isPublic, bool isShort) const;
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory allocated to BroDocObj's objects in a given list.
|
* 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
|
#endif
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
#include "BroDocObj.h"
|
#include "BroDocObj.h"
|
||||||
|
|
||||||
|
map<string, BroDocObj*> doc_ids = map<string, BroDocObj*>();
|
||||||
|
|
||||||
BroDocObj* BroDocObj::last = 0;
|
BroDocObj* BroDocObj::last = 0;
|
||||||
|
|
||||||
BroDocObj::BroDocObj(const ID* id, std::list<std::string>*& reST,
|
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;
|
is_fake_id = is_fake;
|
||||||
use_role = 0;
|
use_role = 0;
|
||||||
FormulateShortDesc();
|
FormulateShortDesc();
|
||||||
|
doc_ids[id->Name()] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
BroDocObj::~BroDocObj()
|
BroDocObj::~BroDocObj()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
|
||||||
|
@ -134,4 +135,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map identifiers to their broxygen documentation objects.
|
||||||
|
*/
|
||||||
|
extern map<string, BroDocObj*> doc_ids;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,13 @@ include_directories(BEFORE
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${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(version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c)
|
||||||
configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h)
|
configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h)
|
||||||
|
|
||||||
|
@ -100,52 +107,13 @@ target_link_libraries(bifcl)
|
||||||
########################################################################
|
########################################################################
|
||||||
## bifcl-dependent targets
|
## bifcl-dependent targets
|
||||||
|
|
||||||
# A macro to define a command that uses the BIF compiler to produce
|
include(BifCl)
|
||||||
# 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)
|
|
||||||
|
|
||||||
set(BIF_SRCS
|
set(BIF_SRCS
|
||||||
bro.bif
|
bro.bif
|
||||||
logging.bif
|
logging.bif
|
||||||
input.bif
|
input.bif
|
||||||
event.bif
|
event.bif
|
||||||
file_analysis.bif
|
|
||||||
const.bif
|
const.bif
|
||||||
types.bif
|
types.bif
|
||||||
strings.bif
|
strings.bif
|
||||||
|
@ -153,74 +121,54 @@ set(BIF_SRCS
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach (bift ${BIF_SRCS})
|
foreach (bift ${BIF_SRCS})
|
||||||
bif_target(${bift})
|
bif_target(${bift} "standard")
|
||||||
endforeach ()
|
endforeach ()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## BinPAC-dependent targets
|
## BinPAC-dependent targets
|
||||||
|
|
||||||
|
include(BinPAC)
|
||||||
|
|
||||||
set(BINPAC_AUXSRC
|
set(BINPAC_AUXSRC
|
||||||
binpac.pac
|
${CMAKE_SOURCE_DIR}/src/binpac.pac
|
||||||
bro.pac
|
${CMAKE_SOURCE_DIR}/src/bro.pac
|
||||||
binpac_bro.h
|
${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-lib.pac)
|
||||||
binpac_target(binpac_bro-lib.pac)
|
list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}")
|
||||||
|
|
||||||
binpac_target(ayiya.pac
|
binpac_target(binpac_bro-lib.pac)
|
||||||
ayiya-protocol.pac ayiya-analyzer.pac)
|
list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}")
|
||||||
binpac_target(bittorrent.pac
|
|
||||||
bittorrent-protocol.pac bittorrent-analyzer.pac)
|
########################################################################
|
||||||
binpac_target(dce_rpc.pac
|
## Including subdirectories.
|
||||||
dce_rpc-protocol.pac dce_rpc-analyzer.pac epmapper.pac)
|
########################################################################
|
||||||
binpac_target(dce_rpc_simple.pac
|
|
||||||
dce_rpc-protocol.pac epmapper.pac)
|
set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE)
|
||||||
binpac_target(dhcp.pac
|
set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE)
|
||||||
dhcp-protocol.pac dhcp-analyzer.pac)
|
|
||||||
binpac_target(dns.pac
|
add_subdirectory(analyzer)
|
||||||
dns-protocol.pac dns-analyzer.pac)
|
add_subdirectory(file_analysis)
|
||||||
binpac_target(dns_tcp.pac
|
|
||||||
dns.pac)
|
set(bro_SUBDIRS
|
||||||
binpac_target(gtpv1.pac
|
${bro_SUBDIR_LIBS}
|
||||||
gtpv1-protocol.pac gtpv1-analyzer.pac)
|
${bro_PLUGIN_LIBS}
|
||||||
binpac_target(http.pac
|
)
|
||||||
http-protocol.pac http-analyzer.pac)
|
|
||||||
binpac_target(ncp.pac)
|
if ( NOT bro_HAVE_OBJECT_LIBRARIES )
|
||||||
binpac_target(netflow.pac
|
foreach (_plugin ${bro_PLUGIN_LIBS})
|
||||||
netflow-protocol.pac netflow-analyzer.pac)
|
string(REGEX REPLACE "plugin-" "" _plugin "${_plugin}")
|
||||||
binpac_target(smb.pac
|
string(REGEX REPLACE "-" "_" _plugin "${_plugin}")
|
||||||
smb-protocol.pac smb-pipe.pac smb-mailslot.pac)
|
set(_decl "namespace plugin { namespace ${_plugin} { class Plugin; extern Plugin __plugin; } };")
|
||||||
binpac_target(socks.pac
|
set(_use "i += (size_t)(&(plugin::${_plugin}::__plugin));")
|
||||||
socks-protocol.pac socks-analyzer.pac)
|
set(__BRO_DECL_PLUGINS "${__BRO_DECL_PLUGINS}${_decl}\n")
|
||||||
binpac_target(ssl.pac
|
set(__BRO_USE_PLUGINS "${__BRO_USE_PLUGINS}${_use}\n")
|
||||||
ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac)
|
endforeach()
|
||||||
binpac_target(syslog.pac
|
|
||||||
syslog-protocol.pac syslog-analyzer.pac)
|
configure_file(plugins.cc.in ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
|
||||||
binpac_target(modbus.pac
|
set(PLUGIN_INIT ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
|
||||||
modbus-protocol.pac modbus-analyzer.pac)
|
endif()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## bro target
|
## bro target
|
||||||
|
@ -240,7 +188,7 @@ endif ()
|
||||||
macro(COLLECT_HEADERS _var)
|
macro(COLLECT_HEADERS _var)
|
||||||
foreach (src ${ARGN})
|
foreach (src ${ARGN})
|
||||||
get_filename_component(ext ${src} EXT)
|
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(base ${src} NAME_WE)
|
||||||
get_filename_component(dir ${src} PATH)
|
get_filename_component(dir ${src} PATH)
|
||||||
if (NOT "${dir}")
|
if (NOT "${dir}")
|
||||||
|
@ -275,10 +223,8 @@ set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS
|
||||||
set(bro_SRCS
|
set(bro_SRCS
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.c
|
${CMAKE_CURRENT_BINARY_DIR}/version.c
|
||||||
${BIF_SRCS}
|
${BIF_SRCS}
|
||||||
${ALL_BIF_OUTPUTS}
|
|
||||||
${BINPAC_AUXSRC}
|
${BINPAC_AUXSRC}
|
||||||
${ALL_BINPAC_INPUTS}
|
${BINPAC_OUTPUTS}
|
||||||
${ALL_BINPAC_OUTPUTS}
|
|
||||||
${TRANSFORMED_BISON_OUTPUTS}
|
${TRANSFORMED_BISON_OUTPUTS}
|
||||||
${FLEX_RuleScanner_OUTPUTS}
|
${FLEX_RuleScanner_OUTPUTS}
|
||||||
${FLEX_RuleScanner_INPUT}
|
${FLEX_RuleScanner_INPUT}
|
||||||
|
@ -290,19 +236,14 @@ set(bro_SRCS
|
||||||
${FLEX_Scanner_INPUT}
|
${FLEX_Scanner_INPUT}
|
||||||
${BISON_Parser_INPUT}
|
${BISON_Parser_INPUT}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
|
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
|
||||||
|
${PLUGIN_INIT}
|
||||||
main.cc
|
main.cc
|
||||||
net_util.cc
|
net_util.cc
|
||||||
util.cc
|
util.cc
|
||||||
module_util.cc
|
module_util.cc
|
||||||
Analyzer.cc
|
|
||||||
Anon.cc
|
Anon.cc
|
||||||
ARP.cc
|
|
||||||
Attr.cc
|
Attr.cc
|
||||||
AYIYA.cc
|
|
||||||
BackDoor.cc
|
|
||||||
Base64.cc
|
Base64.cc
|
||||||
BitTorrent.cc
|
|
||||||
BitTorrentTracker.cc
|
|
||||||
BPF_Program.cc
|
BPF_Program.cc
|
||||||
BroDoc.cc
|
BroDoc.cc
|
||||||
BroDocObj.cc
|
BroDocObj.cc
|
||||||
|
@ -312,14 +253,7 @@ set(bro_SRCS
|
||||||
ChunkedIO.cc
|
ChunkedIO.cc
|
||||||
CompHash.cc
|
CompHash.cc
|
||||||
Conn.cc
|
Conn.cc
|
||||||
ConnSizeAnalyzer.cc
|
|
||||||
ContentLine.cc
|
|
||||||
DCE_RPC.cc
|
|
||||||
DFA.cc
|
DFA.cc
|
||||||
DHCP-binpac.cc
|
|
||||||
DNS.cc
|
|
||||||
DNS-binpac.cc
|
|
||||||
DNS_Mgr.cc
|
|
||||||
DbgBreakpoint.cc
|
DbgBreakpoint.cc
|
||||||
DbgHelp.cc
|
DbgHelp.cc
|
||||||
DbgWatch.cc
|
DbgWatch.cc
|
||||||
|
@ -329,48 +263,29 @@ set(bro_SRCS
|
||||||
Desc.cc
|
Desc.cc
|
||||||
Dict.cc
|
Dict.cc
|
||||||
Discard.cc
|
Discard.cc
|
||||||
DPM.cc
|
DNS_Mgr.cc
|
||||||
EquivClass.cc
|
EquivClass.cc
|
||||||
Event.cc
|
Event.cc
|
||||||
EventHandler.cc
|
EventHandler.cc
|
||||||
EventLauncher.cc
|
EventLauncher.cc
|
||||||
EventRegistry.cc
|
EventRegistry.cc
|
||||||
Expr.cc
|
Expr.cc
|
||||||
FTP.cc
|
|
||||||
File.cc
|
File.cc
|
||||||
FileAnalyzer.cc
|
|
||||||
Finger.cc
|
|
||||||
FlowSrc.cc
|
FlowSrc.cc
|
||||||
Frag.cc
|
Frag.cc
|
||||||
Frame.cc
|
Frame.cc
|
||||||
Func.cc
|
Func.cc
|
||||||
Gnutella.cc
|
|
||||||
GTPv1.cc
|
|
||||||
HTTP.cc
|
|
||||||
HTTP-binpac.cc
|
|
||||||
Hash.cc
|
Hash.cc
|
||||||
ICMP.cc
|
|
||||||
ID.cc
|
ID.cc
|
||||||
Ident.cc
|
|
||||||
IntSet.cc
|
IntSet.cc
|
||||||
InterConn.cc
|
|
||||||
IOSource.cc
|
IOSource.cc
|
||||||
IP.cc
|
IP.cc
|
||||||
IPAddr.cc
|
IPAddr.cc
|
||||||
IRC.cc
|
|
||||||
List.cc
|
List.cc
|
||||||
Reporter.cc
|
Reporter.cc
|
||||||
Login.cc
|
|
||||||
MIME.cc
|
|
||||||
Modbus.cc
|
|
||||||
NCP.cc
|
|
||||||
NFA.cc
|
NFA.cc
|
||||||
NFS.cc
|
|
||||||
NTP.cc
|
|
||||||
NVT.cc
|
|
||||||
Net.cc
|
Net.cc
|
||||||
NetVar.cc
|
NetVar.cc
|
||||||
NetbiosSSN.cc
|
|
||||||
Obj.cc
|
Obj.cc
|
||||||
OpaqueVal.cc
|
OpaqueVal.cc
|
||||||
OSFinger.cc
|
OSFinger.cc
|
||||||
|
@ -378,31 +293,20 @@ set(bro_SRCS
|
||||||
PacketSort.cc
|
PacketSort.cc
|
||||||
PersistenceSerializer.cc
|
PersistenceSerializer.cc
|
||||||
PktSrc.cc
|
PktSrc.cc
|
||||||
PIA.cc
|
|
||||||
PolicyFile.cc
|
PolicyFile.cc
|
||||||
POP3.cc
|
|
||||||
Portmap.cc
|
|
||||||
PrefixTable.cc
|
PrefixTable.cc
|
||||||
PriorityQueue.cc
|
PriorityQueue.cc
|
||||||
Queue.cc
|
Queue.cc
|
||||||
RandTest.cc
|
RandTest.cc
|
||||||
RE.cc
|
RE.cc
|
||||||
RPC.cc
|
|
||||||
Reassem.cc
|
Reassem.cc
|
||||||
RemoteSerializer.cc
|
RemoteSerializer.cc
|
||||||
Rlogin.cc
|
|
||||||
RSH.cc
|
|
||||||
Rule.cc
|
Rule.cc
|
||||||
RuleAction.cc
|
RuleAction.cc
|
||||||
RuleCondition.cc
|
RuleCondition.cc
|
||||||
RuleMatcher.cc
|
RuleMatcher.cc
|
||||||
ScriptAnaly.cc
|
ScriptAnaly.cc
|
||||||
SmithWaterman.cc
|
SmithWaterman.cc
|
||||||
SMB.cc
|
|
||||||
SMTP.cc
|
|
||||||
SOCKS.cc
|
|
||||||
SSH.cc
|
|
||||||
SSL.cc
|
|
||||||
Scope.cc
|
Scope.cc
|
||||||
SerializationFormat.cc
|
SerializationFormat.cc
|
||||||
SerialObj.cc
|
SerialObj.cc
|
||||||
|
@ -410,24 +314,14 @@ set(bro_SRCS
|
||||||
Sessions.cc
|
Sessions.cc
|
||||||
StateAccess.cc
|
StateAccess.cc
|
||||||
Stats.cc
|
Stats.cc
|
||||||
SteppingStone.cc
|
|
||||||
Stmt.cc
|
Stmt.cc
|
||||||
Syslog-binpac.cc
|
|
||||||
TCP.cc
|
|
||||||
TCP_Endpoint.cc
|
|
||||||
TCP_Reassembler.cc
|
|
||||||
Telnet.cc
|
|
||||||
Teredo.cc
|
|
||||||
Timer.cc
|
Timer.cc
|
||||||
Traverse.cc
|
Traverse.cc
|
||||||
Trigger.cc
|
Trigger.cc
|
||||||
TunnelEncapsulation.cc
|
TunnelEncapsulation.cc
|
||||||
Type.cc
|
Type.cc
|
||||||
UDP.cc
|
|
||||||
Val.cc
|
Val.cc
|
||||||
Var.cc
|
Var.cc
|
||||||
XDR.cc
|
|
||||||
ZIP.cc
|
|
||||||
bsd-getopt-long.c
|
bsd-getopt-long.c
|
||||||
bro_inet_ntop.c
|
bro_inet_ntop.c
|
||||||
cq.c
|
cq.c
|
||||||
|
@ -461,29 +355,44 @@ set(bro_SRCS
|
||||||
input/readers/Binary.cc
|
input/readers/Binary.cc
|
||||||
input/readers/SQLite.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
|
3rdparty/sqlite3.c
|
||||||
|
|
||||||
|
plugin/Component.cc
|
||||||
|
plugin/Manager.cc
|
||||||
|
plugin/Plugin.cc
|
||||||
|
plugin/Macros.h
|
||||||
|
|
||||||
nb_dns.c
|
nb_dns.c
|
||||||
digest.h
|
digest.h
|
||||||
)
|
)
|
||||||
|
|
||||||
collect_headers(bro_HEADERS ${bro_SRCS})
|
collect_headers(bro_HEADERS ${bro_SRCS})
|
||||||
|
|
||||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
|
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})
|
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(TARGETS bro DESTINATION bin)
|
||||||
install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base)
|
|
||||||
|
|
||||||
set(BRO_EXE bro
|
set(BRO_EXE bro
|
||||||
CACHE STRING "Bro executable binary" FORCE)
|
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 "Sessions.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "PIA.h"
|
#include "analyzer/protocol/pia/PIA.h"
|
||||||
#include "binpac.h"
|
#include "binpac.h"
|
||||||
#include "TunnelEncapsulation.h"
|
#include "TunnelEncapsulation.h"
|
||||||
|
#include "analyzer/Analyzer.h"
|
||||||
|
|
||||||
void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
|
void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
|
||||||
int arg_do_expire)
|
int arg_do_expire)
|
||||||
|
@ -402,16 +403,21 @@ RecordVal* Connection::BuildConnVal()
|
||||||
return conn_val;
|
return conn_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Analyzer* Connection::FindAnalyzer(AnalyzerID id)
|
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id)
|
||||||
{
|
{
|
||||||
return root_analyzer ? root_analyzer->FindChild(id) : 0;
|
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;
|
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)
|
void Connection::AppendAddl(const char* str)
|
||||||
{
|
{
|
||||||
Unref(BuildConnVal());
|
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,
|
int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||||
Analyzer* analyzer)
|
analyzer::Analyzer* analyzer)
|
||||||
{
|
{
|
||||||
if ( ! software_version_found && ! software_parse_error )
|
if ( ! software_version_found && ! software_parse_error )
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -578,7 +584,7 @@ int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||||
}
|
}
|
||||||
|
|
||||||
int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
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.
|
// Skip leading white space.
|
||||||
while ( len && isspace(*full) )
|
while ( len && isspace(*full) )
|
||||||
|
@ -602,7 +608,7 @@ int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
||||||
return 1;
|
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 )
|
if ( ! f )
|
||||||
return;
|
return;
|
||||||
|
@ -615,7 +621,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
|
||||||
ConnectionEvent(f, analyzer, vl);
|
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 )
|
if ( ! f )
|
||||||
{
|
{
|
||||||
|
@ -634,7 +640,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
|
||||||
ConnectionEvent(f, analyzer, vl);
|
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 )
|
if ( ! f )
|
||||||
{
|
{
|
||||||
|
@ -929,7 +935,7 @@ error:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
|
void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia)
|
||||||
{
|
{
|
||||||
root_analyzer = analyzer;
|
root_analyzer = analyzer;
|
||||||
primary_PIA = pia;
|
primary_PIA = pia;
|
||||||
|
|
34
src/Conn.h
34
src/Conn.h
|
@ -11,19 +11,22 @@
|
||||||
#include "Serializer.h"
|
#include "Serializer.h"
|
||||||
#include "PersistenceSerializer.h"
|
#include "PersistenceSerializer.h"
|
||||||
#include "RuleMatcher.h"
|
#include "RuleMatcher.h"
|
||||||
#include "AnalyzerTags.h"
|
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
#include "TunnelEncapsulation.h"
|
#include "TunnelEncapsulation.h"
|
||||||
|
|
||||||
|
#include "analyzer/Tag.h"
|
||||||
|
#include "analyzer/Analyzer.h"
|
||||||
|
|
||||||
class Connection;
|
class Connection;
|
||||||
class ConnectionTimer;
|
class ConnectionTimer;
|
||||||
class NetSessions;
|
class NetSessions;
|
||||||
class LoginConn;
|
class LoginConn;
|
||||||
class RuleHdrTest;
|
class RuleHdrTest;
|
||||||
class Specific_RE_Matcher;
|
class Specific_RE_Matcher;
|
||||||
class TransportLayerAnalyzer;
|
|
||||||
class RuleEndpointState;
|
class RuleEndpointState;
|
||||||
|
|
||||||
|
namespace analyzer { class TransportLayerAnalyzer; }
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NUL_IN_LINE,
|
NUL_IN_LINE,
|
||||||
SINGULAR_CR,
|
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);
|
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Analyzer;
|
namespace analyzer { class Analyzer; }
|
||||||
|
|
||||||
class Connection : public BroObj {
|
class Connection : public BroObj {
|
||||||
public:
|
public:
|
||||||
|
@ -102,8 +105,9 @@ public:
|
||||||
|
|
||||||
void FlipRoles();
|
void FlipRoles();
|
||||||
|
|
||||||
Analyzer* FindAnalyzer(AnalyzerID id);
|
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
|
||||||
Analyzer* FindAnalyzer(AnalyzerTag::Tag tag); // find first in tree.
|
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; }
|
TransportProto ConnTransport() const { return proto; }
|
||||||
|
|
||||||
|
@ -161,15 +165,15 @@ public:
|
||||||
// Raises a software_version_found event based on the
|
// Raises a software_version_found event based on the
|
||||||
// given string (returns false if it's not parseable).
|
// given string (returns false if it's not parseable).
|
||||||
int VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
int VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||||
Analyzer* analyzer = 0);
|
analyzer::Analyzer* analyzer = 0);
|
||||||
|
|
||||||
// Raises a software_unparsed_version_found event.
|
// Raises a software_unparsed_version_found event.
|
||||||
int UnparsedVersionFoundEvent(const IPAddr& addr,
|
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* analyzer, const char* name = 0);
|
||||||
void Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
||||||
void ConnectionEvent(EventHandlerPtr f, Analyzer* analyzer,
|
void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer,
|
||||||
val_list* vl);
|
val_list* vl);
|
||||||
|
|
||||||
void Weird(const char* name, const char* addl = "");
|
void Weird(const char* name, const char* addl = "");
|
||||||
|
@ -241,9 +245,9 @@ public:
|
||||||
void DeleteTimer(double t);
|
void DeleteTimer(double t);
|
||||||
|
|
||||||
// Sets the root of the analyzer tree as well as the primary PIA.
|
// Sets the root of the analyzer tree as well as the primary PIA.
|
||||||
void SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia);
|
void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia);
|
||||||
TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
||||||
PIA* GetPrimaryPIA() { return primary_PIA; }
|
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||||
|
|
||||||
// Sets the transport protocol in use.
|
// Sets the transport protocol in use.
|
||||||
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
|
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
|
||||||
|
@ -314,8 +318,8 @@ protected:
|
||||||
string history;
|
string history;
|
||||||
uint32 hist_seen;
|
uint32 hist_seen;
|
||||||
|
|
||||||
TransportLayerAnalyzer* root_analyzer;
|
analyzer::TransportLayerAnalyzer* root_analyzer;
|
||||||
PIA* primary_PIA;
|
analyzer::pia::PIA* primary_PIA;
|
||||||
|
|
||||||
uint64 uid; // Globally unique connection ID.
|
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_STRING, // String code
|
||||||
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
||||||
DBG_MAINLOOP, // Main IOSource loop
|
DBG_MAINLOOP, // Main IOSource loop
|
||||||
DBG_DPD, // Dynamic application detection framework
|
DBG_ANALYZER, // Analyzer framework
|
||||||
DBG_TM, // Time-machine packet input via Brocolli
|
DBG_TM, // Time-machine packet input via Brocolli
|
||||||
DBG_LOGGING, // Logging streams
|
DBG_LOGGING, // Logging streams
|
||||||
DBG_INPUT, // Input streams
|
DBG_INPUT, // Input streams
|
||||||
|
|
|
@ -13,7 +13,7 @@ int num_events_queued = 0;
|
||||||
int num_events_dispatched = 0;
|
int num_events_dispatched = 0;
|
||||||
|
|
||||||
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
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)
|
BroObj* arg_obj)
|
||||||
{
|
{
|
||||||
handler = arg_handler;
|
handler = arg_handler;
|
||||||
|
|
16
src/Event.h
16
src/Event.h
|
@ -5,14 +5,16 @@
|
||||||
|
|
||||||
#include "EventRegistry.h"
|
#include "EventRegistry.h"
|
||||||
#include "Serializer.h"
|
#include "Serializer.h"
|
||||||
#include "AnalyzerTags.h"
|
|
||||||
|
#include "analyzer/Tag.h"
|
||||||
|
#include "analyzer/Analyzer.h"
|
||||||
|
|
||||||
class EventMgr;
|
class EventMgr;
|
||||||
|
|
||||||
class Event : public BroObj {
|
class Event : public BroObj {
|
||||||
public:
|
public:
|
||||||
Event(EventHandlerPtr handler, val_list* args,
|
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);
|
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||||
~Event();
|
~Event();
|
||||||
|
|
||||||
|
@ -20,7 +22,7 @@ public:
|
||||||
Event* NextEvent() const { return next_event; }
|
Event* NextEvent() const { return next_event; }
|
||||||
|
|
||||||
SourceID Source() const { return src; }
|
SourceID Source() const { return src; }
|
||||||
AnalyzerID Analyzer() const { return aid; }
|
analyzer::ID Analyzer() const { return aid; }
|
||||||
TimerMgr* Mgr() const { return mgr; }
|
TimerMgr* Mgr() const { return mgr; }
|
||||||
|
|
||||||
void Describe(ODesc* d) const;
|
void Describe(ODesc* d) const;
|
||||||
|
@ -62,7 +64,7 @@ protected:
|
||||||
EventHandlerPtr handler;
|
EventHandlerPtr handler;
|
||||||
val_list* args;
|
val_list* args;
|
||||||
SourceID src;
|
SourceID src;
|
||||||
AnalyzerID aid;
|
analyzer::ID aid;
|
||||||
TimerMgr* mgr;
|
TimerMgr* mgr;
|
||||||
BroObj* obj;
|
BroObj* obj;
|
||||||
Event* next_event;
|
Event* next_event;
|
||||||
|
@ -77,7 +79,7 @@ public:
|
||||||
~EventMgr();
|
~EventMgr();
|
||||||
|
|
||||||
void QueueEvent(EventHandlerPtr h, val_list* vl,
|
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)
|
TimerMgr* mgr = 0, BroObj* obj = 0)
|
||||||
{
|
{
|
||||||
if ( h )
|
if ( h )
|
||||||
|
@ -105,7 +107,7 @@ public:
|
||||||
|
|
||||||
// Returns the ID of the analyzer which raised the last event, or 0 if
|
// Returns the ID of the analyzer which raised the last event, or 0 if
|
||||||
// non-analyzer event.
|
// 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.
|
// Returns the timer mgr associated with the last raised event.
|
||||||
TimerMgr* CurrentTimerMgr() const { return current_mgr; }
|
TimerMgr* CurrentTimerMgr() const { return current_mgr; }
|
||||||
|
@ -124,7 +126,7 @@ protected:
|
||||||
Event* head;
|
Event* head;
|
||||||
Event* tail;
|
Event* tail;
|
||||||
SourceID current_src;
|
SourceID current_src;
|
||||||
AnalyzerID current_aid;
|
analyzer::ID current_aid;
|
||||||
TimerMgr* current_mgr;
|
TimerMgr* current_mgr;
|
||||||
RecordVal* src_val;
|
RecordVal* src_val;
|
||||||
bool draining;
|
bool draining;
|
||||||
|
|
|
@ -10,7 +10,6 @@ EventHandler::EventHandler(const char* arg_name)
|
||||||
used = false;
|
used = false;
|
||||||
local = 0;
|
local = 0;
|
||||||
type = 0;
|
type = 0;
|
||||||
group = 0;
|
|
||||||
error_handler = false;
|
error_handler = false;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +18,6 @@ EventHandler::~EventHandler()
|
||||||
{
|
{
|
||||||
Unref(local);
|
Unref(local);
|
||||||
delete [] name;
|
delete [] name;
|
||||||
delete [] group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler::operator bool() const
|
EventHandler::operator bool() const
|
||||||
|
|
|
@ -41,10 +41,6 @@ public:
|
||||||
void SetErrorHandler() { error_handler = true; }
|
void SetErrorHandler() { error_handler = true; }
|
||||||
bool ErrorHandler() { return error_handler; }
|
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; }
|
void SetEnable(bool arg_enable) { enabled = arg_enable; }
|
||||||
|
|
||||||
// We don't serialize the handler(s) itself here, but
|
// We don't serialize the handler(s) itself here, but
|
||||||
|
@ -54,7 +50,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* group;
|
|
||||||
Func* local;
|
Func* local;
|
||||||
FuncType* type;
|
FuncType* type;
|
||||||
bool used; // this handler is indeed used somewhere
|
bool used; // this handler is indeed used somewhere
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Analyzer.h"
|
#include "analyzer/Analyzer.h"
|
||||||
#include "EventLauncher.h"
|
#include "EventLauncher.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "NetVar.h"
|
||||||
|
#include "Conn.h"
|
||||||
|
|
||||||
#include "event.bif.func_def"
|
#include "event.bif.func_def"
|
||||||
|
|
|
@ -80,20 +80,13 @@ void EventRegistry::PrintDebug()
|
||||||
while ( (v = handlers.NextEntry(k, c)) )
|
while ( (v = handlers.NextEntry(k, c)) )
|
||||||
{
|
{
|
||||||
delete k;
|
delete k;
|
||||||
fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(),
|
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
|
||||||
v->LocalHandler()? "local" : "no");
|
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)
|
void EventRegistry::SetErrorHandler(const char* name)
|
||||||
{
|
{
|
||||||
EventHandler* eh = Lookup(name);
|
EventHandler* eh = Lookup(name);
|
||||||
|
@ -103,18 +96,3 @@ void EventRegistry::SetErrorHandler(const char* name)
|
||||||
eh->SetErrorHandler();
|
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;
|
typedef PList(constchar) string_list;
|
||||||
string_list* Match(RE_Matcher* pattern);
|
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
|
// Marks a handler as handling errors. Error handler will not be called
|
||||||
// recursively to avoid infinite loops in case they trigger an error
|
// recursively to avoid infinite loops in case they trigger an error
|
||||||
// themselves.
|
// themselves.
|
||||||
void SetErrorHandler(const char* name);
|
void SetErrorHandler(const char* name);
|
||||||
|
|
||||||
// Enable/disable all members of the group.
|
|
||||||
void EnableGroup(const char* group, bool enable);
|
|
||||||
|
|
||||||
string_list* UnusedHandlers();
|
string_list* UnusedHandlers();
|
||||||
string_list* UsedHandlers();
|
string_list* UsedHandlers();
|
||||||
void PrintDebug();
|
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 "FlowSrc.h"
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
#include "netflow_pac.h"
|
#include "analyzer/protocol/netflow/netflow_pac.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
FlowSrc::FlowSrc()
|
FlowSrc::FlowSrc()
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Var.h"
|
#include "Var.h"
|
||||||
#include "Login.h"
|
#include "analyzer/protocol/login/Login.h"
|
||||||
#include "Sessions.h"
|
#include "Sessions.h"
|
||||||
#include "RE.h"
|
#include "RE.h"
|
||||||
#include "Serializer.h"
|
#include "Serializer.h"
|
||||||
|
@ -553,18 +553,15 @@ void builtin_error(const char* msg, BroObj* arg)
|
||||||
#include "input.bif.func_h"
|
#include "input.bif.func_h"
|
||||||
#include "reporter.bif.func_h"
|
#include "reporter.bif.func_h"
|
||||||
#include "strings.bif.func_h"
|
#include "strings.bif.func_h"
|
||||||
#include "file_analysis.bif.func_h"
|
|
||||||
|
|
||||||
#include "bro.bif.func_def"
|
#include "bro.bif.func_def"
|
||||||
#include "logging.bif.func_def"
|
#include "logging.bif.func_def"
|
||||||
#include "input.bif.func_def"
|
#include "input.bif.func_def"
|
||||||
#include "reporter.bif.func_def"
|
#include "reporter.bif.func_def"
|
||||||
#include "strings.bif.func_def"
|
#include "strings.bif.func_def"
|
||||||
#include "file_analysis.bif.func_def"
|
|
||||||
|
|
||||||
void init_builtin_funcs()
|
void init_builtin_funcs()
|
||||||
{
|
{
|
||||||
ftp_port = internal_type("ftp_port")->AsRecordType();
|
|
||||||
bro_resources = internal_type("bro_resources")->AsRecordType();
|
bro_resources = internal_type("bro_resources")->AsRecordType();
|
||||||
net_stats = internal_type("NetStats")->AsRecordType();
|
net_stats = internal_type("NetStats")->AsRecordType();
|
||||||
matcher_stats = internal_type("matcher_stats")->AsRecordType();
|
matcher_stats = internal_type("matcher_stats")->AsRecordType();
|
||||||
|
@ -576,7 +573,6 @@ void init_builtin_funcs()
|
||||||
#include "input.bif.func_init"
|
#include "input.bif.func_init"
|
||||||
#include "reporter.bif.func_init"
|
#include "reporter.bif.func_init"
|
||||||
#include "strings.bif.func_init"
|
#include "strings.bif.func_init"
|
||||||
#include "file_analysis.bif.func_init"
|
|
||||||
|
|
||||||
did_builtin_init = true;
|
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];
|
T byte_lookup[N][H3_BYTE_RANGE];
|
||||||
public:
|
public:
|
||||||
H3();
|
H3();
|
||||||
~H3() { free(byte_lookup); }
|
|
||||||
T operator()(const void* data, size_t size, size_t offset = 0) const
|
T operator()(const void* data, size_t size, size_t offset = 0) const
|
||||||
{
|
{
|
||||||
const unsigned char *p = static_cast<const unsigned char*>(data);
|
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 )
|
if ( Type()->Tag() == TYPE_FUNC )
|
||||||
{
|
{
|
||||||
Attr* attr = attrs->FindAttr(ATTR_GROUP);
|
Attr* attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if ( attr )
|
if ( attr )
|
||||||
event_registry->SetErrorHandler(Name());
|
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 IsGlobal() const { return scope != SCOPE_FUNCTION; }
|
||||||
|
|
||||||
bool IsExport() const { return is_export; }
|
bool IsExport() const { return is_export; }
|
||||||
|
void SetExport() { is_export = true; }
|
||||||
|
|
||||||
string ModuleName() const;
|
string ModuleName() const;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
#include "Conn.h"
|
#include "Conn.h"
|
||||||
#include "DPM.h"
|
|
||||||
#include "bro_inet_ntop.h"
|
#include "bro_inet_ntop.h"
|
||||||
|
|
||||||
|
#include "analyzer/Manager.h"
|
||||||
|
|
||||||
const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
|
const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0xff, 0xff };
|
0, 0, 0xff, 0xff };
|
||||||
|
@ -44,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id)
|
||||||
return new HashKey(&key, sizeof(key));
|
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)
|
void IPAddr::Mask(int top_bits_to_keep)
|
||||||
{
|
{
|
||||||
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "threading/SerialTypes.h"
|
#include "threading/SerialTypes.h"
|
||||||
|
|
||||||
struct ConnID;
|
struct ConnID;
|
||||||
class ExpectedConn;
|
namespace analyzer { class ExpectedConn; }
|
||||||
|
|
||||||
typedef in_addr in4_addr;
|
typedef in_addr in4_addr;
|
||||||
|
|
||||||
|
@ -363,7 +363,6 @@ public:
|
||||||
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
||||||
|
|
||||||
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||||
friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
|
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
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);
|
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
|
* Class storing both IPv4 and IPv6 prefixes
|
||||||
* (i.e., \c 192.168.1.1/16 and \c FD00::/8.
|
* (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;
|
RecordType* http_message_stat;
|
||||||
int truncate_http_URI;
|
int truncate_http_URI;
|
||||||
|
|
||||||
int pm_request;
|
|
||||||
RecordType* pm_mapping;
|
RecordType* pm_mapping;
|
||||||
TableType* pm_mappings;
|
TableType* pm_mappings;
|
||||||
RecordType* pm_port_request;
|
RecordType* pm_port_request;
|
||||||
|
@ -209,7 +208,6 @@ TableType* irc_join_list;
|
||||||
RecordType* irc_join_info;
|
RecordType* irc_join_info;
|
||||||
TableVal* irc_servers;
|
TableVal* irc_servers;
|
||||||
|
|
||||||
TableVal* dpd_config;
|
|
||||||
int dpd_reassemble_first_packets;
|
int dpd_reassemble_first_packets;
|
||||||
int dpd_buffer_size;
|
int dpd_buffer_size;
|
||||||
int dpd_match_only_beginning;
|
int dpd_match_only_beginning;
|
||||||
|
@ -251,7 +249,6 @@ OpaqueType* entropy_type;
|
||||||
#include "logging.bif.netvar_def"
|
#include "logging.bif.netvar_def"
|
||||||
#include "input.bif.netvar_def"
|
#include "input.bif.netvar_def"
|
||||||
#include "reporter.bif.netvar_def"
|
#include "reporter.bif.netvar_def"
|
||||||
#include "file_analysis.bif.netvar_def"
|
|
||||||
|
|
||||||
void init_event_handlers()
|
void init_event_handlers()
|
||||||
{
|
{
|
||||||
|
@ -319,7 +316,6 @@ void init_net_var()
|
||||||
#include "logging.bif.netvar_init"
|
#include "logging.bif.netvar_init"
|
||||||
#include "input.bif.netvar_init"
|
#include "input.bif.netvar_init"
|
||||||
#include "reporter.bif.netvar_init"
|
#include "reporter.bif.netvar_init"
|
||||||
#include "file_analysis.bif.netvar_init"
|
|
||||||
|
|
||||||
conn_id = internal_type("conn_id")->AsRecordType();
|
conn_id = internal_type("conn_id")->AsRecordType();
|
||||||
endpoint = internal_type("endpoint")->AsRecordType();
|
endpoint = internal_type("endpoint")->AsRecordType();
|
||||||
|
@ -423,14 +419,6 @@ void init_net_var()
|
||||||
http_message_stat = internal_type("http_message_stat")->AsRecordType();
|
http_message_stat = internal_type("http_message_stat")->AsRecordType();
|
||||||
truncate_http_URI = opt_internal_int("truncate_http_URI");
|
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_mapping = internal_type("pm_mapping")->AsRecordType();
|
||||||
pm_mappings = internal_type("pm_mappings")->AsTableType();
|
pm_mappings = internal_type("pm_mappings")->AsTableType();
|
||||||
pm_port_request = internal_type("pm_port_request")->AsRecordType();
|
pm_port_request = internal_type("pm_port_request")->AsRecordType();
|
||||||
|
@ -526,7 +514,6 @@ void init_net_var()
|
||||||
opt_internal_double("remote_trace_sync_interval");
|
opt_internal_double("remote_trace_sync_interval");
|
||||||
remote_trace_sync_peers = opt_internal_int("remote_trace_sync_peers");
|
remote_trace_sync_peers = opt_internal_int("remote_trace_sync_peers");
|
||||||
|
|
||||||
dpd_config = internal_val("dpd_config")->AsTableVal();
|
|
||||||
dpd_reassemble_first_packets =
|
dpd_reassemble_first_packets =
|
||||||
opt_internal_int("dpd_reassemble_first_packets");
|
opt_internal_int("dpd_reassemble_first_packets");
|
||||||
dpd_buffer_size = opt_internal_int("dpd_buffer_size");
|
dpd_buffer_size = opt_internal_int("dpd_buffer_size");
|
||||||
|
|
|
@ -97,7 +97,6 @@ extern RecordType* http_stats_rec;
|
||||||
extern RecordType* http_message_stat;
|
extern RecordType* http_message_stat;
|
||||||
extern int truncate_http_URI;
|
extern int truncate_http_URI;
|
||||||
|
|
||||||
extern int pm_request;
|
|
||||||
extern RecordType* pm_mapping;
|
extern RecordType* pm_mapping;
|
||||||
extern TableType* pm_mappings;
|
extern TableType* pm_mappings;
|
||||||
extern RecordType* pm_port_request;
|
extern RecordType* pm_port_request;
|
||||||
|
@ -213,7 +212,6 @@ extern TableType* irc_join_list;
|
||||||
extern RecordType* irc_join_info;
|
extern RecordType* irc_join_info;
|
||||||
extern TableVal* irc_servers;
|
extern TableVal* irc_servers;
|
||||||
|
|
||||||
extern TableVal* dpd_config;
|
|
||||||
extern int dpd_reassemble_first_packets;
|
extern int dpd_reassemble_first_packets;
|
||||||
extern int dpd_buffer_size;
|
extern int dpd_buffer_size;
|
||||||
extern int dpd_match_only_beginning;
|
extern int dpd_match_only_beginning;
|
||||||
|
@ -262,6 +260,5 @@ extern void init_net_var();
|
||||||
#include "logging.bif.netvar_h"
|
#include "logging.bif.netvar_h"
|
||||||
#include "input.bif.netvar_h"
|
#include "input.bif.netvar_h"
|
||||||
#include "reporter.bif.netvar_h"
|
#include "reporter.bif.netvar_h"
|
||||||
#include "file_analysis.bif.netvar_h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,8 +8,9 @@ using std::string;
|
||||||
#include "Conn.h"
|
#include "Conn.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "NetVar.h"
|
#include "NetVar.h"
|
||||||
#include "DPM.h"
|
#include "analyzer/protocol/pia/PIA.h"
|
||||||
#include "PIA.h"
|
|
||||||
|
#include "analyzer/Manager.h"
|
||||||
|
|
||||||
void RuleActionEvent::DoAction(const Rule* parent, RuleEndpointState* state,
|
void RuleActionEvent::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
|
@ -34,42 +35,45 @@ void RuleActionEvent::PrintDebug()
|
||||||
fprintf(stderr, " RuleActionEvent: |%s|\n", msg);
|
fprintf(stderr, " RuleActionEvent: |%s|\n", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
RuleActionDPM::RuleActionDPM(const char* arg_analyzer)
|
RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
|
||||||
{
|
{
|
||||||
string str(arg_analyzer);
|
string str(arg_analyzer);
|
||||||
string::size_type pos = str.find(':');
|
string::size_type pos = str.find(':');
|
||||||
string arg = str.substr(0, pos);
|
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 )
|
if ( pos != string::npos )
|
||||||
{
|
{
|
||||||
arg = str.substr(pos + 1);
|
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
|
else
|
||||||
child_analyzer = AnalyzerTag::Error;
|
child_analyzer = analyzer::Tag();
|
||||||
|
|
||||||
if ( analyzer != AnalyzerTag::Error )
|
|
||||||
dpm->ActivateSigs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleActionDPM::PrintDebug()
|
void RuleActionAnalyzer::PrintDebug()
|
||||||
{
|
{
|
||||||
if ( child_analyzer == AnalyzerTag::Error )
|
if ( ! child_analyzer )
|
||||||
fprintf(stderr, "|%s|\n", Analyzer::GetTagName(analyzer));
|
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer));
|
||||||
else
|
else
|
||||||
fprintf(stderr, "|%s:%s|\n",
|
fprintf(stderr, "|%s:%s|\n",
|
||||||
Analyzer::GetTagName(analyzer),
|
analyzer_mgr->GetAnalyzerName(analyzer),
|
||||||
Analyzer::GetTagName(child_analyzer));
|
analyzer_mgr->GetAnalyzerName(child_analyzer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
if ( ! ChildAnalyzer() )
|
||||||
{
|
{
|
||||||
if ( ! Analyzer::IsAvailable(Analyzer()) )
|
if ( ! analyzer_mgr->IsEnabled(Analyzer()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( state->PIA() )
|
if ( state->PIA() )
|
||||||
|
@ -77,7 +81,7 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ! Analyzer::IsAvailable(ChildAnalyzer()) )
|
if ( ! analyzer_mgr->IsEnabled(ChildAnalyzer()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This is ugly and works only if there exists only one
|
// 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()
|
void RuleActionEnable::PrintDebug()
|
||||||
{
|
{
|
||||||
fprintf(stderr, " RuleActionEnable: ");
|
fprintf(stderr, " RuleActionEnable: ");
|
||||||
RuleActionDPM::PrintDebug();
|
RuleActionAnalyzer::PrintDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
if ( ! ChildAnalyzer() )
|
||||||
{
|
{
|
||||||
if ( state->PIA() )
|
if ( state->PIA() )
|
||||||
state->PIA()->DeactivateAnalyzer(Analyzer());
|
state->PIA()->DeactivateAnalyzer(Analyzer());
|
||||||
|
@ -109,5 +113,5 @@ void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
void RuleActionDisable::PrintDebug()
|
void RuleActionDisable::PrintDebug()
|
||||||
{
|
{
|
||||||
fprintf(stderr, " RuleActionDisable: ");
|
fprintf(stderr, " RuleActionDisable: ");
|
||||||
RuleActionDPM::PrintDebug();
|
RuleActionAnalyzer::PrintDebug();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#ifndef ruleaction_h
|
#ifndef ruleaction_h
|
||||||
#define ruleaction_h
|
#define ruleaction_h
|
||||||
|
|
||||||
#include "AnalyzerTags.h"
|
|
||||||
#include "BroString.h"
|
#include "BroString.h"
|
||||||
#include "List.h"
|
#include "List.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "analyzer/Tag.h"
|
||||||
|
|
||||||
class Rule;
|
class Rule;
|
||||||
class RuleEndpointState;
|
class RuleEndpointState;
|
||||||
|
|
||||||
|
@ -35,29 +36,27 @@ private:
|
||||||
const char* msg;
|
const char* msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for DPM enable/disable actions.
|
// Base class for enable/disable actions.
|
||||||
class RuleActionDPM : public RuleAction {
|
class RuleActionAnalyzer : public RuleAction {
|
||||||
public:
|
public:
|
||||||
RuleActionDPM(const char* analyzer);
|
RuleActionAnalyzer(const char* analyzer);
|
||||||
|
|
||||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len) = 0;
|
const u_char* data, int len) = 0;
|
||||||
|
|
||||||
virtual void PrintDebug();
|
virtual void PrintDebug();
|
||||||
|
|
||||||
AnalyzerTag::Tag Analyzer() const { return analyzer; }
|
analyzer::Tag Analyzer() const { return analyzer; }
|
||||||
AnalyzerTag::Tag ChildAnalyzer() const { return child_analyzer; }
|
analyzer::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// FIXME: This is in fact an AnalyzerID but we can't include "Analyzer.h"
|
analyzer::Tag analyzer;
|
||||||
// at this point due to circular dependenides. Fix that!
|
analyzer::Tag child_analyzer;
|
||||||
AnalyzerTag::Tag analyzer;
|
|
||||||
AnalyzerTag::Tag child_analyzer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RuleActionEnable : public RuleActionDPM {
|
class RuleActionEnable : public RuleActionAnalyzer {
|
||||||
public:
|
public:
|
||||||
RuleActionEnable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||||
|
|
||||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len);
|
const u_char* data, int len);
|
||||||
|
@ -65,9 +64,9 @@ public:
|
||||||
virtual void PrintDebug();
|
virtual void PrintDebug();
|
||||||
};
|
};
|
||||||
|
|
||||||
class RuleActionDisable : public RuleActionDPM {
|
class RuleActionDisable : public RuleActionAnalyzer {
|
||||||
public:
|
public:
|
||||||
RuleActionDisable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||||
|
|
||||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len);
|
const u_char* data, int len);
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "RuleCondition.h"
|
#include "RuleCondition.h"
|
||||||
#include "TCP.h"
|
#include "analyzer/protocol/tcp/TCP.h"
|
||||||
#include "Scope.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
|
// We more or less follow Snort here: an established session
|
||||||
// is one for which the initial handshake has succeded (but we
|
// is one for which the initial handshake has succeded (but we
|
||||||
// add partial connections). The connection tear-down is part
|
// add partial connections). The connection tear-down is part
|
||||||
// of the connection.
|
// of the connection.
|
||||||
return e->state != TCP_ENDPOINT_INACTIVE &&
|
return e->state != analyzer::tcp::TCP_ENDPOINT_INACTIVE &&
|
||||||
e->state != TCP_ENDPOINT_SYN_SENT &&
|
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_SENT &&
|
||||||
e->state != TCP_ENDPOINT_SYN_ACK_SENT;
|
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_ACK_SENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
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;
|
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 )
|
if ( tcpstates & STATE_STATELESS )
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "Analyzer.h"
|
#include "analyzer/Analyzer.h"
|
||||||
#include "RuleMatcher.h"
|
#include "RuleMatcher.h"
|
||||||
#include "DFA.h"
|
#include "DFA.h"
|
||||||
#include "NetVar.h"
|
#include "NetVar.h"
|
||||||
|
@ -159,9 +159,9 @@ void RuleHdrTest::PrintDebug()
|
||||||
fprintf(stderr, "\n");
|
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,
|
RuleEndpointState* arg_opposite,
|
||||||
::PIA* arg_PIA)
|
analyzer::pia::PIA* arg_PIA)
|
||||||
{
|
{
|
||||||
payload_size = -1;
|
payload_size = -1;
|
||||||
analyzer = arg_analyzer;
|
analyzer = arg_analyzer;
|
||||||
|
@ -562,10 +562,10 @@ static inline bool compare(const vector<IPPrefix>& prefixes, const IPAddr& a,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RuleEndpointState* RuleMatcher::InitEndpoint(Analyzer* analyzer,
|
RuleEndpointState* RuleMatcher::InitEndpoint(analyzer::Analyzer* analyzer,
|
||||||
const IP_Hdr* ip, int caplen,
|
const IP_Hdr* ip, int caplen,
|
||||||
RuleEndpointState* opposite,
|
RuleEndpointState* opposite,
|
||||||
bool from_orig, PIA* pia)
|
bool from_orig, analyzer::pia::PIA* pia)
|
||||||
{
|
{
|
||||||
RuleEndpointState* state =
|
RuleEndpointState* state =
|
||||||
new RuleEndpointState(analyzer, from_orig, opposite, pia);
|
new RuleEndpointState(analyzer, from_orig, opposite, pia);
|
||||||
|
@ -1300,8 +1300,8 @@ uint32 id_to_uint(const char* id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleMatcherState::InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
void RuleMatcherState::InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||||
int caplen, bool from_orig, PIA* pia)
|
int caplen, bool from_orig, analyzer::pia::PIA* pia)
|
||||||
{
|
{
|
||||||
if ( ! rule_matcher )
|
if ( ! rule_matcher )
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -35,8 +35,10 @@ extern const char* current_rule_file;
|
||||||
class RuleMatcher;
|
class RuleMatcher;
|
||||||
extern RuleMatcher* rule_matcher;
|
extern RuleMatcher* rule_matcher;
|
||||||
|
|
||||||
class Analyzer;
|
namespace analyzer {
|
||||||
class PIA;
|
namespace pia { class PIA; }
|
||||||
|
class Analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
// RuleHdrTest and associated things:
|
// RuleHdrTest and associated things:
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ class RuleEndpointState {
|
||||||
public:
|
public:
|
||||||
~RuleEndpointState();
|
~RuleEndpointState();
|
||||||
|
|
||||||
Analyzer* GetAnalyzer() const { return analyzer; }
|
analyzer::Analyzer* GetAnalyzer() const { return analyzer; }
|
||||||
bool IsOrig() { return is_orig; }
|
bool IsOrig() { return is_orig; }
|
||||||
|
|
||||||
// For flipping roles.
|
// For flipping roles.
|
||||||
|
@ -152,15 +154,15 @@ public:
|
||||||
// Returns -1 if no chunk has been fed yet at all.
|
// Returns -1 if no chunk has been fed yet at all.
|
||||||
int PayloadSize() { return payload_size; }
|
int PayloadSize() { return payload_size; }
|
||||||
|
|
||||||
::PIA* PIA() const { return pia; }
|
analyzer::pia::PIA* PIA() const { return pia; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class RuleMatcher;
|
friend class RuleMatcher;
|
||||||
|
|
||||||
// Constructor is private; use RuleMatcher::InitEndpoint()
|
// Constructor is private; use RuleMatcher::InitEndpoint()
|
||||||
// for creating an instance.
|
// for creating an instance.
|
||||||
RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig,
|
RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
|
||||||
RuleEndpointState* arg_opposite, ::PIA* arg_PIA);
|
RuleEndpointState* arg_opposite, analyzer::pia::PIA* arg_PIA);
|
||||||
|
|
||||||
struct Matcher {
|
struct Matcher {
|
||||||
RE_Match_State* state;
|
RE_Match_State* state;
|
||||||
|
@ -171,9 +173,9 @@ private:
|
||||||
typedef PList(Matcher) matcher_list;
|
typedef PList(Matcher) matcher_list;
|
||||||
|
|
||||||
bool is_orig;
|
bool is_orig;
|
||||||
Analyzer* analyzer;
|
analyzer::Analyzer* analyzer;
|
||||||
RuleEndpointState* opposite;
|
RuleEndpointState* opposite;
|
||||||
::PIA* pia;
|
analyzer::pia::PIA* pia;
|
||||||
|
|
||||||
matcher_list matchers;
|
matcher_list matchers;
|
||||||
rule_hdr_test_list hdr_tests;
|
rule_hdr_test_list hdr_tests;
|
||||||
|
@ -207,8 +209,8 @@ public:
|
||||||
// the given packet (which should be the first packet encountered for
|
// the given packet (which should be the first packet encountered for
|
||||||
// this endpoint). If the matching is triggered by an PIA, a pointer to
|
// this endpoint). If the matching is triggered by an PIA, a pointer to
|
||||||
// it needs to be given.
|
// it needs to be given.
|
||||||
RuleEndpointState* InitEndpoint(Analyzer* analyzer, const IP_Hdr* ip,
|
RuleEndpointState* InitEndpoint(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||||
int caplen, RuleEndpointState* opposite, bool is_orig, PIA* pia);
|
int caplen, RuleEndpointState* opposite, bool is_orig, analyzer::pia::PIA* pia);
|
||||||
|
|
||||||
// Finish matching for this stream.
|
// Finish matching for this stream.
|
||||||
void FinishEndpoint(RuleEndpointState* state);
|
void FinishEndpoint(RuleEndpointState* state);
|
||||||
|
@ -310,8 +312,8 @@ public:
|
||||||
{ delete orig_match_state; delete resp_match_state; }
|
{ delete orig_match_state; delete resp_match_state; }
|
||||||
|
|
||||||
// ip may be nil.
|
// ip may be nil.
|
||||||
void InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
void InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||||
int caplen, bool from_orig, PIA* pia = 0);
|
int caplen, bool from_orig, analyzer::pia::PIA* pia = 0);
|
||||||
|
|
||||||
// bol/eol should be set to false for type Rule::PAYLOAD; they're
|
// bol/eol should be set to false for type Rule::PAYLOAD; they're
|
||||||
// deduced automatically.
|
// 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 "Reporter.h"
|
||||||
#include "OSFinger.h"
|
#include "OSFinger.h"
|
||||||
|
|
||||||
#include "ICMP.h"
|
#include "analyzer/protocol/icmp/ICMP.h"
|
||||||
#include "UDP.h"
|
#include "analyzer/protocol/udp/UDP.h"
|
||||||
|
|
||||||
#include "DNS-binpac.h"
|
#include "analyzer/protocol/stepping-stone/SteppingStone.h"
|
||||||
#include "HTTP-binpac.h"
|
#include "analyzer/protocol/stepping-stone/events.bif.h"
|
||||||
|
#include "analyzer/protocol/backdoor/BackDoor.h"
|
||||||
#include "SteppingStone.h"
|
#include "analyzer/protocol/backdoor/events.bif.h"
|
||||||
#include "BackDoor.h"
|
#include "analyzer/protocol/interconn/InterConn.h"
|
||||||
#include "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 "Discard.h"
|
||||||
#include "RuleMatcher.h"
|
#include "RuleMatcher.h"
|
||||||
#include "DPM.h"
|
|
||||||
|
|
||||||
#include "PacketSort.h"
|
#include "PacketSort.h"
|
||||||
#include "TunnelEncapsulation.h"
|
#include "TunnelEncapsulation.h"
|
||||||
|
|
||||||
|
#include "analyzer/Manager.h"
|
||||||
|
|
||||||
// These represent NetBIOS services on ephemeral ports. They're numbered
|
// 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
|
// so that we can use a single int to hold either an actual TCP/UDP server
|
||||||
// port or one of these.
|
// port or one of these.
|
||||||
|
@ -104,7 +107,7 @@ NetSessions::NetSessions()
|
||||||
fragments.SetDeleteFunc(bro_obj_delete_func);
|
fragments.SetDeleteFunc(bro_obj_delete_func);
|
||||||
|
|
||||||
if ( stp_correlate_pair )
|
if ( stp_correlate_pair )
|
||||||
stp_manager = new SteppingStoneManager();
|
stp_manager = new analyzer::stepping_stone::SteppingStoneManager();
|
||||||
else
|
else
|
||||||
stp_manager = 0;
|
stp_manager = 0;
|
||||||
|
|
||||||
|
@ -143,7 +146,7 @@ NetSessions::NetSessions()
|
||||||
pkt_profiler = 0;
|
pkt_profiler = 0;
|
||||||
|
|
||||||
if ( arp_request || arp_reply || bad_arp )
|
if ( arp_request || arp_reply || bad_arp )
|
||||||
arp_analyzer = new ARP_Analyzer();
|
arp_analyzer = new analyzer::arp::ARP_Analyzer();
|
||||||
else
|
else
|
||||||
arp_analyzer = 0;
|
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);
|
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 )
|
if ( arp_analyzer )
|
||||||
arp_analyzer->NextPacket(t, hdr, pkt, hdr_size);
|
arp_analyzer->NextPacket(t, hdr, pkt, hdr_size);
|
||||||
|
@ -523,9 +526,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
const struct icmp* icmpp = (const struct icmp *) data;
|
||||||
|
|
||||||
id.src_port = icmpp->icmp_type;
|
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,
|
icmpp->icmp_code,
|
||||||
id.is_one_way);
|
id.is_one_way);
|
||||||
|
|
||||||
id.src_port = htons(id.src_port);
|
id.src_port = htons(id.src_port);
|
||||||
id.dst_port = htons(id.dst_port);
|
id.dst_port = htons(id.dst_port);
|
||||||
|
@ -539,9 +542,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
const struct icmp* icmpp = (const struct icmp *) data;
|
||||||
|
|
||||||
id.src_port = icmpp->icmp_type;
|
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,
|
icmpp->icmp_code,
|
||||||
id.is_one_way);
|
id.is_one_way);
|
||||||
|
|
||||||
id.src_port = htons(id.src_port);
|
id.src_port = htons(id.src_port);
|
||||||
id.dst_port = htons(id.dst_port);
|
id.dst_port = htons(id.dst_port);
|
||||||
|
@ -964,12 +967,12 @@ void NetSessions::Remove(Connection* c)
|
||||||
{
|
{
|
||||||
c->CancelTimers();
|
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 )
|
if ( ta && c->ConnTransport() == TRANSPORT_TCP )
|
||||||
{
|
{
|
||||||
assert(ta->GetTag() == AnalyzerTag::TCP);
|
assert(ta->IsAnalyzer("TCP"));
|
||||||
TCP_Endpoint* to = ta->Orig();
|
analyzer::tcp::TCP_Endpoint* to = ta->Orig();
|
||||||
TCP_Endpoint* tr = ta->Resp();
|
analyzer::tcp::TCP_Endpoint* tr = ta->Resp();
|
||||||
|
|
||||||
tcp_stats.StateLeft(to->state, tr->state);
|
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);
|
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
|
||||||
conn->SetTransport(tproto);
|
conn->SetTransport(tproto);
|
||||||
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
analyzer_mgr->BuildInitialAnalyzerTree(conn);
|
||||||
|
|
||||||
bool external = conn->IsExternal();
|
bool external = conn->IsExternal();
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
#include "Dict.h"
|
#include "Dict.h"
|
||||||
#include "CompHash.h"
|
#include "CompHash.h"
|
||||||
#include "IP.h"
|
#include "IP.h"
|
||||||
#include "ARP.h"
|
|
||||||
#include "Frag.h"
|
#include "Frag.h"
|
||||||
#include "PacketFilter.h"
|
#include "PacketFilter.h"
|
||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
#include "NetVar.h"
|
#include "NetVar.h"
|
||||||
#include "TunnelEncapsulation.h"
|
#include "TunnelEncapsulation.h"
|
||||||
|
#include "analyzer/protocol/tcp/Stats.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
struct pcap_pkthdr;
|
struct pcap_pkthdr;
|
||||||
|
@ -26,11 +27,12 @@ declare(PDict,Connection);
|
||||||
declare(PDict,FragReassembler);
|
declare(PDict,FragReassembler);
|
||||||
|
|
||||||
class Discarder;
|
class Discarder;
|
||||||
class SteppingStoneManager;
|
|
||||||
class PacketFilter;
|
class PacketFilter;
|
||||||
|
|
||||||
class PacketSortElement;
|
class PacketSortElement;
|
||||||
|
|
||||||
|
namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } }
|
||||||
|
namespace analyzer { namespace arp { class ARP_Analyzer; } }
|
||||||
|
|
||||||
struct SessionStats {
|
struct SessionStats {
|
||||||
int num_TCP_conns;
|
int num_TCP_conns;
|
||||||
int num_UDP_conns;
|
int num_UDP_conns;
|
||||||
|
@ -127,7 +129,7 @@ public:
|
||||||
|
|
||||||
void ExpireTimerMgrs();
|
void ExpireTimerMgrs();
|
||||||
|
|
||||||
SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
analyzer::stepping_stone::SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
||||||
|
|
||||||
unsigned int CurrentConnections()
|
unsigned int CurrentConnections()
|
||||||
{
|
{
|
||||||
|
@ -183,7 +185,7 @@ public:
|
||||||
unsigned int ConnectionMemoryUsage();
|
unsigned int ConnectionMemoryUsage();
|
||||||
unsigned int ConnectionMemoryUsageConnVals();
|
unsigned int ConnectionMemoryUsageConnVals();
|
||||||
unsigned int MemoryAllocation();
|
unsigned int MemoryAllocation();
|
||||||
TCPStateStats tcp_stats; // keeps statistics on TCP states
|
analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RemoteSerializer;
|
friend class RemoteSerializer;
|
||||||
|
@ -255,9 +257,9 @@ protected:
|
||||||
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
|
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
|
||||||
IPTunnelMap ip_tunnels;
|
IPTunnelMap ip_tunnels;
|
||||||
|
|
||||||
ARP_Analyzer* arp_analyzer;
|
analyzer::arp::ARP_Analyzer* arp_analyzer;
|
||||||
|
|
||||||
SteppingStoneManager* stp_manager;
|
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
||||||
Discarder* discarder;
|
Discarder* discarder;
|
||||||
PacketFilter* packet_filter;
|
PacketFilter* packet_filter;
|
||||||
OSFingerprint* SYN_OS_Fingerprinter;
|
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);
|
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,
|
PacketProfiler::PacketProfiler(unsigned int mode, double freq,
|
||||||
BroFile* arg_file)
|
BroFile* arg_file)
|
||||||
{
|
{
|
||||||
|
|
64
src/Stats.h
64
src/Stats.h
|
@ -7,9 +7,6 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#include "TCP_Endpoint.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Object called by SegmentProfiler when it is done and reports its
|
// Object called by SegmentProfiler when it is done and reports its
|
||||||
// cumulative CPU/memory statistics.
|
// cumulative CPU/memory statistics.
|
||||||
class SegmentStatsReporter {
|
class SegmentStatsReporter {
|
||||||
|
@ -121,67 +118,6 @@ extern uint64 tot_ack_bytes;
|
||||||
extern uint64 tot_gap_events;
|
extern uint64 tot_gap_events;
|
||||||
extern uint64 tot_gap_bytes;
|
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 {
|
class PacketProfiler {
|
||||||
public:
|
public:
|
||||||
PacketProfiler(unsigned int mode, double freq, BroFile* arg_file);
|
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;
|
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()
|
EnumType::~EnumType()
|
||||||
{
|
{
|
||||||
for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter )
|
for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter )
|
||||||
|
|
|
@ -523,6 +523,7 @@ protected:
|
||||||
class EnumType : public BroType {
|
class EnumType : public BroType {
|
||||||
public:
|
public:
|
||||||
EnumType(const string& arg_name);
|
EnumType(const string& arg_name);
|
||||||
|
EnumType(EnumType* e);
|
||||||
~EnumType();
|
~EnumType();
|
||||||
|
|
||||||
// The value of this name is next internal counter value, starting
|
// The value of this name is next internal counter value, starting
|
||||||
|
@ -567,6 +568,7 @@ protected:
|
||||||
class CommentedEnumType: public EnumType {
|
class CommentedEnumType: public EnumType {
|
||||||
public:
|
public:
|
||||||
CommentedEnumType(const string& arg_name) : EnumType(arg_name) {}
|
CommentedEnumType(const string& arg_name) : EnumType(arg_name) {}
|
||||||
|
CommentedEnumType(EnumType* e) : EnumType(e) {}
|
||||||
~CommentedEnumType();
|
~CommentedEnumType();
|
||||||
|
|
||||||
void DescribeReST(ODesc* d) const;
|
void DescribeReST(ODesc* d) const;
|
||||||
|
|
|
@ -1049,6 +1049,11 @@ StringVal::StringVal(const char* s) : Val(TYPE_STRING)
|
||||||
val.string_val = new BroString(s);
|
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()
|
StringVal* StringVal::ToUpper()
|
||||||
{
|
{
|
||||||
val.string_val->ToUpper();
|
val.string_val->ToUpper();
|
||||||
|
|
|
@ -608,6 +608,7 @@ class StringVal : public Val {
|
||||||
public:
|
public:
|
||||||
StringVal(BroString* s);
|
StringVal(BroString* s);
|
||||||
StringVal(const char* s);
|
StringVal(const char* s);
|
||||||
|
StringVal(const string& s);
|
||||||
StringVal(int length, const char* s);
|
StringVal(int length, const char* s);
|
||||||
|
|
||||||
Val* SizeVal() const
|
Val* SizeVal() const
|
||||||
|
|
|
@ -156,6 +156,12 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
|
|
||||||
if ( do_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)) ||
|
if ( (c == INIT_EXTRA && id->FindAttr(ATTR_ADD_FUNC)) ||
|
||||||
(c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) )
|
(c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) )
|
||||||
// Just apply the function.
|
// Just apply the function.
|
||||||
|
|
|
@ -1,191 +1,45 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Analyzer.h"
|
#include "Analyzer.h"
|
||||||
#include "PIA.h"
|
#include "Manager.h"
|
||||||
#include "Event.h"
|
|
||||||
|
|
||||||
#include "AYIYA.h"
|
#include "analyzer/protocol/pia/PIA.h"
|
||||||
#include "BackDoor.h"
|
#include "../Event.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"
|
|
||||||
|
|
||||||
// Keep same order here as in AnalyzerTag definition!
|
namespace analyzer {
|
||||||
const Analyzer::Config Analyzer::analyzer_configs[] = {
|
|
||||||
{ AnalyzerTag::Error, "<ERROR>", 0, 0, 0, false },
|
|
||||||
|
|
||||||
{ AnalyzerTag::PIA_TCP, "PIA_TCP", PIA_TCP::InstantiateAnalyzer,
|
class AnalyzerTimer : public Timer {
|
||||||
PIA_TCP::Available, 0, false },
|
public:
|
||||||
{ AnalyzerTag::PIA_UDP, "PIA_UDP", PIA_UDP::InstantiateAnalyzer,
|
AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||||
PIA_UDP::Available, 0, false },
|
double arg_t, int arg_do_expire, TimerType arg_type);
|
||||||
|
|
||||||
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
|
virtual ~AnalyzerTimer();
|
||||||
ICMP_Analyzer::Available, 0, false },
|
|
||||||
|
|
||||||
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
|
void Dispatch(double t, int is_expire);
|
||||||
TCP_Analyzer::Available, 0, false },
|
|
||||||
{ AnalyzerTag::UDP, "UDP", UDP_Analyzer::InstantiateAnalyzer,
|
|
||||||
UDP_Analyzer::Available, 0, false },
|
|
||||||
|
|
||||||
{ AnalyzerTag::BitTorrent, "BITTORRENT",
|
protected:
|
||||||
BitTorrent_Analyzer::InstantiateAnalyzer,
|
AnalyzerTimer() {}
|
||||||
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 },
|
|
||||||
|
|
||||||
{ AnalyzerTag::DHCP_BINPAC, "DHCP_BINPAC",
|
void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
|
||||||
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 },
|
|
||||||
|
|
||||||
{ AnalyzerTag::AYIYA, "AYIYA",
|
Analyzer* analyzer;
|
||||||
AYIYA_Analyzer::InstantiateAnalyzer,
|
analyzer_timer_func timer;
|
||||||
AYIYA_Analyzer::Available, 0, false },
|
int do_expire;
|
||||||
{ 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 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
AnalyzerTimer::~AnalyzerTimer()
|
||||||
{
|
{
|
||||||
analyzer->RemoveTimer(this);
|
analyzer->RemoveTimer(this);
|
||||||
|
@ -216,36 +70,53 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||||
Ref(analyzer->Conn());
|
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(tag);
|
||||||
assert(a);
|
return analyzer_mgr->GetAnalyzerName(tag);
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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++ )
|
assert(tag);
|
||||||
if ( strcasecmp(analyzer_configs[i].name, name) == 0 )
|
return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0;
|
||||||
return analyzer_configs[i].tag;
|
|
||||||
|
|
||||||
return AnalyzerTag::Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in debugging output.
|
// Used in debugging output.
|
||||||
static string fmt_analyzer(Analyzer* a)
|
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
|
// Don't Ref conn here to avoid circular ref'ing. It can't be deleted
|
||||||
// before us.
|
// 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)
|
void Analyzer::NextStream(int len, const u_char* data, bool is_orig)
|
||||||
{
|
{
|
||||||
if ( skip )
|
if ( skip )
|
||||||
|
@ -514,7 +380,7 @@ void Analyzer::ForwardEndOfData(bool orig)
|
||||||
|
|
||||||
void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
||||||
{
|
{
|
||||||
if ( HasChildAnalyzer(analyzer->GetTag()) )
|
if ( HasChildAnalyzer(analyzer->GetAnalyzerTag()) )
|
||||||
{
|
{
|
||||||
analyzer->Done();
|
analyzer->Done();
|
||||||
delete analyzer;
|
delete analyzer;
|
||||||
|
@ -533,16 +399,19 @@ void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
||||||
if ( init )
|
if ( init )
|
||||||
analyzer->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());
|
fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Analyzer* Analyzer::AddChildAnalyzer(AnalyzerTag::Tag analyzer)
|
Analyzer* Analyzer::AddChildAnalyzer(Tag analyzer)
|
||||||
{
|
{
|
||||||
if ( ! HasChildAnalyzer(analyzer) )
|
if ( ! HasChildAnalyzer(analyzer) )
|
||||||
{
|
{
|
||||||
Analyzer* a = InstantiateAnalyzer(analyzer, conn);
|
Analyzer* a = analyzer_mgr->InstantiateAnalyzer(analyzer, conn);
|
||||||
AddChildAnalyzer(a);
|
|
||||||
|
if ( a )
|
||||||
|
AddChildAnalyzer(a);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +423,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) )
|
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());
|
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||||
// We just flag it as being removed here but postpone
|
// We just flag it as being removed here but postpone
|
||||||
// actually doing that to later. Otherwise, we'd need
|
// 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)
|
LOOP_OVER_CHILDREN(i)
|
||||||
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
|
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());
|
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||||
// See comment above.
|
// See comment above.
|
||||||
(*i)->removing = true;
|
(*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)
|
LOOP_OVER_CHILDREN(i)
|
||||||
if ( (*i)->tag == tag )
|
if ( (*i)->tag == tag )
|
||||||
|
@ -593,7 +462,7 @@ bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
Analyzer* Analyzer::FindChild(ID arg_id)
|
||||||
{
|
{
|
||||||
if ( id == arg_id )
|
if ( id == arg_id )
|
||||||
return this;
|
return this;
|
||||||
|
@ -608,7 +477,7 @@ Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
Analyzer* Analyzer::FindChild(Tag arg_tag)
|
||||||
{
|
{
|
||||||
if ( tag == arg_tag )
|
if ( tag == arg_tag )
|
||||||
return this;
|
return this;
|
||||||
|
@ -623,6 +492,12 @@ Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
||||||
return 0;
|
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)
|
void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||||
{
|
{
|
||||||
Analyzer* child = *i;
|
Analyzer* child = *i;
|
||||||
|
@ -636,7 +511,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||||
child->removing = false;
|
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());
|
fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str());
|
||||||
|
|
||||||
children.erase(i);
|
children.erase(i);
|
||||||
|
@ -645,9 +520,9 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||||
|
|
||||||
void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
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(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -675,7 +550,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
|
|
||||||
analyzer->Init();
|
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(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -699,7 +574,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
else
|
else
|
||||||
*head = s->sibling;
|
*head = s->sibling;
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "%s removed support %s",
|
DBG_LOG(DBG_ANALYZER, "%s removed support %s",
|
||||||
fmt_analyzer(this).c_str(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -711,7 +586,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
|
bool Analyzer::HasSupportAnalyzer(Tag tag, bool orig)
|
||||||
{
|
{
|
||||||
SupportAnalyzer* s = orig ? orig_supporters : resp_supporters;
|
SupportAnalyzer* s = orig ? orig_supporters : resp_supporters;
|
||||||
for ( ; s; s = s->sibling )
|
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,
|
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||||
int seq, const IP_Hdr* ip, int caplen)
|
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_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
|
||||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
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_analyzer(this).c_str(), len, is_orig ? "T" : "F",
|
||||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::Undelivered(int seq, int len, bool is_orig)
|
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");
|
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::EndOfData(bool is_orig)
|
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");
|
fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::FlipRoles()
|
void Analyzer::FlipRoles()
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s FlipRoles()");
|
DBG_LOG(DBG_ANALYZER, "%s FlipRoles()");
|
||||||
|
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
(*i)->FlipRoles();
|
(*i)->FlipRoles();
|
||||||
|
@ -774,9 +649,12 @@ void Analyzer::ProtocolConfirmation()
|
||||||
if ( protocol_confirmed )
|
if ( protocol_confirmed )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
EnumVal* tval = tag.AsEnumVal();
|
||||||
|
Ref(tval);
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(new Val(tag, TYPE_COUNT));
|
vl->append(tval);
|
||||||
vl->append(new Val(id, TYPE_COUNT));
|
vl->append(new Val(id, TYPE_COUNT));
|
||||||
|
|
||||||
// We immediately raise the event so that the analyzer can quickly
|
// 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
|
else
|
||||||
r = new StringVal(reason);
|
r = new StringVal(reason);
|
||||||
|
|
||||||
|
EnumVal* tval = tag.AsEnumVal();
|
||||||
|
Ref(tval);
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(new Val(tag, TYPE_COUNT));
|
vl->append(tval);
|
||||||
vl->append(new Val(id, TYPE_COUNT));
|
vl->append(new Val(id, TYPE_COUNT));
|
||||||
vl->append(r);
|
vl->append(r);
|
||||||
|
|
||||||
|
@ -876,6 +757,31 @@ void Analyzer::UpdateConnVal(RecordVal *conn_val)
|
||||||
(*i)->UpdateConnVal(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,
|
void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
|
||||||
int seq, const IP_Hdr* ip, int caplen)
|
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