diff --git a/CHANGES b/CHANGES index 1c23429a43..4685ece5bb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,124 @@ +2.1-784 | 2013-07-04 22:28:48 -0400 + + * Add a call to lookup_connection in SSH scripts to update connval. (Seth Hall) + + * Updating submodule(s). (Robin Sommer) + +2.1-782 | 2013-07-03 17:00:39 -0700 + + * Remove the SSL log queueing mechanism that was included with the + log delay mechanism. (Seth Hall) + +2.1-780 | 2013-07-03 16:46:26 -0700 + + * Rewrite of the RAW input reader for improved robustness and new + features. (Bernhard Amann) This includes: + + - Send "end_of_data" event for all kind of streams. + - Send "process_finished" event with exit code of child + process at process termination. + - Expose name of input stream to readers. + - Better error handling. + - New "force_kill" option which SIGKILLs processes on reader termination. + - Supports reading from stdout and stderr simultaneously. + - Support sending data to stdin of child process. + - Streaming reads from external commands work without blocking. + +2.1-762 | 2013-07-03 16:33:22 -0700 + + * Fix to correct support for TLS 1.2. Addresses #1020. (Seth Hall, + with help from Rafal Lesniak). + +2.1-760 | 2013-07-03 16:31:36 -0700 + + * Teach broxygen to generate protocol analyzer plugin reference. + (Jon Siwek) + + * Adding 'const' to a number of C++ methods. (Jon Siwek) + +2.1-757 | 2013-07-03 16:28:10 -0700 + + * Fix redef of table index from clearing table. + + `redef foo["x"] = 1` now acts like `redef foo += { ["x"] = 1 }` + instead of `redef foo = { ["x"] = 1 }`. + + Addresses #1013. (Jon Siwek) + + +2.1-755 | 2013-07-03 16:22:43 -0700 + + * Add a general file analysis overview/how-to document. (Jon Siwek) + + * Improve file analysis doxygen comments. (Jon Siwek) + + * Improve tracking of HTTP file extraction. http.log now has files + taken from request and response bodies in different fields for + each, and can now track multiple files per body. That is, the + "extraction_file" field is now "extracted_request_files" and + "extracted_response_files". Addresses #988. (Jon Siwek) + + * Fix HTTP multipart body file analysis. Each part now gets assigned + a different file handle/id. (Jon Siwek) + + * Remove logging of analyzers field of FileAnalysis::Info. (Jon + Siwek) + + * Remove extraction counter in default file extraction scripts. (Jon + Siwek) + + * Remove FileAnalysis::postpone_timeout. + FileAnalysis::set_timeout_interval can now perform same function. + (Jon Siwek) + + * Make default get_file_handle handlers &priority=5 so they're + easier to override. (Jon Siwek) + + * Add input interface to forward data for file analysis. The new + Input::add_analysis function is used to automatically forward + input data on to the file analysis framework. (Jon Siwek) + + * File analysis framework interface simplifications. (Jon Siwek) + + - Remove script-layer data input interface (will be managed directly + by input framework later). + + - Only track files internally by file id hash. Chance of collision + too small to justify also tracking unique file string. + + +2.1-741 | 2013-06-07 17:28:50 -0700 + + * Fixing typo that could cause an assertion to falsely trigger. + (Robin Sommer) + +2.1-740 | 2013-06-07 16:37:32 -0700 + + * Fix for CMake 2.6.x. (Robin Sommer) + +2.1-738 | 2013-06-07 08:38:13 -0700 + + * Remove invalid free on non-allocated pointer in hash function + object. Addresses #1018. (Matthias Vallentin) + +2.1-736 | 2013-06-06 10:05:20 -0700 + + * New "magic constants" @DIR and @FILENAME that expand to the + directory path of the current script and just the script file name + without path, respectively. (Jon Siwek) + +2.1-731 | 2013-06-04 21:19:08 -0700 + + * Reorginization of internal protocol analyzer code. We're moving + them to a modularized structure, based on a plugin model. Along + with this change comes generic plugin infrastructure that we'll + later extend to other Bro component as well. For now all plugins + are compiled in statically, but in the future we plan to also + enable dynamic loading at run time. (Robin Sommer) + + * Ignoring file ids in external tests. (Robin Sommer) + 2.1-675 | 2013-06-02 20:03:19 -0700 * Fix a compiler warning. (Robin Sommer) diff --git a/NEWS b/NEWS index 665636b174..be0ddffaa2 100644 --- a/NEWS +++ b/NEWS @@ -68,11 +68,17 @@ New Functionality global foo: function(s: string, t: string &default="abc", u: count &default=0); +- Scripts can now use two new "magic constants" @DIR and @FILENAME + that expand to the directory path of the current script and just the + script file name without path, respectively. (Jon Siwek) + - The new file analysis framework moves most of the processing of file - content from script-land into the core, where it belongs. Much of - this is an internal change, the framework comes with the following - user-visibible functionality (some of that was already available - before, but done differently): + content from script-land into the core, where it belongs. See + doc/file-analysis.rst for more information. + + Much of this is an internal change, but the framework also comes + with the following user-visibible functionality (some of that was + already available before, but done differently): [TODO: This will probably change with further script updates.] diff --git a/VERSION b/VERSION index f3667fe959..f1aa1a9e8e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-675 +2.1-784 diff --git a/aux/binpac b/aux/binpac index f86a3169b8..c39bd478b9 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit f86a3169b8d49189d264cbc1a7507260cd9ff51d +Subproject commit c39bd478b9d0ecd05b1b83aa9d09a7887893977c diff --git a/aux/bro-aux b/aux/bro-aux index cfaf4eea78..a9942558c7 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit cfaf4eea788bdac4ebfe9e46e3de2cd74b0bc068 +Subproject commit a9942558c7d3dfd80148b8aaded64c82ade3d117 diff --git a/aux/broccoli b/aux/broccoli index 8955807b0f..889f9c6594 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 8955807b0f4151f5f6aca2e68d353b9b341d9f86 +Subproject commit 889f9c65944ceac20ad9230efc39d33e6e1221c3 diff --git a/aux/broctl b/aux/broctl index 0eca32b35d..017e773244 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 0eca32b35d16a4d387f41976ab46360ee6ecaed8 +Subproject commit 017e7732446b36af935c26834394b51829335e7c diff --git a/bro-path-dev.in b/bro-path-dev.in index 81d4f111fc..2c17d057c9 100755 --- a/bro-path-dev.in +++ b/bro-path-dev.in @@ -12,7 +12,7 @@ broPolicies=${BRO_SCRIPT_SOURCE_PATH}:${BRO_SCRIPT_SOURCE_PATH}/policy:${BRO_SCRIPT_SOURCE_PATH}/site -broGenPolicies=${CMAKE_BINARY_DIR}/src +broGenPolicies=${CMAKE_BINARY_DIR}/scripts installedPolicies=${BRO_SCRIPT_INSTALL_PATH}:${BRO_SCRIPT_INSTALL_PATH}/site diff --git a/cmake b/cmake index e1a7fd00a0..0187b33a29 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit e1a7fd00a0a66d6831a239fe84f5fcfaa54e2c35 +Subproject commit 0187b33a29d5ec824f940feff60dc5d8c2fe314f diff --git a/doc/ext/bro.py b/doc/ext/bro.py index 9bdd86bd9a..6ef11c37f6 100644 --- a/doc/ext/bro.py +++ b/doc/ext/bro.py @@ -82,7 +82,8 @@ class BroGeneric(ObjectDescription): objects = self.env.domaindata['bro']['objects'] key = (self.objtype, name) - if key in objects: + if ( key in objects and self.objtype != "id" and + self.objtype != "type" ): self.env.warn(self.env.docname, 'duplicate description of %s %s, ' % (self.objtype, name) + @@ -150,6 +151,12 @@ class BroEnum(BroGeneric): #self.indexnode['entries'].append(('single', indextext, # targetname, targetname)) m = sig.split() + + if len(m) < 2: + self.env.warn(self.env.docname, + "bro:enum directive missing argument(s)") + return + if m[1] == "Notice::Type": if 'notices' not in self.env.domaindata['bro']: self.env.domaindata['bro']['notices'] = [] diff --git a/doc/file-analysis.rst b/doc/file-analysis.rst index e3e62ceb2e..f312e06471 100644 --- a/doc/file-analysis.rst +++ b/doc/file-analysis.rst @@ -10,7 +10,7 @@ File Analysis script-layer depending on which network protocol was involved in the file transfer. Scripts written to analyze files over one protocol would have to be copied and modified to fit other protocols. The - file analysis framework (FAF) is an attempt to provide a generalized + file analysis framework (FAF) instead provides a generalized presentation of file-related information. The information regarding the protocol involved in transporting a file over the network is still available, but it no longer has to dictate how one organizes diff --git a/doc/index.rst b/doc/index.rst index 78f705abfb..ad05f7bf82 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -46,7 +46,7 @@ Script Reference scripts/packages scripts/index scripts/builtins - scripts/bifs + scripts/proto-analyzers Other Bro Components -------------------- diff --git a/doc/scripts/CMakeLists.txt b/doc/scripts/CMakeLists.txt index 315f751cd1..ddb09bb29c 100644 --- a/doc/scripts/CMakeLists.txt +++ b/doc/scripts/CMakeLists.txt @@ -15,11 +15,11 @@ endif () # # srcDir: the directory which contains broInput # broInput: the file name of a bro policy script, any path prefix of this -# argument will be used to derive what path under policy/ the generated +# argument will be used to derive what path under scripts/ the generated # documentation will be placed. # group: optional name of group that the script documentation will belong to. -# If this is not given, .bif files automatically get their own group or -# the group is automatically by any path portion of the broInput argument. +# If this is not given, the group is automatically set to any path portion +# of the broInput argument. # # In addition to adding the makefile target, several CMake variables are set: # @@ -45,12 +45,6 @@ macro(REST_TARGET srcDir broInput) set(sumTextSrc ${absSrcPath}) set(ogSourceFile ${absSrcPath}) - if (${extension} STREQUAL ".bif.bro") - set(ogSourceFile ${BIF_SRC_DIR}/${basename}) - # the summary text is taken at configure time, but .bif.bro files - # may not have been generated yet, so read .bif file instead - set(sumTextSrc ${ogSourceFile}) - endif () if (NOT relDstDir) set(docName "${basename}") @@ -70,8 +64,6 @@ macro(REST_TARGET srcDir broInput) if (NOT "${ARGN}" STREQUAL "") set(group ${ARGN}) - elseif (${extension} STREQUAL ".bif.bro") - set(group bifs) elseif (relDstDir) set(group ${relDstDir}/index) # add package index to master package list if not already in it @@ -132,6 +124,29 @@ endmacro(REST_TARGET) # Schedule Bro scripts for which to generate documentation. include(DocSourcesList.cmake) +# This reST target is independent of a particular Bro script... +add_custom_command(OUTPUT proto-analyzers.rst + # delete any leftover state from previous bro runs + COMMAND "${CMAKE_COMMAND}" + ARGS -E remove_directory .state + # generate the reST documentation using bro + COMMAND BROPATH=${BROPATH}:${srcDir} BROMAGIC=${CMAKE_SOURCE_DIR}/magic ${CMAKE_BINARY_DIR}/src/bro + ARGS -b -Z base/init-bare.bro || (rm -rf .state *.log *.rst && exit 1) + # move generated doc into a new directory tree that + # defines the final structure of documents + COMMAND "${CMAKE_COMMAND}" + ARGS -E make_directory ${dstDir} + COMMAND "${CMAKE_COMMAND}" + ARGS -E copy proto-analyzers.rst ${dstDir} + # clean up the build directory + COMMAND rm + ARGS -rf .state *.log *.rst + DEPENDS bro + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "[Bro] Generating reST docs for proto-analyzers.rst" +) +list(APPEND ALL_REST_OUTPUTS proto-analyzers.rst) + # create temporary list of all docs to include in the master policy/index file file(WRITE ${MASTER_POLICY_INDEX} "${MASTER_POLICY_INDEX_TEXT}") diff --git a/doc/scripts/DocSourcesList.cmake b/doc/scripts/DocSourcesList.cmake index e4c92a0777..fdd919f86b 100644 --- a/doc/scripts/DocSourcesList.cmake +++ b/doc/scripts/DocSourcesList.cmake @@ -16,15 +16,64 @@ rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro internal) rest_target(${psd} base/init-default.bro internal) rest_target(${psd} base/init-bare.bro internal) -rest_target(${CMAKE_BINARY_DIR}/src base/bro.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/const.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/event.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/file_analysis.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/input.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/logging.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/reporter.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/strings.bif.bro) -rest_target(${CMAKE_BINARY_DIR}/src base/types.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/analyzer.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/bro.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/const.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/event.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/file_analysis.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/input.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/logging.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ARP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_AYIYA.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_BackDoor.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_BitTorrent.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ConnSize.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DCE_RPC.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DHCP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_DNS.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FTP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FTP.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_File.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_FileHash.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Finger.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_GTPv1.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Gnutella.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_HTTP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_HTTP.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ICMP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_IRC.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Ident.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_InterConn.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Login.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Login.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_MIME.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Modbus.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NCP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NTP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetBIOS.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetBIOS.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_NetFlow.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_PIA.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_POP3.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_RPC.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMB.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMTP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SMTP.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SOCKS.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSH.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSL.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SSL.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_SteppingStone.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Syslog.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_TCP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_TCP.functions.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_Teredo.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_UDP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/plugins/Bro_ZIP.events.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/reporter.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/strings.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/scripts base/bif/types.bif.bro) +rest_target(${psd} base/frameworks/analyzer/main.bro) rest_target(${psd} base/frameworks/cluster/main.bro) rest_target(${psd} base/frameworks/cluster/nodes/manager.bro) rest_target(${psd} base/frameworks/cluster/nodes/proxy.bro) @@ -146,7 +195,6 @@ rest_target(${psd} policy/frameworks/software/vulnerable.bro) rest_target(${psd} policy/integration/barnyard2/main.bro) rest_target(${psd} policy/integration/barnyard2/types.bro) rest_target(${psd} policy/integration/collective-intel/main.bro) -rest_target(${psd} policy/misc/analysis-groups.bro) rest_target(${psd} policy/misc/app-metrics.bro) rest_target(${psd} policy/misc/capture-loss.bro) rest_target(${psd} policy/misc/detect-traceroute/main.bro) diff --git a/doc/scripts/bifs.rst b/doc/scripts/bifs.rst deleted file mode 100644 index eaae0e13b8..0000000000 --- a/doc/scripts/bifs.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. This is a stub doc to which broxygen appends during the build process - -Built-In Functions (BIFs) -========================= - diff --git a/doc/scripts/example.bro b/doc/scripts/example.bro index 9f6f656ee1..2ff12bfa27 100644 --- a/doc/scripts/example.bro +++ b/doc/scripts/example.bro @@ -54,11 +54,11 @@ global example_ports = { 443/tcp, 562/tcp, } &redef; -# redefinitions of "dpd_config" are self-documenting and -# go into the generated doc's "Port Analysis" section -redef dpd_config += { - [ANALYZER_SSL] = [$ports = example_ports] -}; + +event bro_init() + { + Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, example_ports); + } # redefinitions of "Notice::Type" are self-documenting, but # more information can be supplied in two different ways diff --git a/doc/scripts/genDocSourcesList.sh b/doc/scripts/genDocSourcesList.sh index a10121221a..31905c68db 100755 --- a/doc/scripts/genDocSourcesList.sh +++ b/doc/scripts/genDocSourcesList.sh @@ -67,12 +67,12 @@ sourcedir=${thisdir}/../.. echo "$statictext" > $outfile -bifs=`( cd ${sourcedir}/src && find . -name \*\.bif | sort )` +bifs=`( cd ${sourcedir}/build/scripts/base && find . -name \*\.bif.bro | sort )` for file in $bifs do - f=${file:2}.bro - echo "rest_target(\${CMAKE_BINARY_DIR}/src base/$f)" >> $outfile + f=${file:2} + echo "rest_target(\${CMAKE_BINARY_DIR}/scripts base/$f)" >> $outfile done scriptfiles=`( cd ${sourcedir}/scripts && find . -name \*\.bro | sort )` diff --git a/scripts/base/frameworks/analyzer/__load__.bro b/scripts/base/frameworks/analyzer/__load__.bro new file mode 100644 index 0000000000..a10fe855df --- /dev/null +++ b/scripts/base/frameworks/analyzer/__load__.bro @@ -0,0 +1 @@ +@load ./main diff --git a/scripts/base/frameworks/analyzer/main.bro b/scripts/base/frameworks/analyzer/main.bro new file mode 100644 index 0000000000..c7bfd1ce34 --- /dev/null +++ b/scripts/base/frameworks/analyzer/main.bro @@ -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); + } + diff --git a/scripts/base/frameworks/dpd/main.bro b/scripts/base/frameworks/dpd/main.bro index a5349b6cfb..c3282a1da4 100644 --- a/scripts/base/frameworks/dpd/main.bro +++ b/scripts/base/frameworks/dpd/main.bro @@ -23,12 +23,12 @@ export { analyzer: string &log; ## The textual reason for the analysis failure. 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. disabled_aids: set[count]; }; - + ## Ignore violations which go this many bytes into the connection. ## Set to 0 to never ignore protocol violations. const ignore_violations_after = 10 * 1024 &redef; @@ -41,41 +41,30 @@ redef record connection += { event bro_init() &priority=5 { Log::create_stream(DPD::LOG, [$columns=Info]); - - # Populate the internal DPD analysis variable. - for ( a in dpd_config ) - { - for ( p in dpd_config[a]$ports ) - { - if ( p !in dpd_analyzer_ports ) - dpd_analyzer_ports[p] = set(); - add dpd_analyzer_ports[p][a]; - } - } } -event protocol_confirmation(c: connection, atype: count, aid: count) &priority=10 +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=10 { - local analyzer = analyzer_name(atype); - + local analyzer = Analyzer::name(atype); + if ( fmt("-%s",analyzer) in c$service ) delete c$service[fmt("-%s", analyzer)]; add c$service[analyzer]; } -event protocol_violation(c: connection, atype: count, aid: count, +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=10 { - local analyzer = analyzer_name(atype); + local analyzer = Analyzer::name(atype); # If the service hasn't been confirmed yet, don't generate a log message # for the protocol violation. if ( analyzer !in c$service ) return; - + delete c$service[analyzer]; add c$service[fmt("-%s", analyzer)]; - + local info: Info; info$ts=network_time(); info$uid=c$uid; @@ -86,7 +75,7 @@ event protocol_violation(c: connection, atype: count, aid: count, c$dpd = info; } -event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=5 +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=5 { if ( !c?$dpd || aid in c$dpd$disabled_aids ) return; @@ -94,13 +83,13 @@ event protocol_violation(c: connection, atype: count, aid: count, reason: string local size = c$orig$size + c$resp$size; if ( ignore_violations_after > 0 && size > ignore_violations_after ) return; - + # Disable the analyzer that raised the last core-generated event. disable_analyzer(c$id, 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 { if ( c?$dpd ) diff --git a/scripts/base/frameworks/files/main.bro b/scripts/base/frameworks/files/main.bro index 1c0481a87c..d6e26e1833 100644 --- a/scripts/base/frameworks/files/main.bro +++ b/scripts/base/frameworks/files/main.bro @@ -1,7 +1,7 @@ ##! An interface for driving the analysis of files, possibly independent of ##! any network protocol over which they're transported. -@load base/file_analysis.bif +@load base/bif/file_analysis.bif @load base/frameworks/logging @load base/utils/site @@ -105,7 +105,7 @@ export { ## A table that can be used to disable file analysis completely for ## any files transferred over given network protocol analyzers. - const disable: table[AnalyzerTag] of bool = table() &redef; + const disable: table[Analyzer::Tag] of bool = table() &redef; ## The salt concatenated to unique file handle strings generated by ## :bro:see:`get_file_handle` before hashing them in to a file id diff --git a/scripts/base/frameworks/input/main.bro b/scripts/base/frameworks/input/main.bro index 5a12239819..e5d74cbc36 100644 --- a/scripts/base/frameworks/input/main.bro +++ b/scripts/base/frameworks/input/main.bro @@ -125,7 +125,6 @@ export { ## A file analyis input stream type used to forward input data to the ## file analysis framework. type AnalysisDescription: record { - ## String that allows the reader to find the source. ## For `READER_ASCII`, this is the filename. source: string; @@ -186,7 +185,7 @@ export { global end_of_data: event(name: string, source:string); } -@load base/input.bif +@load base/bif/input.bif module Input; diff --git a/scripts/base/frameworks/input/readers/raw.bro b/scripts/base/frameworks/input/readers/raw.bro index 45deed3eda..9fa7d1a2fb 100644 --- a/scripts/base/frameworks/input/readers/raw.bro +++ b/scripts/base/frameworks/input/readers/raw.bro @@ -6,4 +6,12 @@ export { ## Separator between input records. ## Please note that the separator has to be exactly one character long const record_separator = "\n" &redef; + + ## Event that is called when a process created by the raw reader exits. + ## + ## name: name of the input stream + ## source: source of the input stream + ## exit_code: exit code of the program, or number of the signal that forced the program to exit + ## signal_exit: false when program exitted normally, true when program was forced to exit by a signal + global process_finished: event(name: string, source:string, exit_code:count, signal_exit:bool); } diff --git a/scripts/base/frameworks/logging/main.bro b/scripts/base/frameworks/logging/main.bro index b1d76cfb62..30cc9c0d73 100644 --- a/scripts/base/frameworks/logging/main.bro +++ b/scripts/base/frameworks/logging/main.bro @@ -366,7 +366,7 @@ export { # We keep a script-level copy of all filters so that we can manipulate them. global filters: table[ID, string] of Filter; -@load base/logging.bif # Needs Filter and Stream defined. +@load base/bif/logging.bif # Needs Filter and Stream defined. module Log; diff --git a/scripts/base/frameworks/reporter/main.bro b/scripts/base/frameworks/reporter/main.bro index 249ecdac98..891aebf6b2 100644 --- a/scripts/base/frameworks/reporter/main.bro +++ b/scripts/base/frameworks/reporter/main.bro @@ -9,7 +9,7 @@ ##! Note that this framework deals with the handling of internally generated ##! reporter messages, for the interface in to actually creating interface ##! into actually creating reporter messages from the scripting layer, use -##! the built-in functions in :doc:`/scripts/base/reporter.bif`. +##! the built-in functions in :doc:`/scripts/base/bif/reporter.bif`. module Reporter; diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index a8fc6c8236..faa725b3f6 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -83,19 +83,17 @@ export { } const ayiya_ports = { 5072/udp }; -redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] }; - const teredo_ports = { 3544/udp }; -redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] }; - const gtpv1_ports = { 2152/udp, 2123/udp }; -redef dpd_config += { [ANALYZER_GTPV1] = [$ports = gtpv1_ports] }; - redef likely_server_ports += { ayiya_ports, teredo_ports, gtpv1_ports }; event bro_init() &priority=5 { Log::create_stream(Tunnel::LOG, [$columns=Info]); + + Analyzer::register_for_ports(Analyzer::ANALYZER_AYIYA, ayiya_ports); + Analyzer::register_for_ports(Analyzer::ANALYZER_TEREDO, teredo_ports); + Analyzer::register_for_ports(Analyzer::ANALYZER_GTPV1, gtpv1_ports); } function register_all(ecv: EncapsulatingConnVector) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 4e1a5248c8..d8d70a9bc1 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1,5 +1,5 @@ -@load base/const.bif -@load base/types.bif +@load base/bif/const.bif.bro +@load base/bif/types.bif # Type declarations @@ -222,17 +222,6 @@ type endpoint_stats: record { endian_type: count; }; -## A unique analyzer instance ID. Each time instantiates a protocol analyzers -## for a connection, it assigns it a unique ID that can be used to reference -## that instance. -## -## .. bro:see:: analyzer_name disable_analyzer protocol_confirmation -## protocol_violation -## -## .. todo::While we declare an alias for the type here, the events/functions still -## use ``count``. That should be changed. -type AnalyzerID: count; - module Tunnel; export { ## Records the identity of an encapsulating parent of a tunneled connection. @@ -713,9 +702,9 @@ type entropy_test_result: record { }; # Prototypes of Bro built-in functions. -@load base/strings.bif -@load base/bro.bif -@load base/reporter.bif +@load base/bif/strings.bif +@load base/bif/bro.bif +@load base/bif/reporter.bif ## Deprecated. This is superseded by the new logging framework. global log_file_name: function(tag: string): string &redef; @@ -2723,7 +2712,7 @@ export { } module GLOBAL; -@load base/event.bif +@load base/bif/event.bif ## BPF filter the user has set via the -f command line options. Empty if none. const cmd_line_bpf_filter = "" &redef; @@ -2913,34 +2902,11 @@ const remote_trace_sync_peers = 0 &redef; ## consistency check. const remote_check_sync_consistency = F &redef; -## Analyzer tags. The core automatically defines constants -## ``ANALYZER_*``, e.g., ``ANALYZER_HTTP``. -## -## .. bro:see:: dpd_config -## -## .. todo::We should autodoc these automaticallty generated constants. -type AnalyzerTag: count; - -## Set of ports activating a particular protocol analysis. -## -## .. bro:see:: dpd_config -type dpd_protocol_config: record { - ports: set[port] &optional; ##< Set of ports. -}; - -## Port configuration for Bro's "dynamic protocol detection". Protocol -## analyzers can be activated via either well-known ports or content analysis. -## This table defines the ports. -## -## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size -## dpd_match_only_beginning dpd_ignore_ports -const dpd_config: table[AnalyzerTag] of dpd_protocol_config = {} &redef; - ## Reassemble the beginning of all TCP connections before doing ## signature-matching. Enabling this provides more accurate matching at the ## expensive of CPU cycles. ## -## .. bro:see:: dpd_config dpd_buffer_size +## .. bro:see:: dpd_buffer_size ## dpd_match_only_beginning dpd_ignore_ports ## ## .. note:: Despite the name, this option affects *all* signature matching, not @@ -2955,24 +2921,24 @@ const dpd_reassemble_first_packets = T &redef; ## activated afterwards. Then only analyzers that can deal with partial ## connections will be able to analyze the session. ## -## .. bro:see:: dpd_reassemble_first_packets dpd_config dpd_match_only_beginning +## .. bro:see:: dpd_reassemble_first_packets dpd_match_only_beginning ## dpd_ignore_ports const dpd_buffer_size = 1024 &redef; ## If true, stops signature matching if dpd_buffer_size has been reached. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size -## dpd_config dpd_ignore_ports +## dpd_ignore_ports ## ## .. note:: Despite the name, this option affects *all* signature matching, not ## only signatures used for dynamic protocol detection. const dpd_match_only_beginning = T &redef; ## If true, don't consider any ports for deciding which protocol analyzer to -## use. If so, the value of :bro:see:`dpd_config` is ignored. +## use. ## ## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size -## dpd_match_only_beginning dpd_config +## dpd_match_only_beginning const dpd_ignore_ports = F &redef; ## Ports which the core considers being likely used by servers. For ports in @@ -2980,13 +2946,6 @@ const dpd_ignore_ports = F &redef; ## connection if it misses the initial handshake. const likely_server_ports: set[port] &redef; -## Deprated. Set of all ports for which we know an analyzer, built by -## :doc:`/scripts/base/frameworks/dpd/main`. -## -## .. todo::This should be defined by :doc:`/scripts/base/frameworks/dpd/main` -## itself we still need it. -global dpd_analyzer_ports: table[port] of set[AnalyzerTag]; - ## Per-incident timer managers are drained after this amount of inactivity. const timer_mgr_inactivity_timeout = 1 min &redef; @@ -3095,10 +3054,12 @@ module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; -# Load the logging framework here because it uses fairly deep integration with +# Load BiFs defined by plugins. +@load base/bif/plugins + +# Load these frameworks here because they use fairly deep integration with # BiFs and script-land defined types. @load base/frameworks/logging - @load base/frameworks/input - +@load base/frameworks/analyzer @load base/frameworks/files diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 719842af09..dbd672073f 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -22,6 +22,7 @@ # loaded in base/init-bare.bro #@load base/frameworks/logging @load base/frameworks/notice +@load base/frameworks/analyzer @load base/frameworks/dpd @load base/frameworks/signatures @load base/frameworks/packet-filter diff --git a/scripts/base/protocols/conn/inactivity.bro b/scripts/base/protocols/conn/inactivity.bro index 28df192de3..b383f1ad7c 100644 --- a/scripts/base/protocols/conn/inactivity.bro +++ b/scripts/base/protocols/conn/inactivity.bro @@ -6,9 +6,9 @@ module Conn; export { ## Define inactivity timeouts by the service detected being used over ## the connection. - const analyzer_inactivity_timeouts: table[AnalyzerTag] of interval = { + const analyzer_inactivity_timeouts: table[Analyzer::Tag] of interval = { # For interactive services, allow longer periods of inactivity. - [[ANALYZER_SSH, ANALYZER_FTP]] = 1 hrs, + [[Analyzer::ANALYZER_SSH, Analyzer::ANALYZER_FTP]] = 1 hrs, } &redef; ## Define inactivity timeouts based on common protocol ports. @@ -18,7 +18,7 @@ export { } -event protocol_confirmation(c: connection, atype: count, aid: count) +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) { if ( atype in analyzer_inactivity_timeouts ) set_inactivity_timeout(c$id, analyzer_inactivity_timeouts[atype]); diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index fd524b49cf..15da9aa7b7 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -130,19 +130,13 @@ redef capture_filters += { ["netbios-ns"] = "udp port 137", }; -const dns_ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp }; -redef dpd_config += { [ANALYZER_DNS] = [$ports = dns_ports] }; - -const dns_udp_ports = { 53/udp, 137/udp, 5353/udp, 5355/udp }; -const dns_tcp_ports = { 53/tcp }; -redef dpd_config += { [ANALYZER_DNS_UDP_BINPAC] = [$ports = dns_udp_ports] }; -redef dpd_config += { [ANALYZER_DNS_TCP_BINPAC] = [$ports = dns_tcp_ports] }; - -redef likely_server_ports += { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp }; +const ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp }; +redef likely_server_ports += { ports }; event bro_init() &priority=5 { Log::create_stream(DNS::LOG, [$columns=Info, $ev=log_dns]); + Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, ports); } function new_session(c: connection, trans_id: count): Info diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index 7e2a1200cc..88e1fbeeb8 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -1,6 +1,6 @@ ##! The logging this script does is primarily focused on logging FTP commands ##! 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. @load ./utils-commands @@ -13,16 +13,16 @@ module FTP; export { ## The FTP protocol logging stream identifier. redef enum Log::ID += { LOG }; - + ## List of commands that should have their command/response pairs logged. const logged_commands = { "APPE", "DELE", "RETR", "STOR", "STOU", "ACCT", "PORT", "PASV", "EPRT", "EPSV" } &redef; - + ## This setting changes if passwords used in FTP sessions are captured or not. const default_capture_password = F &redef; - + ## User IDs that can be considered "anonymous". 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. resp_p: port &log; }; - + type Info: record { ## Time when the command was sent. ts: time &log; @@ -53,12 +53,12 @@ export { command: string &log &optional; ## Argument for the command if one is given. arg: string &log &optional; - + ## Libmagic "sniffed" file type if the command indicates a file transfer. mime_type: string &log &optional; ## Size of the file if the command indicates a file transfer. file_size: count &log &optional; - + ## Reply code from the server in response to the command. reply_code: count &log &optional; ## Reply message from the server in response to the command. @@ -74,31 +74,31 @@ export { ## more concrete is discovered that the existing but unknown ## directory is ok to use. cwd: string &default="."; - + ## Command that is currently waiting for a response. 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. pending_commands: PendingCmds; - + ## Indicates if the session is in active or passive mode. passive: bool &default=F; - + ## Determines if the password will be captured for this request. 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. type ReplyCode: record { x: count; y: count; z: count; }; - + ## Parse FTP reply codes into the three constituent single digit values. global parse_ftp_reply_code: function(code: count): ReplyCode; - + ## Event that can be handled to access the :bro:type:`FTP::Info` ## record as it is sent on to the logging framework. global log_ftp: event(rec: Info); @@ -111,11 +111,10 @@ redef record connection += { }; # Configure DPD -const ports = { 21/tcp, 2811/tcp } &redef; # 2811/tcp is GridFTP. redef capture_filters += { ["ftp"] = "port 21 and port 2811" }; -redef dpd_config += { [ANALYZER_FTP] = [$ports = ports] }; -redef likely_server_ports += { 21/tcp, 2811/tcp }; +const ports = { 21/tcp, 2811/tcp }; +redef likely_server_ports += { ports }; # Establish the variable for tracking expected connections. global ftp_data_expected: table[addr, port] of Info &read_expire=5mins; @@ -123,6 +122,7 @@ global ftp_data_expected: table[addr, port] of Info &read_expire=5mins; event bro_init() &priority=5 { Log::create_stream(FTP::LOG, [$columns=Info, $ev=log_ftp]); + Analyzer::register_for_ports(Analyzer::ANALYZER_FTP, ports); } ## A set of commands where the argument can be expected to refer @@ -166,7 +166,7 @@ function set_ftp_session(c: connection) s$uid=c$uid; s$id=c$id; c$ftp=s; - + # Add a shim command so the server can respond with some init response. add_pending_cmd(c$ftp$pending_commands, "", ""); } @@ -178,13 +178,13 @@ function ftp_message(s: Info) # or it's a deliberately logged command. if ( |s$tags| > 0 || (s?$cmdarg && s$cmdarg$cmd in logged_commands) ) { - if ( s?$password && - ! s$capture_password && + if ( s?$password && + ! s$capture_password && to_lower(s$user) !in guest_ids ) { s$password = ""; } - + local arg = s$cmdarg$arg; 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); } - + s$ts=s$cmdarg$ts; s$command=s$cmdarg$cmd; if ( arg == "" ) @@ -204,9 +204,9 @@ function ftp_message(s: Info) Log::write(FTP::LOG, s); } - - # 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" + + # 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" # values after logging. delete s$mime_type; delete s$file_size; @@ -221,8 +221,8 @@ function add_expected_data_channel(s: Info, chan: ExpectedDataChannel) s$passive = chan$passive; s$data_channel = chan; ftp_data_expected[chan$resp_h, chan$resp_p] = s; - expect_connection(chan$orig_h, chan$resp_h, chan$resp_p, ANALYZER_FTP_DATA, - 5mins); + Analyzer::schedule_analyzer(chan$orig_h, chan$resp_h, chan$resp_p, Analyzer::ANALYZER_FTP_DATA, + 5mins); } 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); ftp_message(c$ftp); } - + local id = c$id; set_ftp_session(c); - + # Queue up the new command and argument add_pending_cmd(c$ftp$pending_commands, command, arg); - + if ( command == "USER" ) c$ftp$user = arg; - + else if ( command == "PASS" ) c$ftp$password = arg; - + else if ( command == "PORT" || command == "EPRT" ) { 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) if ( cont_resp ) return; - + # TODO: do some sort of generic clear text login processing here. local response_xyz = parse_ftp_reply_code(code); #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. c$ftp$file_size = extract_count(msg); } - + # PASV and EPSV processing else if ( (code == 227 || code == 229) && (c$ftp$cmdarg$cmd == "PASV" || c$ftp$cmdarg$cmd == "EPSV") ) { local data = (code == 227) ? parse_ftp_pasv(msg) : parse_ftp_epsv(msg); - + if ( data$valid ) { c$ftp$passive=T; - + if ( code == 229 && data$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" ) c$ftp$cwd = extract_path(msg); } - + # 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. 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; 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 ) c$ftp_data_reuse = T; } - + event connection_state_remove(c: connection) &priority=-5 { if ( c$ftp_data_reuse ) return; diff --git a/scripts/base/protocols/http/main.bro b/scripts/base/protocols/http/main.bro index ebf412d36e..a982fdc9c6 100644 --- a/scripts/base/protocols/http/main.bro +++ b/scripts/base/protocols/http/main.bro @@ -127,29 +127,26 @@ redef record connection += { http_state: State &optional; }; -# Initialize the HTTP logging stream. -event bro_init() &priority=5 - { - Log::create_stream(HTTP::LOG, [$columns=Info, $ev=log_http]); - } - # DPD configuration. -const ports = { - 80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3128/tcp, - 8000/tcp, 8080/tcp, 8888/tcp, -}; -redef dpd_config += { - [[ANALYZER_HTTP, ANALYZER_HTTP_BINPAC]] = [$ports = ports], -}; redef capture_filters += { ["http"] = "tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888)" }; -redef likely_server_ports += { - 80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3138/tcp, +const ports = { + 80/tcp, 81/tcp, 631/tcp, 1080/tcp, 3128/tcp, 8000/tcp, 8080/tcp, 8888/tcp, }; +redef likely_server_ports += { ports }; + + +# Initialize the HTTP logging stream and ports. +event bro_init() &priority=5 + { + Log::create_stream(HTTP::LOG, [$columns=Info, $ev=log_http]); + Analyzer::register_for_ports(Analyzer::ANALYZER_HTTP, ports); + } + function code_in_range(c: count, min: count, max: count) : bool { return c >= min && c <= max; diff --git a/scripts/base/protocols/irc/dcc-send.bro b/scripts/base/protocols/irc/dcc-send.bro index afe01485a2..b79eb370e6 100644 --- a/scripts/base/protocols/irc/dcc-send.bro +++ b/scripts/base/protocols/irc/dcc-send.bro @@ -70,11 +70,11 @@ event irc_dcc_message(c: connection, is_orig: bool, c$irc$dcc_file_name = argument; c$irc$dcc_file_size = size; local p = count_to_port(dest_port, tcp); - expect_connection(to_addr("0.0.0.0"), address, p, ANALYZER_IRC_DATA, 5 min); + Analyzer::schedule_analyzer(0.0.0.0, address, p, Analyzer::ANALYZER_IRC_DATA, 5 min); dcc_expected_transfers[address, p] = c$irc; } -event expected_connection_seen(c: connection, a: count) &priority=10 +event expected_connection_seen(c: connection, a: Analyzer::Tag) &priority=10 { local id = c$id; if ( [id$resp_h, id$resp_p] in dcc_expected_transfers ) diff --git a/scripts/base/protocols/irc/main.bro b/scripts/base/protocols/irc/main.bro index 1cf542b8ea..490c39f54f 100644 --- a/scripts/base/protocols/irc/main.bro +++ b/scripts/base/protocols/irc/main.bro @@ -45,14 +45,13 @@ redef capture_filters += { ["irc-6668"] = "port 6668" }; redef capture_filters += { ["irc-6669"] = "port 6669" }; # DPD configuration. -const irc_ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp }; -redef dpd_config += { [ANALYZER_IRC] = [$ports = irc_ports] }; - -redef likely_server_ports += { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp }; +const ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp }; +redef likely_server_ports += { ports }; event bro_init() &priority=5 { Log::create_stream(IRC::LOG, [$columns=Info, $ev=irc_log]); + Analyzer::register_for_ports(Analyzer::ANALYZER_IRC, ports); } function new_session(c: connection): Info diff --git a/scripts/base/protocols/modbus/main.bro b/scripts/base/protocols/modbus/main.bro index aa11c5ce07..a418873306 100644 --- a/scripts/base/protocols/modbus/main.bro +++ b/scripts/base/protocols/modbus/main.bro @@ -31,12 +31,14 @@ redef record connection += { # Configure DPD and the packet filter. redef capture_filters += { ["modbus"] = "tcp port 502" }; -redef dpd_config += { [ANALYZER_MODBUS] = [$ports = set(502/tcp)] }; -redef likely_server_ports += { 502/tcp }; + +const ports = { 502/tcp }; +redef likely_server_ports += { ports }; event bro_init() &priority=5 { Log::create_stream(Modbus::LOG, [$columns=Info, $ev=log_modbus]); + Analyzer::register_for_ports(Analyzer::ANALYZER_MODBUS, ports); } event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool) &priority=5 diff --git a/scripts/base/protocols/smtp/main.bro b/scripts/base/protocols/smtp/main.bro index 03b3d36a24..c7b3a452d2 100644 --- a/scripts/base/protocols/smtp/main.bro +++ b/scripts/base/protocols/smtp/main.bro @@ -74,9 +74,6 @@ export { const mail_path_capture = ALL_HOSTS &redef; global log_smtp: event(rec: Info); - - ## Configure the default ports for SMTP analysis. - const ports = { 25/tcp, 587/tcp } &redef; } redef record connection += { @@ -86,13 +83,14 @@ redef record connection += { # Configure DPD redef capture_filters += { ["smtp"] = "tcp port 25 or tcp port 587" }; -redef dpd_config += { [ANALYZER_SMTP] = [$ports = ports] }; -redef likely_server_ports += { 25/tcp, 587/tcp }; +const ports = { 25/tcp, 587/tcp }; +redef likely_server_ports += { ports }; event bro_init() &priority=5 { Log::create_stream(SMTP::LOG, [$columns=SMTP::Info, $ev=log_smtp]); + Analyzer::register_for_ports(Analyzer::ANALYZER_SMTP, ports); } function find_address_in_smtp_header(header: string): string diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index df5ee69f16..a188646515 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -34,9 +34,13 @@ export { global log_socks: event(rec: Info); } +const ports = { 1080/tcp }; +redef likely_server_ports += { ports }; + event bro_init() &priority=5 { Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]); + Analyzer::register_for_ports(Analyzer::ANALYZER_SOCKS, ports); } redef record connection += { @@ -45,7 +49,6 @@ redef record connection += { # Configure DPD redef capture_filters += { ["socks"] = "tcp port 1080" }; -redef dpd_config += { [ANALYZER_SOCKS] = [$ports = set(1080/tcp)] }; redef likely_server_ports += { 1080/tcp }; function set_session(c: connection, version: count) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index d069486e67..ddd3e8b834 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -71,10 +71,11 @@ export { } # Configure DPD and the packet filter -redef capture_filters += { ["ssh"] = "tcp port 22" }; -redef dpd_config += { [ANALYZER_SSH] = [$ports = set(22/tcp)] }; -redef likely_server_ports += { 22/tcp }; +const ports = { 22/tcp }; + +redef capture_filters += { ["ssh"] = "tcp port 22" }; +redef likely_server_ports += { ports }; redef record connection += { ssh: Info &optional; @@ -83,6 +84,7 @@ redef record connection += { event bro_init() &priority=5 { Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]); + Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports); } function set_session(c: connection) @@ -116,7 +118,7 @@ function check_ssh_connection(c: connection, done: bool) # Responder must have sent fewer than 40 packets. c$resp$num_pkts < 40 && # If there was a content gap we can't reliably do this heuristic. - c?$conn && c$conn$missed_bytes == 0)# && + c?$conn && c$conn$missed_bytes == 0 )# && # Only "normal" connections can count. #c$conn?$conn_state && c$conn$conn_state in valid_states ) { @@ -176,6 +178,7 @@ event ssh_watcher(c: connection) if ( ! connection_exists(id) ) return; + lookup_connection(c$id); check_ssh_connection(c, F); if ( ! c$ssh$done ) schedule +15secs { ssh_watcher(c) }; diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index c6c4091a87..61d8d2fdb4 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -94,11 +94,6 @@ redef record Info += { delay_tokens: set[string] &optional; }; -event bro_init() &priority=5 - { - Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]); - } - redef capture_filters += { ["ssl"] = "tcp port 443", ["nntps"] = "tcp port 563", @@ -117,23 +112,15 @@ redef capture_filters += { const ports = { 443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp, 989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp -}; +} &redef; -redef dpd_config += { - [[ANALYZER_SSL]] = [$ports = ports] -}; +redef likely_server_ports += { ports }; -redef likely_server_ports += { - 443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp, - 989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp -}; - -# A queue that buffers log records. -global log_delay_queue: table[count] of Info; -# The top queue index where records are added. -global log_delay_queue_head = 0; -# The bottom queue index that points to the next record to be flushed. -global log_delay_queue_tail = 0; +event bro_init() &priority=5 + { + Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl]); + Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, ports); + } function set_session(c: connection) { @@ -144,26 +131,17 @@ function set_session(c: connection) function delay_log(info: Info, token: string) { - info$delay_tokens = set(); + if ( ! info?$delay_tokens ) + info$delay_tokens = set(); add info$delay_tokens[token]; - - log_delay_queue[log_delay_queue_head] = info; - ++log_delay_queue_head; } function undelay_log(info: Info, token: string) { - if ( token in info$delay_tokens ) + if ( info?$delay_tokens && token in info$delay_tokens ) delete info$delay_tokens[token]; } -global log_record: function(info: Info); - -event delay_logging(info: Info) - { - log_record(info); - } - function log_record(info: Info) { if ( ! info?$delay_tokens || |info$delay_tokens| == 0 ) @@ -172,26 +150,14 @@ function log_record(info: Info) } else { - for ( unused_index in log_delay_queue ) + when ( |info$delay_tokens| == 0 ) { - if ( log_delay_queue_head == log_delay_queue_tail ) - return; - if ( |log_delay_queue[log_delay_queue_tail]$delay_tokens| > 0 ) - { - if ( info$ts + max_log_delay > network_time() ) - { - schedule 1sec { delay_logging(info) }; - return; - } - 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; + log_record(info); + } + timeout max_log_delay + { + Reporter::info(fmt("SSL delay tokens not released in time (%s tokens remaining)", + |info$delay_tokens|)); } } } @@ -288,28 +254,16 @@ event ssl_established(c: connection) &priority=-5 finish(c); } -event protocol_confirmation(c: connection, atype: count, aid: count) &priority=5 +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5 { # Check by checking for existence of c$ssl record. - if ( c?$ssl && analyzer_name(atype) == "SSL" ) + if ( c?$ssl && atype == Analyzer::ANALYZER_SSL ) c$ssl$analyzer_id = aid; } -event protocol_violation(c: connection, atype: count, aid: count, +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=5 { if ( c?$ssl ) finish(c); } - -event bro_done() - { - if ( |log_delay_queue| == 0 ) - return; - for ( unused_index in log_delay_queue ) - { - Log::write(SSL::LOG, log_delay_queue[log_delay_queue_tail]); - delete log_delay_queue[log_delay_queue_tail]; - ++log_delay_queue_tail; - } - } diff --git a/scripts/base/protocols/syslog/main.bro b/scripts/base/protocols/syslog/main.bro index 61334e3f2b..7c15fb4fae 100644 --- a/scripts/base/protocols/syslog/main.bro +++ b/scripts/base/protocols/syslog/main.bro @@ -27,10 +27,9 @@ export { } redef capture_filters += { ["syslog"] = "port 514" }; -const ports = { 514/udp } &redef; -redef dpd_config += { [ANALYZER_SYSLOG_BINPAC] = [$ports = ports] }; -redef likely_server_ports += { 514/udp }; +const ports = { 514/udp }; +redef likely_server_ports += { ports }; redef record connection += { syslog: Info &optional; @@ -39,6 +38,7 @@ redef record connection += { event bro_init() &priority=5 { Log::create_stream(Syslog::LOG, [$columns=Info]); + Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, ports); } event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=5 diff --git a/scripts/policy/frameworks/dpd/detect-protocols.bro b/scripts/policy/frameworks/dpd/detect-protocols.bro index 8f4e892ce4..d50e4599ed 100644 --- a/scripts/policy/frameworks/dpd/detect-protocols.bro +++ b/scripts/policy/frameworks/dpd/detect-protocols.bro @@ -21,22 +21,22 @@ export { type dir: enum { NONE, INCOMING, OUTGOING, BOTH }; - const valids: table[count, addr, port] of dir = { + const valids: table[Analyzer::Tag, addr, port] of dir = { # A couple of ports commonly used for benign HTTP servers. # For now we want to see everything. - # [ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING, - # [ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING, + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING, # - # [ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella - # [ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella - # [ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella + # [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella } &redef; # Set of analyzers for which we suppress Server_Found notices @@ -44,8 +44,8 @@ export { # log files, this also saves memory because for these we don't # need to remember which servers we already have reported, which # for some can be a lot. - const suppress_servers: set [count] = { - # ANALYZER_HTTP + const suppress_servers: set [Analyzer::Tag] = { + # Analyzer::ANALYZER_HTTP } &redef; # We consider a connection to use a protocol X if the analyzer for X @@ -60,7 +60,7 @@ export { # Entry point for other analyzers to report that they recognized # a certain (sub-)protocol. - global found_protocol: function(c: connection, analyzer: count, + global found_protocol: function(c: connection, analyzer: Analyzer::Tag, protocol: string); # Table keeping reported (server, port, analyzer) tuples (and their @@ -70,7 +70,7 @@ export { } # Table that tracks currently active dynamic analyzers per connection. -global conns: table[conn_id] of set[count]; +global conns: table[conn_id] of set[Analyzer::Tag]; # Table of reports by other analyzers about the protocol used in a connection. global protocols: table[conn_id] of set[string]; @@ -80,7 +80,7 @@ type protocol : record { sub: string; # "sub-protocols" reported by other sources }; -function get_protocol(c: connection, a: count) : protocol +function get_protocol(c: connection, a: Analyzer::Tag) : protocol { local str = ""; if ( c$id in protocols ) @@ -89,7 +89,7 @@ function get_protocol(c: connection, a: count) : protocol str = |str| > 0 ? fmt("%s/%s", str, p) : p; } - return [$a=analyzer_name(a), $sub=str]; + return [$a=Analyzer::name(a), $sub=str]; } function fmt_protocol(p: protocol) : string @@ -97,7 +97,7 @@ function fmt_protocol(p: protocol) : string return p$sub != "" ? fmt("%s (via %s)", p$sub, p$a) : p$a; } -function do_notice(c: connection, a: count, d: dir) +function do_notice(c: connection, a: Analyzer::Tag, d: dir) { if ( d == BOTH ) return; @@ -113,7 +113,7 @@ function do_notice(c: connection, a: count, d: dir) NOTICE([$note=Protocol_Found, $msg=fmt("%s %s on port %s", id_string(c$id), s, c$id$resp_p), - $sub=s, $conn=c, $n=a]); + $sub=s, $conn=c]); # We report multiple Server_Found's per host if we find a new # sub-protocol. @@ -129,7 +129,7 @@ function do_notice(c: connection, a: count, d: dir) NOTICE([$note=Server_Found, $msg=fmt("%s: %s server on port %s%s", c$id$resp_h, s, c$id$resp_p, (known ? " (update)" : "")), - $p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h, $n=a]); + $p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h]); if ( ! known ) servers[c$id$resp_h, c$id$resp_p, p$a] = set(); @@ -194,10 +194,10 @@ event connection_state_remove(c: connection) report_protocols(c); } -event protocol_confirmation(c: connection, atype: count, aid: count) +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) { # Don't report anything running on a well-known port. - if ( atype in dpd_config && c$id$resp_p in dpd_config[atype]$ports ) + if ( c$id$resp_p in Analyzer::registered_ports(atype) ) return; if ( c$id in conns ) @@ -214,11 +214,10 @@ event protocol_confirmation(c: connection, atype: count, aid: count) } } -function found_protocol(c: connection, analyzer: count, protocol: string) +function found_protocol(c: connection, atype: Analyzer::Tag, protocol: string) { # Don't report anything running on a well-known port. - if ( analyzer in dpd_config && - c$id$resp_p in dpd_config[analyzer]$ports ) + if ( c$id$resp_p in Analyzer::registered_ports(atype) ) return; if ( c$id !in protocols ) diff --git a/scripts/policy/frameworks/dpd/packet-segment-logging.bro b/scripts/policy/frameworks/dpd/packet-segment-logging.bro index 3883cd1207..a605d84a74 100644 --- a/scripts/policy/frameworks/dpd/packet-segment-logging.bro +++ b/scripts/policy/frameworks/dpd/packet-segment-logging.bro @@ -20,7 +20,7 @@ export { } -event protocol_violation(c: connection, atype: count, aid: count, +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=4 { if ( ! c?$dpd ) return; diff --git a/scripts/policy/misc/analysis-groups.bro b/scripts/policy/misc/analysis-groups.bro deleted file mode 100644 index 17f5bab845..0000000000 --- a/scripts/policy/misc/analysis-groups.bro +++ /dev/null @@ -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); - } \ No newline at end of file diff --git a/scripts/policy/protocols/conn/known-services.bro b/scripts/policy/protocols/conn/known-services.bro index f494a30f82..4e474f76a0 100644 --- a/scripts/policy/protocols/conn/known-services.bro +++ b/scripts/policy/protocols/conn/known-services.bro @@ -87,7 +87,7 @@ function known_services_done(c: connection) event log_it(network_time(), id$resp_h, id$resp_p, c$service); } -event protocol_confirmation(c: connection, atype: count, aid: count) &priority=-5 +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=-5 { known_services_done(c); } diff --git a/scripts/test-all-policy.bro b/scripts/test-all-policy.bro index 7b349b64a3..daad03d9b6 100644 --- a/scripts/test-all-policy.bro +++ b/scripts/test-all-policy.bro @@ -31,7 +31,6 @@ @load integration/barnyard2/types.bro @load integration/collective-intel/__load__.bro @load integration/collective-intel/main.bro -@load misc/analysis-groups.bro @load misc/app-metrics.bro @load misc/capture-loss.bro @load misc/detect-traceroute/__load__.bro diff --git a/src/Analyzer.h b/src/Analyzer.h deleted file mode 100644 index 6ccd7648d3..0000000000 --- a/src/Analyzer.h +++ /dev/null @@ -1,403 +0,0 @@ -// Main analyzer interface. - -#ifndef ANALYZER_H -#define ANALYZER_H - -#include - -#include "AnalyzerTags.h" -#include "Conn.h" -#include "Obj.h" - -class DPM; -class PIA; -class Analyzer; -typedef list 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 diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h deleted file mode 100644 index 8429dec335..0000000000 --- a/src/AnalyzerTags.h +++ /dev/null @@ -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 diff --git a/src/Base64.cc b/src/Base64.cc index d3abd9b563..50732534ab 100644 --- a/src/Base64.cc +++ b/src/Base64.cc @@ -82,9 +82,7 @@ int* Base64Converter::InitBase64Table(const string& alphabet) return base64_table; } - - -Base64Converter::Base64Converter(Analyzer* arg_analyzer, const string& arg_alphabet) +Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& arg_alphabet) { if ( arg_alphabet.size() > 0 ) { diff --git a/src/Base64.h b/src/Base64.h index 8cfeffde74..d7e4384ac5 100644 --- a/src/Base64.h +++ b/src/Base64.h @@ -7,7 +7,8 @@ #include "util.h" #include "BroString.h" -#include "Analyzer.h" +#include "Reporter.h" +#include "analyzer/Analyzer.h" // Maybe we should have a base class for generic decoders? class Base64Converter { @@ -15,7 +16,7 @@ public: // is used for error reporting, and it should be zero when // the decoder is called by the built-in function decode_base64() or encode_base64(). // Empty alphabet indicates the default base64 alphabet. - Base64Converter(Analyzer* analyzer, const string& alphabet = ""); + Base64Converter(analyzer::Analyzer* analyzer, const string& alphabet = ""); ~Base64Converter(); // A note on Decode(): @@ -62,7 +63,7 @@ protected: int base64_after_padding; int* base64_table; int errored; // if true, we encountered an error - skip further processing - Analyzer* analyzer; + analyzer::Analyzer* analyzer; }; diff --git a/src/BroDoc.cc b/src/BroDoc.cc index 23b1f56aaa..c04cd92eca 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -8,6 +8,9 @@ #include "BroDoc.h" #include "BroDocObj.h" #include "util.h" +#include "plugin/Manager.h" +#include "analyzer/Manager.h" +#include "analyzer/Component.h" BroDoc::BroDoc(const std::string& rel, const std::string& abs) { @@ -35,12 +38,14 @@ BroDoc::BroDoc(const std::string& rel, const std::string& abs) downloadable_filename = source_filename; +#if 0 size_t ext_pos = downloadable_filename.find(".bif.bro"); if ( std::string::npos != ext_pos ) downloadable_filename.erase(ext_pos + 4); +#endif reST_filename = doc_title; - ext_pos = reST_filename.find(".bro"); + size_t ext_pos = reST_filename.find(".bro"); if ( std::string::npos == ext_pos ) reST_filename += ".rst"; @@ -162,84 +167,77 @@ void BroDoc::SetPacketFilter(const std::string& s) packet_filter.clear(); } -void BroDoc::AddPortAnalysis(const std::string& analyzer, - const std::string& ports) - { - std::string reST_string = analyzer + "::\n" + ports + "\n\n"; - port_analysis.push_back(reST_string); - } - void BroDoc::WriteDocFile() const { - WriteToDoc(".. Automatically generated. Do not edit.\n\n"); + WriteToDoc(reST_file, ".. Automatically generated. Do not edit.\n\n"); - WriteToDoc(":tocdepth: 3\n\n"); + WriteToDoc(reST_file, ":tocdepth: 3\n\n"); - WriteSectionHeading(doc_title.c_str(), '='); + WriteSectionHeading(reST_file, doc_title.c_str(), '='); - WriteStringList(".. bro:namespace:: %s\n", modules); + WriteStringList(reST_file, ".. bro:namespace:: %s\n", modules); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); - // WriteSectionHeading("Overview", '-'); - WriteStringList("%s\n", summary); + // WriteSectionHeading(reST_file, "Overview", '-'); + WriteStringList(reST_file, "%s\n", summary); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); if ( ! modules.empty() ) { - WriteToDoc(":Namespace%s: ", (modules.size() > 1 ? "s" : "")); - // WriteStringList(":bro:namespace:`%s`", modules); - WriteStringList("``%s``, ", "``%s``", modules); - WriteToDoc("\n"); + WriteToDoc(reST_file, ":Namespace%s: ", (modules.size() > 1 ? "s" : "")); + // WriteStringList(reST_file, ":bro:namespace:`%s`", modules); + WriteStringList(reST_file, "``%s``, ", "``%s``", modules); + WriteToDoc(reST_file, "\n"); } if ( ! imports.empty() ) { - WriteToDoc(":Imports: "); + WriteToDoc(reST_file, ":Imports: "); std::list::const_iterator it; for ( it = imports.begin(); it != imports.end(); ++it ) { if ( it != imports.begin() ) - WriteToDoc(", "); + WriteToDoc(reST_file, ", "); string pretty(*it); size_t pos = pretty.find("/index"); if ( pos != std::string::npos && pos + 6 == pretty.size() ) pretty = pretty.substr(0, pos); - WriteToDoc(":doc:`%s `", pretty.c_str(), it->c_str()); + WriteToDoc(reST_file, ":doc:`%s `", pretty.c_str(), it->c_str()); } - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); } - WriteToDoc(":Source File: :download:`%s`\n", + WriteToDoc(reST_file, ":Source File: :download:`%s`\n", downloadable_filename.c_str()); - WriteToDoc("\n"); + WriteToDoc(reST_file, "\n"); WriteInterface("Summary", '~', '#', true, true); if ( ! notices.empty() ) - WriteBroDocObjList(notices, "Notices", '#'); + WriteBroDocObjList(reST_file, notices, "Notices", '#'); if ( port_analysis.size() || packet_filter.size() ) - WriteSectionHeading("Configuration Changes", '#'); + WriteSectionHeading(reST_file, "Configuration Changes", '#'); if ( ! port_analysis.empty() ) { - WriteSectionHeading("Port Analysis", '^'); - WriteToDoc("Loading this script makes the following changes to " + WriteSectionHeading(reST_file, "Port Analysis", '^'); + WriteToDoc(reST_file, "Loading this script makes the following changes to " ":bro:see:`dpd_config`.\n\n"); - WriteStringList("%s, ", "%s", port_analysis); + WriteStringList(reST_file, "%s, ", "%s", port_analysis); } if ( ! packet_filter.empty() ) { - WriteSectionHeading("Packet Filter", '^'); - WriteToDoc("Loading this script makes the following changes to " + WriteSectionHeading(reST_file, "Packet Filter", '^'); + WriteToDoc(reST_file, "Loading this script makes the following changes to " ":bro:see:`capture_filters`.\n\n"); - WriteToDoc("Filters added::\n\n"); - WriteToDoc("%s\n", packet_filter.c_str()); + WriteToDoc(reST_file, "Filters added::\n\n"); + WriteToDoc(reST_file, "%s\n", packet_filter.c_str()); } WriteInterface("Detailed Interface", '~', '#', true, false); @@ -265,23 +263,23 @@ void BroDoc::WriteDocFile() const void BroDoc::WriteInterface(const char* heading, char underline, char sub, bool isPublic, bool isShort) const { - WriteSectionHeading(heading, underline); - WriteBroDocObjList(options, isPublic, "Options", sub, isShort); - WriteBroDocObjList(constants, isPublic, "Constants", sub, isShort); - WriteBroDocObjList(state_vars, isPublic, "State Variables", sub, isShort); - WriteBroDocObjList(types, isPublic, "Types", sub, isShort); - WriteBroDocObjList(events, isPublic, "Events", sub, isShort); - WriteBroDocObjList(hooks, isPublic, "Hooks", sub, isShort); - WriteBroDocObjList(functions, isPublic, "Functions", sub, isShort); - WriteBroDocObjList(redefs, isPublic, "Redefinitions", sub, isShort); + WriteSectionHeading(reST_file, heading, underline); + WriteBroDocObjList(reST_file, options, isPublic, "Options", sub, isShort); + WriteBroDocObjList(reST_file, constants, isPublic, "Constants", sub, isShort); + WriteBroDocObjList(reST_file, state_vars, isPublic, "State Variables", sub, isShort); + WriteBroDocObjList(reST_file, types, isPublic, "Types", sub, isShort); + WriteBroDocObjList(reST_file, events, isPublic, "Events", sub, isShort); + WriteBroDocObjList(reST_file, hooks, isPublic, "Hooks", sub, isShort); + WriteBroDocObjList(reST_file, functions, isPublic, "Functions", sub, isShort); + WriteBroDocObjList(reST_file, redefs, isPublic, "Redefinitions", sub, isShort); } -void BroDoc::WriteStringList(const char* format, const char* last_format, - const std::list& l) const +void BroDoc::WriteStringList(FILE* f, const char* format, const char* last_format, + const std::list& l) { if ( l.empty() ) { - WriteToDoc("\n"); + WriteToDoc(f, "\n"); return; } @@ -290,12 +288,12 @@ void BroDoc::WriteStringList(const char* format, const char* last_format, last--; for ( it = l.begin(); it != last; ++it ) - WriteToDoc(format, it->c_str()); + WriteToDoc(f, format, it->c_str()); - WriteToDoc(last_format, last->c_str()); + WriteToDoc(f, last_format, last->c_str()); } -void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const +void BroDoc::WriteBroDocObjTable(FILE* f, const BroDocObjList& l) { int max_id_col = 0; int max_com_col = 0; @@ -315,38 +313,38 @@ void BroDoc::WriteBroDocObjTable(const BroDocObjList& l) const } // Start table. - WriteRepeatedChar('=', max_id_col); - WriteToDoc(" "); + WriteRepeatedChar(f, '=', max_id_col); + WriteToDoc(f, " "); if ( max_com_col == 0 ) - WriteToDoc("="); + WriteToDoc(f, "="); else - WriteRepeatedChar('=', max_com_col); + WriteRepeatedChar(f, '=', max_com_col); - WriteToDoc("\n"); + WriteToDoc(f, "\n"); for ( it = l.begin(); it != l.end(); ++it ) { if ( it != l.begin() ) - WriteToDoc("\n\n"); - (*it)->WriteReSTCompact(reST_file, max_id_col); + WriteToDoc(f, "\n\n"); + (*it)->WriteReSTCompact(f, max_id_col); } // End table. - WriteToDoc("\n"); - WriteRepeatedChar('=', max_id_col); - WriteToDoc(" "); + WriteToDoc(f, "\n"); + WriteRepeatedChar(f, '=', max_id_col); + WriteToDoc(f, " "); if ( max_com_col == 0 ) - WriteToDoc("="); + WriteToDoc(f, "="); else - WriteRepeatedChar('=', max_com_col); + WriteRepeatedChar(f, '=', max_com_col); - WriteToDoc("\n\n"); + WriteToDoc(f, "\n\n"); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, - const char* heading, char underline, bool isShort) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic, + const char* heading, char underline, bool isShort) { if ( l.empty() ) return; @@ -364,7 +362,7 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, if ( it == l.end() ) return; - WriteSectionHeading(heading, underline); + WriteSectionHeading(f, heading, underline); BroDocObjList filtered_list; @@ -375,13 +373,13 @@ void BroDoc::WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, } if ( isShort ) - WriteBroDocObjTable(filtered_list); + WriteBroDocObjTable(f, filtered_list); else - WriteBroDocObjList(filtered_list); + WriteBroDocObjList(f, filtered_list); } -void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, - const char* heading, char underline, bool isShort) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic, + const char* heading, char underline, bool isShort) { BroDocObjMap::const_iterator it; BroDocObjList l; @@ -389,24 +387,24 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, for ( it = m.begin(); it != m.end(); ++it ) l.push_back(it->second); - WriteBroDocObjList(l, wantPublic, heading, underline, isShort); + WriteBroDocObjList(f, l, wantPublic, heading, underline, isShort); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l, const char* heading, - char underline) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading, + char underline) { - WriteSectionHeading(heading, underline); - WriteBroDocObjList(l); + WriteSectionHeading(f, heading, underline); + WriteBroDocObjList(f, l); } -void BroDoc::WriteBroDocObjList(const BroDocObjList& l) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjList& l) { for ( BroDocObjList::const_iterator it = l.begin(); it != l.end(); ++it ) - (*it)->WriteReST(reST_file); + (*it)->WriteReST(f); } -void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading, - char underline) const +void BroDoc::WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading, + char underline) { BroDocObjMap::const_iterator it; BroDocObjList l; @@ -414,28 +412,28 @@ void BroDoc::WriteBroDocObjList(const BroDocObjMap& m, const char* heading, for ( it = m.begin(); it != m.end(); ++it ) l.push_back(it->second); - WriteBroDocObjList(l, heading, underline); + WriteBroDocObjList(f, l, heading, underline); } -void BroDoc::WriteToDoc(const char* format, ...) const +void BroDoc::WriteToDoc(FILE* f, const char* format, ...) { va_list argp; va_start(argp, format); - vfprintf(reST_file, format, argp); + vfprintf(f, format, argp); va_end(argp); } -void BroDoc::WriteSectionHeading(const char* heading, char underline) const +void BroDoc::WriteSectionHeading(FILE* f, const char* heading, char underline) { - WriteToDoc("%s\n", heading); - WriteRepeatedChar(underline, strlen(heading)); - WriteToDoc("\n"); + WriteToDoc(f, "%s\n", heading); + WriteRepeatedChar(f, underline, strlen(heading)); + WriteToDoc(f, "\n"); } -void BroDoc::WriteRepeatedChar(char c, size_t n) const +void BroDoc::WriteRepeatedChar(FILE* f, char c, size_t n) { for ( size_t i = 0; i < n; ++i ) - WriteToDoc("%c", c); + WriteToDoc(f, "%c", c); } void BroDoc::FreeBroDocObjPtrList(BroDocObjList& l) @@ -457,3 +455,143 @@ void BroDoc::AddFunction(BroDocObj* o) else functions[o->Name()]->Combine(o); } + +static void WritePluginSectionHeading(FILE* f, const plugin::Plugin* p) + { + string name = p->Name(); + + fprintf(f, "%s\n", name.c_str()); + for ( size_t i = 0; i < name.size(); ++i ) + fprintf(f, "-"); + fprintf(f, "\n\n"); + + fprintf(f, "%s\n\n", p->Description()); + } + +static void WriteAnalyzerComponent(FILE* f, const analyzer::Component* c) + { + EnumType* atag = analyzer_mgr->GetTagEnumType(); + string tag = fmt("ANALYZER_%s", c->CanonicalName()); + + if ( atag->Lookup("Analyzer", tag.c_str()) < 0 ) + reporter->InternalError("missing analyzer tag for %s", tag.c_str()); + + fprintf(f, ":bro:enum:`Analyzer::%s`\n\n", tag.c_str()); + } + +static void WritePluginComponents(FILE* f, const plugin::Plugin* p) + { + plugin::Plugin::component_list components = p->Components(); + plugin::Plugin::component_list::const_iterator it; + + fprintf(f, "Components\n"); + fprintf(f, "++++++++++\n\n"); + + for ( it = components.begin(); it != components.end(); ++it ) + { + switch ( (*it)->Type() ) { + case plugin::component::ANALYZER: + WriteAnalyzerComponent(f, + dynamic_cast(*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* r = new list(); + 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); + } diff --git a/src/BroDoc.h b/src/BroDoc.h index 79f02b7110..9f92f821f8 100644 --- a/src/BroDoc.h +++ b/src/BroDoc.h @@ -81,15 +81,6 @@ public: */ void SetPacketFilter(const std::string& s); - /** - * Schedules documentation of a given set of ports being associated - * with a particular analyzer as a result of the current script - * being loaded -- the way the "dpd_config" table is changed. - * @param analyzer An analyzer that changed the "dpd_config" table. - * @param ports The set of ports assigned to the analyzer in table. - */ - void AddPortAnalysis(const std::string& analyzer, const std::string& ports); - /** * Schedules documentation of a script option. An option is * defined as any variable in the script that is declared 'const' @@ -242,7 +233,115 @@ public: return reST_filename.c_str(); } -protected: + typedef std::list BroDocObjList; + typedef std::map 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& l); + + /** + * @see WriteStringList(FILE* f, const char*, const char*, + * const std::list&>) + */ + static void WriteStringList(FILE* f, const char* format, + const std::list& l){ + WriteStringList(f, format, format, l); + } + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param f The file to write to. + * @param l A list of BroDocObj pointers + * @param wantPublic If true, filter out objects that are not declared + * in the global scope. If false, filter out those that are in + * the global scope. + * @param heading The title of the section to create in the reST doc. + * @param underline The character to use to underline the reST + * section heading. + * @param isShort Whether to write the full documentation or a "short" + * version (a single sentence) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, bool wantPublic, + const char* heading, char underline, + bool isShort); + + /** + * Wraps the BroDocObjMap into a BroDocObjList and the writes that list + * to the reST document + * @see WriteBroDocObjList(FILE* f, const BroDocObjList&, bool, const char*, char, + bool) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, bool wantPublic, + const char* heading, char underline, + bool isShort); + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param l A list of BroDocObj pointers + * @param heading The title of the section to create in the reST doc. + * @param underline The character to use to underline the reST + * section heading. + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l, const char* heading, + char underline); + + /** + * Writes out a list of BroDocObj objects to the reST document + * @param l A list of BroDocObj pointers + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjList& l); + + /** + * Wraps the BroDocObjMap into a BroDocObjList and the writes that list + * to the reST document + * @see WriteBroDocObjList(FILE* f, const BroDocObjList&, const char*, char) + */ + static void WriteBroDocObjList(FILE* f, const BroDocObjMap& m, const char* heading, + char underline); + + /** + * Writes out a reST section heading + * @param f The file to write to. + * @param heading The title of the heading to create + * @param underline The character to use to underline the section title + * within the reST document + */ + static void WriteSectionHeading(FILE* f, const char* heading, char underline); + +private: FILE* reST_file; std::string reST_filename; std::string source_filename; // points to the basename of source file @@ -255,9 +354,6 @@ protected: std::list imports; std::list port_analysis; - typedef std::list BroDocObjList; - typedef std::map BroDocObjMap; - BroDocObjList options; BroDocObjList constants; BroDocObjList state_vars; @@ -272,107 +368,6 @@ protected: BroDocObjList all; - /** - * Writes out a list of strings to the reST document. - * If the list is empty, prints a newline character. - * @param format A printf style format string for elements of the list - * except for the last one in the list - * @param last_format A printf style format string to use for the last - * element of the list - * @param l A reference to a list of strings - */ - void WriteStringList(const char* format, const char* last_format, - const std::list& l) const; - - /** - * @see WriteStringList(const char*, const char*, - * const std::list&>) - */ - void WriteStringList(const char* format, - const std::list& l) const - { - WriteStringList(format, format, l); - } - - - /** - * Writes out a table of BroDocObj's to the reST document - * @param l A list of BroDocObj pointers - */ - void WriteBroDocObjTable(const BroDocObjList& l) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - * @param wantPublic If true, filter out objects that are not declared - * in the global scope. If false, filter out those that are in - * the global scope. - * @param heading The title of the section to create in the reST doc. - * @param underline The character to use to underline the reST - * section heading. - * @param isShort Whether to write the full documentation or a "short" - * version (a single sentence) - */ - void WriteBroDocObjList(const BroDocObjList& l, bool wantPublic, - const char* heading, char underline, - bool isShort) const; - - /** - * Wraps the BroDocObjMap into a BroDocObjList and the writes that list - * to the reST document - * @see WriteBroDocObjList(const BroDocObjList&, bool, const char*, char, - bool) - */ - void WriteBroDocObjList(const BroDocObjMap& m, bool wantPublic, - const char* heading, char underline, - bool isShort) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - * @param heading The title of the section to create in the reST doc. - * @param underline The character to use to underline the reST - * section heading. - */ - void WriteBroDocObjList(const BroDocObjList& l, const char* heading, - char underline) const; - - /** - * Writes out a list of BroDocObj objects to the reST document - * @param l A list of BroDocObj pointers - */ - void WriteBroDocObjList(const BroDocObjList& l) const; - - /** - * Wraps the BroDocObjMap into a BroDocObjList and the writes that list - * to the reST document - * @see WriteBroDocObjList(const BroDocObjList&, const char*, char) - */ - void WriteBroDocObjList(const BroDocObjMap& m, const char* heading, - char underline) const; - - /** - * A wrapper to fprintf() that always uses the reST document - * for the FILE* argument. - * @param format A printf style format string. - */ - void WriteToDoc(const char* format, ...) const; - - /** - * Writes out a reST section heading - * @param heading The title of the heading to create - * @param underline The character to use to underline the section title - * within the reST document - */ - void WriteSectionHeading(const char* heading, char underline) const; - - /** - * Writes out given number of characters to reST document - * @param c the character to write - * @param n the number of characters to write - */ - void WriteRepeatedChar(char c, size_t n) const; - /** * Writes out the reST for either the script's public or private interface * @param heading The title of the interfaces section heading @@ -387,7 +382,6 @@ protected: */ void WriteInterface(const char* heading, char underline, char subunderline, bool isPublic, bool isShort) const; -private: /** * Frees memory allocated to BroDocObj's objects in a given list. @@ -413,4 +407,10 @@ private: }; }; +/** + * Writes out plugin index documentation for all analyzer plugins. + * @param filename the name of the file to write. + */ +void CreateProtoAnalyzerDoc(const char* filename); + #endif diff --git a/src/BroDocObj.cc b/src/BroDocObj.cc index 12753ea15d..4316b3113a 100644 --- a/src/BroDocObj.cc +++ b/src/BroDocObj.cc @@ -4,6 +4,8 @@ #include "ID.h" #include "BroDocObj.h" +map doc_ids = map(); + BroDocObj* BroDocObj::last = 0; BroDocObj::BroDocObj(const ID* id, std::list*& reST, @@ -16,6 +18,7 @@ BroDocObj::BroDocObj(const ID* id, std::list*& reST, is_fake_id = is_fake; use_role = 0; FormulateShortDesc(); + doc_ids[id->Name()] = this; } BroDocObj::~BroDocObj() diff --git a/src/BroDocObj.h b/src/BroDocObj.h index cb512f8cda..ab42dc3c94 100644 --- a/src/BroDocObj.h +++ b/src/BroDocObj.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ID.h" @@ -134,4 +135,9 @@ protected: private: }; +/** + * Map identifiers to their broxygen documentation objects. + */ +extern map doc_ids; + #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c853c301eb..e353dd4695 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,13 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ) +# This collects generated bif and pac files from subdirectories. +set(bro_ALL_GENERATED_OUTPUTS CACHE INTERNAL "automatically generated files" FORCE) + +# If TRUE, use CMake's object libraries for sub-directories instead of +# static libraries. This requires CMake >= 2.8.8. +set(bro_HAVE_OBJECT_LIBRARIES FALSE) + configure_file(version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c) configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h) @@ -100,52 +107,13 @@ target_link_libraries(bifcl) ######################################################################## ## bifcl-dependent targets -# A macro to define a command that uses the BIF compiler to produce -# C++ segments and Bro language declarations from .bif file -# The outputs are appended to list ALL_BIF_OUTPUTS -# Outputs that should be installed are appended to INSTALL_BIF_OUTPUTS -macro(BIF_TARGET bifInput) - get_bif_output_files(${bifInput} bifOutputs) - add_custom_command(OUTPUT ${bifOutputs} - COMMAND bifcl - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${bifInput} || (rm -f ${bifOutputs} && exit 1) - # In order be able to run bro from the build directory, - # the generated bro script needs to be inside a - # a directory tree named the same way it will be - # referenced from an @load. - COMMAND "${CMAKE_COMMAND}" - ARGS -E copy ${bifInput}.bro base/${bifInput}.bro - COMMAND "${CMAKE_COMMAND}" - ARGS -E remove -f ${bifInput}.bro - DEPENDS ${bifInput} - DEPENDS bifcl - COMMENT "[BIFCL] Processing ${bifInput}" - ) - list(APPEND ALL_BIF_OUTPUTS ${bifOutputs}) - list(APPEND INSTALL_BIF_OUTPUTS - ${CMAKE_CURRENT_BINARY_DIR}/base/${bifInput}.bro) -endmacro(BIF_TARGET) - -# returns a list of output files that bifcl will produce -# for given input file in ${outputFileVar} -macro(GET_BIF_OUTPUT_FILES inputFile outputFileVar) - set(${outputFileVar} - base/${inputFile}.bro - ${inputFile}.func_def - ${inputFile}.func_h - ${inputFile}.func_init - ${inputFile}.netvar_def - ${inputFile}.netvar_h - ${inputFile}.netvar_init - ) -endmacro(GET_BIF_OUTPUT_FILES) +include(BifCl) set(BIF_SRCS bro.bif logging.bif input.bif event.bif - file_analysis.bif const.bif types.bif strings.bif @@ -153,74 +121,54 @@ set(BIF_SRCS ) foreach (bift ${BIF_SRCS}) - bif_target(${bift}) + bif_target(${bift} "standard") endforeach () ######################################################################## ## BinPAC-dependent targets +include(BinPAC) + set(BINPAC_AUXSRC - binpac.pac - bro.pac - binpac_bro.h + ${CMAKE_SOURCE_DIR}/src/binpac.pac + ${CMAKE_SOURCE_DIR}/src/bro.pac + ${CMAKE_SOURCE_DIR}/src/binpac_bro.h ) -# A macro to define a command that uses the BinPac compiler to -# produce C++ code that implements a protocol parser/analyzer -# The outputs of the command are appended to list ALL_BINPAC_OUTPUTS -# All arguments to this macro are appended to list ALL_BINPAC_INPUTS -macro(BINPAC_TARGET pacFile) - get_filename_component(basename ${pacFile} NAME_WE) - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h - ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc - COMMAND ${BinPAC_EXE} - ARGS -q -d ${CMAKE_CURRENT_BINARY_DIR} - -I ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/${pacFile} - DEPENDS ${BinPAC_EXE} ${pacFile} - ${BINPAC_AUXSRC} ${ARGN} - COMMENT "[BINPAC] Processing ${pacFile}" - ) - list(APPEND ALL_BINPAC_INPUTS ${ARGV}) - list(APPEND ALL_BINPAC_OUTPUTS - ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h - ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc) -endmacro(BINPAC_TARGET) - binpac_target(binpac-lib.pac) -binpac_target(binpac_bro-lib.pac) +list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}") -binpac_target(ayiya.pac - ayiya-protocol.pac ayiya-analyzer.pac) -binpac_target(bittorrent.pac - bittorrent-protocol.pac bittorrent-analyzer.pac) -binpac_target(dce_rpc.pac - dce_rpc-protocol.pac dce_rpc-analyzer.pac epmapper.pac) -binpac_target(dce_rpc_simple.pac - dce_rpc-protocol.pac epmapper.pac) -binpac_target(dhcp.pac - dhcp-protocol.pac dhcp-analyzer.pac) -binpac_target(dns.pac - dns-protocol.pac dns-analyzer.pac) -binpac_target(dns_tcp.pac - dns.pac) -binpac_target(gtpv1.pac - gtpv1-protocol.pac gtpv1-analyzer.pac) -binpac_target(http.pac - http-protocol.pac http-analyzer.pac) -binpac_target(ncp.pac) -binpac_target(netflow.pac - netflow-protocol.pac netflow-analyzer.pac) -binpac_target(smb.pac - smb-protocol.pac smb-pipe.pac smb-mailslot.pac) -binpac_target(socks.pac - socks-protocol.pac socks-analyzer.pac) -binpac_target(ssl.pac - ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac) -binpac_target(syslog.pac - syslog-protocol.pac syslog-analyzer.pac) -binpac_target(modbus.pac - modbus-protocol.pac modbus-analyzer.pac) +binpac_target(binpac_bro-lib.pac) +list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}") + +######################################################################## +## Including subdirectories. +######################################################################## + +set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE) +set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE) + +add_subdirectory(analyzer) +add_subdirectory(file_analysis) + +set(bro_SUBDIRS + ${bro_SUBDIR_LIBS} + ${bro_PLUGIN_LIBS} +) + +if ( NOT bro_HAVE_OBJECT_LIBRARIES ) + foreach (_plugin ${bro_PLUGIN_LIBS}) + string(REGEX REPLACE "plugin-" "" _plugin "${_plugin}") + string(REGEX REPLACE "-" "_" _plugin "${_plugin}") + set(_decl "namespace plugin { namespace ${_plugin} { class Plugin; extern Plugin __plugin; } };") + set(_use "i += (size_t)(&(plugin::${_plugin}::__plugin));") + set(__BRO_DECL_PLUGINS "${__BRO_DECL_PLUGINS}${_decl}\n") + set(__BRO_USE_PLUGINS "${__BRO_USE_PLUGINS}${_use}\n") + endforeach() + + configure_file(plugins.cc.in ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc) + set(PLUGIN_INIT ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc) +endif() ######################################################################## ## bro target @@ -240,7 +188,7 @@ endif () macro(COLLECT_HEADERS _var) foreach (src ${ARGN}) get_filename_component(ext ${src} EXT) - if (${ext} STREQUAL ".cc" OR ${ext} STREQUAL ".c") + if ("${ext}" STREQUAL ".cc" OR "${ext}" STREQUAL ".c") get_filename_component(base ${src} NAME_WE) get_filename_component(dir ${src} PATH) if (NOT "${dir}") @@ -275,10 +223,8 @@ set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS set(bro_SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.c ${BIF_SRCS} - ${ALL_BIF_OUTPUTS} ${BINPAC_AUXSRC} - ${ALL_BINPAC_INPUTS} - ${ALL_BINPAC_OUTPUTS} + ${BINPAC_OUTPUTS} ${TRANSFORMED_BISON_OUTPUTS} ${FLEX_RuleScanner_OUTPUTS} ${FLEX_RuleScanner_INPUT} @@ -290,19 +236,14 @@ set(bro_SRCS ${FLEX_Scanner_INPUT} ${BISON_Parser_INPUT} ${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h + ${PLUGIN_INIT} main.cc net_util.cc util.cc module_util.cc - Analyzer.cc Anon.cc - ARP.cc Attr.cc - AYIYA.cc - BackDoor.cc Base64.cc - BitTorrent.cc - BitTorrentTracker.cc BPF_Program.cc BroDoc.cc BroDocObj.cc @@ -312,14 +253,7 @@ set(bro_SRCS ChunkedIO.cc CompHash.cc Conn.cc - ConnSizeAnalyzer.cc - ContentLine.cc - DCE_RPC.cc DFA.cc - DHCP-binpac.cc - DNS.cc - DNS-binpac.cc - DNS_Mgr.cc DbgBreakpoint.cc DbgHelp.cc DbgWatch.cc @@ -329,48 +263,29 @@ set(bro_SRCS Desc.cc Dict.cc Discard.cc - DPM.cc + DNS_Mgr.cc EquivClass.cc Event.cc EventHandler.cc EventLauncher.cc EventRegistry.cc Expr.cc - FTP.cc File.cc - FileAnalyzer.cc - Finger.cc FlowSrc.cc Frag.cc Frame.cc Func.cc - Gnutella.cc - GTPv1.cc - HTTP.cc - HTTP-binpac.cc Hash.cc - ICMP.cc ID.cc - Ident.cc IntSet.cc - InterConn.cc IOSource.cc IP.cc IPAddr.cc - IRC.cc List.cc Reporter.cc - Login.cc - MIME.cc - Modbus.cc - NCP.cc NFA.cc - NFS.cc - NTP.cc - NVT.cc Net.cc NetVar.cc - NetbiosSSN.cc Obj.cc OpaqueVal.cc OSFinger.cc @@ -378,31 +293,20 @@ set(bro_SRCS PacketSort.cc PersistenceSerializer.cc PktSrc.cc - PIA.cc PolicyFile.cc - POP3.cc - Portmap.cc PrefixTable.cc PriorityQueue.cc Queue.cc RandTest.cc RE.cc - RPC.cc Reassem.cc RemoteSerializer.cc - Rlogin.cc - RSH.cc Rule.cc RuleAction.cc RuleCondition.cc RuleMatcher.cc ScriptAnaly.cc SmithWaterman.cc - SMB.cc - SMTP.cc - SOCKS.cc - SSH.cc - SSL.cc Scope.cc SerializationFormat.cc SerialObj.cc @@ -410,24 +314,14 @@ set(bro_SRCS Sessions.cc StateAccess.cc Stats.cc - SteppingStone.cc Stmt.cc - Syslog-binpac.cc - TCP.cc - TCP_Endpoint.cc - TCP_Reassembler.cc - Telnet.cc - Teredo.cc Timer.cc Traverse.cc Trigger.cc TunnelEncapsulation.cc Type.cc - UDP.cc Val.cc Var.cc - XDR.cc - ZIP.cc bsd-getopt-long.c bro_inet_ntop.c cq.c @@ -461,29 +355,44 @@ set(bro_SRCS input/readers/Binary.cc input/readers/SQLite.cc - file_analysis/Manager.cc - file_analysis/File.cc - file_analysis/FileTimer.cc - file_analysis/Analyzer.h - file_analysis/AnalyzerSet.cc - file_analysis/Extract.cc - file_analysis/Hash.cc - file_analysis/DataEvent.cc - 3rdparty/sqlite3.c + plugin/Component.cc + plugin/Manager.cc + plugin/Plugin.cc + plugin/Macros.h + nb_dns.c digest.h ) collect_headers(bro_HEADERS ${bro_SRCS}) -add_executable(bro ${bro_SRCS} ${bro_HEADERS}) - -target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +if ( bro_HAVE_OBJECT_LIBRARIES ) + add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_SUBDIRS}) + target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +else () + add_executable(bro ${bro_SRCS} ${bro_HEADERS}) + target_link_libraries(bro ${bro_SUBDIRS} ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +endif () install(TARGETS bro DESTINATION bin) -install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base) set(BRO_EXE bro CACHE STRING "Bro executable binary" FORCE) + +# Target to create all the autogenerated files. +add_custom_target(generate_outputs) +add_dependencies(generate_outputs ${bro_ALL_GENERATED_OUTPUTS}) + +# Build __load__.bro files for plugins/*.bif.bro. +bro_bif_create_loader(bif_loader_plugins ${CMAKE_BINARY_DIR}/scripts/base/bif/plugins) +add_dependencies(bif_loader_plugins ${bro_SUBDIRS}) +add_dependencies(bro bif_loader_plugins) + +# Install *.bif.bro. +install(DIRECTORY ${CMAKE_BINARY_DIR}/scripts/base/bif DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base) + +# Make clean removes the bif directory. +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/scripts/base/bif) + diff --git a/src/Conn.cc b/src/Conn.cc index bc2e7fb5cf..fb6ca3d810 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -11,9 +11,10 @@ #include "Sessions.h" #include "Reporter.h" #include "Timer.h" -#include "PIA.h" +#include "analyzer/protocol/pia/PIA.h" #include "binpac.h" #include "TunnelEncapsulation.h" +#include "analyzer/Analyzer.h" void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) @@ -402,16 +403,21 @@ RecordVal* Connection::BuildConnVal() return conn_val; } -Analyzer* Connection::FindAnalyzer(AnalyzerID id) +analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id) { return root_analyzer ? root_analyzer->FindChild(id) : 0; } -Analyzer* Connection::FindAnalyzer(AnalyzerTag::Tag tag) +analyzer::Analyzer* Connection::FindAnalyzer(analyzer::Tag tag) { return root_analyzer ? root_analyzer->FindChild(tag) : 0; } +analyzer::Analyzer* Connection::FindAnalyzer(const char* name) + { + return root_analyzer->FindChild(name); + } + void Connection::AppendAddl(const char* str) { Unref(BuildConnVal()); @@ -540,7 +546,7 @@ Val* Connection::BuildVersionVal(const char* s, int len) } int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len, - Analyzer* analyzer) + analyzer::Analyzer* analyzer) { if ( ! software_version_found && ! software_parse_error ) return 1; @@ -578,7 +584,7 @@ int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len, } int Connection::UnparsedVersionFoundEvent(const IPAddr& addr, - const char* full, int len, Analyzer* analyzer) + const char* full, int len, analyzer::Analyzer* analyzer) { // Skip leading white space. while ( len && isspace(*full) ) @@ -602,7 +608,7 @@ int Connection::UnparsedVersionFoundEvent(const IPAddr& addr, return 1; } -void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name) +void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name) { if ( ! f ) return; @@ -615,7 +621,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name) ConnectionEvent(f, analyzer, vl); } -void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2) +void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2) { if ( ! f ) { @@ -634,7 +640,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2) ConnectionEvent(f, analyzer, vl); } -void Connection::ConnectionEvent(EventHandlerPtr f, Analyzer* a, val_list* vl) +void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_list* vl) { if ( ! f ) { @@ -929,7 +935,7 @@ error: return false; } -void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia) +void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia) { root_analyzer = analyzer; primary_PIA = pia; diff --git a/src/Conn.h b/src/Conn.h index 782d41a801..95c521d875 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -11,19 +11,22 @@ #include "Serializer.h" #include "PersistenceSerializer.h" #include "RuleMatcher.h" -#include "AnalyzerTags.h" #include "IPAddr.h" #include "TunnelEncapsulation.h" +#include "analyzer/Tag.h" +#include "analyzer/Analyzer.h" + class Connection; class ConnectionTimer; class NetSessions; class LoginConn; class RuleHdrTest; class Specific_RE_Matcher; -class TransportLayerAnalyzer; class RuleEndpointState; +namespace analyzer { class TransportLayerAnalyzer; } + typedef enum { NUL_IN_LINE, SINGULAR_CR, @@ -47,7 +50,7 @@ static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1, return addr1 < addr2 || (addr1 == addr2 && p1 < p2); } -class Analyzer; +namespace analyzer { class Analyzer; } class Connection : public BroObj { public: @@ -102,8 +105,9 @@ public: void FlipRoles(); - Analyzer* FindAnalyzer(AnalyzerID id); - Analyzer* FindAnalyzer(AnalyzerTag::Tag tag); // find first in tree. + analyzer::Analyzer* FindAnalyzer(analyzer::ID id); + analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree. + analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree. TransportProto ConnTransport() const { return proto; } @@ -161,15 +165,15 @@ public: // Raises a software_version_found event based on the // given string (returns false if it's not parseable). int VersionFoundEvent(const IPAddr& addr, const char* s, int len, - Analyzer* analyzer = 0); + analyzer::Analyzer* analyzer = 0); // Raises a software_unparsed_version_found event. int UnparsedVersionFoundEvent(const IPAddr& addr, - const char* full_descr, int len, Analyzer* analyzer); + const char* full_descr, int len, analyzer::Analyzer* analyzer); - void Event(EventHandlerPtr f, Analyzer* analyzer, const char* name = 0); - void Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2 = 0); - void ConnectionEvent(EventHandlerPtr f, Analyzer* analyzer, + void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name = 0); + void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2 = 0); + void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer, val_list* vl); void Weird(const char* name, const char* addl = ""); @@ -241,9 +245,9 @@ public: void DeleteTimer(double t); // Sets the root of the analyzer tree as well as the primary PIA. - void SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia); - TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; } - PIA* GetPrimaryPIA() { return primary_PIA; } + void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia); + analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; } + analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; } // Sets the transport protocol in use. void SetTransport(TransportProto arg_proto) { proto = arg_proto; } @@ -314,8 +318,8 @@ protected: string history; uint32 hist_seen; - TransportLayerAnalyzer* root_analyzer; - PIA* primary_PIA; + analyzer::TransportLayerAnalyzer* root_analyzer; + analyzer::pia::PIA* primary_PIA; uint64 uid; // Globally unique connection ID. }; diff --git a/src/DHCP-binpac.cc b/src/DHCP-binpac.cc deleted file mode 100644 index 2aec6e6e9f..0000000000 --- a/src/DHCP-binpac.cc +++ /dev/null @@ -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); - } diff --git a/src/DHCP-binpac.h b/src/DHCP-binpac.h deleted file mode 100644 index 06ddff3bb6..0000000000 --- a/src/DHCP-binpac.h +++ /dev/null @@ -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 diff --git a/src/DNS-binpac.cc b/src/DNS-binpac.cc deleted file mode 100644 index 999f6015c0..0000000000 --- a/src/DNS-binpac.cc +++ /dev/null @@ -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); - } diff --git a/src/DNS-binpac.h b/src/DNS-binpac.h deleted file mode 100644 index 0bbacf9192..0000000000 --- a/src/DNS-binpac.h +++ /dev/null @@ -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 diff --git a/src/DPM.cc b/src/DPM.cc deleted file mode 100644 index 611cf65c89..0000000000 --- a/src/DPM.cc +++ /dev/null @@ -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; - } - } - diff --git a/src/DPM.h b/src/DPM.h deleted file mode 100644 index f59d21dbfc..0000000000 --- a/src/DPM.h +++ /dev/null @@ -1,131 +0,0 @@ -// The central management unit for dynamic analyzer selection. - -#ifndef DPM_H -#define DPM_H - -#include - -#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 tag_list; - typedef map 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, - bool (*)(const AssignedAnalyzer*, - const AssignedAnalyzer*)> conn_queue; - conn_queue expected_conns_queue; -}; - -extern DPM* dpm; - -#endif diff --git a/src/DebugLogger.h b/src/DebugLogger.h index 5ce7230066..e293b326a8 100644 --- a/src/DebugLogger.h +++ b/src/DebugLogger.h @@ -21,7 +21,7 @@ enum DebugStream { DBG_STRING, // String code DBG_NOTIFIERS, // Notifiers (see StateAccess.h) DBG_MAINLOOP, // Main IOSource loop - DBG_DPD, // Dynamic application detection framework + DBG_ANALYZER, // Analyzer framework DBG_TM, // Time-machine packet input via Brocolli DBG_LOGGING, // Logging streams DBG_INPUT, // Input streams diff --git a/src/Event.cc b/src/Event.cc index 9dd3415eaf..d6bb0d8e58 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -13,7 +13,7 @@ int num_events_queued = 0; int num_events_dispatched = 0; Event::Event(EventHandlerPtr arg_handler, val_list* arg_args, - SourceID arg_src, AnalyzerID arg_aid, TimerMgr* arg_mgr, + SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr, BroObj* arg_obj) { handler = arg_handler; diff --git a/src/Event.h b/src/Event.h index e0ce7bf555..9d0a707cda 100644 --- a/src/Event.h +++ b/src/Event.h @@ -5,14 +5,16 @@ #include "EventRegistry.h" #include "Serializer.h" -#include "AnalyzerTags.h" + +#include "analyzer/Tag.h" +#include "analyzer/Analyzer.h" class EventMgr; class Event : public BroObj { public: Event(EventHandlerPtr handler, val_list* args, - SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0, + SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, TimerMgr* mgr = 0, BroObj* obj = 0); ~Event(); @@ -20,7 +22,7 @@ public: Event* NextEvent() const { return next_event; } SourceID Source() const { return src; } - AnalyzerID Analyzer() const { return aid; } + analyzer::ID Analyzer() const { return aid; } TimerMgr* Mgr() const { return mgr; } void Describe(ODesc* d) const; @@ -62,7 +64,7 @@ protected: EventHandlerPtr handler; val_list* args; SourceID src; - AnalyzerID aid; + analyzer::ID aid; TimerMgr* mgr; BroObj* obj; Event* next_event; @@ -77,7 +79,7 @@ public: ~EventMgr(); void QueueEvent(EventHandlerPtr h, val_list* vl, - SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0, + SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, TimerMgr* mgr = 0, BroObj* obj = 0) { if ( h ) @@ -105,7 +107,7 @@ public: // Returns the ID of the analyzer which raised the last event, or 0 if // non-analyzer event. - AnalyzerID CurrentAnalyzer() const { return current_aid; } + analyzer::ID CurrentAnalyzer() const { return current_aid; } // Returns the timer mgr associated with the last raised event. TimerMgr* CurrentTimerMgr() const { return current_mgr; } @@ -124,7 +126,7 @@ protected: Event* head; Event* tail; SourceID current_src; - AnalyzerID current_aid; + analyzer::ID current_aid; TimerMgr* current_mgr; RecordVal* src_val; bool draining; diff --git a/src/EventHandler.cc b/src/EventHandler.cc index 5598f93f98..4a74d68a08 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -10,7 +10,6 @@ EventHandler::EventHandler(const char* arg_name) used = false; local = 0; type = 0; - group = 0; error_handler = false; enabled = true; } @@ -19,7 +18,6 @@ EventHandler::~EventHandler() { Unref(local); delete [] name; - delete [] group; } EventHandler::operator bool() const diff --git a/src/EventHandler.h b/src/EventHandler.h index a86b8a285c..786d9f94ba 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -41,10 +41,6 @@ public: void SetErrorHandler() { error_handler = true; } bool ErrorHandler() { return error_handler; } - const char* Group() { return group; } - void SetGroup(const char* arg_group) - { group = copy_string(arg_group); } - void SetEnable(bool arg_enable) { enabled = arg_enable; } // We don't serialize the handler(s) itself here, but @@ -54,7 +50,6 @@ public: private: const char* name; - const char* group; Func* local; FuncType* type; bool used; // this handler is indeed used somewhere diff --git a/src/EventLauncher.cc b/src/EventLauncher.cc index 246c9dc8aa..cc32efe59e 100644 --- a/src/EventLauncher.cc +++ b/src/EventLauncher.cc @@ -1,6 +1,8 @@ #include "Val.h" -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include "EventLauncher.h" #include "Event.h" +#include "NetVar.h" +#include "Conn.h" #include "event.bif.func_def" diff --git a/src/EventRegistry.cc b/src/EventRegistry.cc index 4d29c5d95f..2da16de51d 100644 --- a/src/EventRegistry.cc +++ b/src/EventRegistry.cc @@ -80,20 +80,13 @@ void EventRegistry::PrintDebug() while ( (v = handlers.NextEntry(k, c)) ) { delete k; - fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(), - v->LocalHandler()? "local" : "no"); + fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(), + v->LocalHandler()? "local" : "no", + *v ? "active" : "not active" + ); } } -void EventRegistry::SetGroup(const char* name, const char* group) - { - EventHandler* eh = Lookup(name); - if ( ! eh ) - reporter->InternalError("unknown event handler in SetGroup()"); - - eh->SetGroup(group); - } - void EventRegistry::SetErrorHandler(const char* name) { EventHandler* eh = Lookup(name); @@ -103,18 +96,3 @@ void EventRegistry::SetErrorHandler(const char* name) eh->SetErrorHandler(); } -void EventRegistry::EnableGroup(const char* group, bool enable) - { - IterCookie* c = handlers.InitForIteration(); - - HashKey* k; - EventHandler* v; - while ( (v = handlers.NextEntry(k, c)) ) - { - delete k; - - if ( v->Group() && strcmp(v->Group(), group) == 0 ) - v->SetEnable(enable); - } - } - diff --git a/src/EventRegistry.h b/src/EventRegistry.h index 6ee5e3bcbd..3b4c8df918 100644 --- a/src/EventRegistry.h +++ b/src/EventRegistry.h @@ -26,17 +26,11 @@ public: typedef PList(constchar) string_list; string_list* Match(RE_Matcher* pattern); - // Associates a group with the given event. - void SetGroup(const char* name, const char* group); - // Marks a handler as handling errors. Error handler will not be called // recursively to avoid infinite loops in case they trigger an error // themselves. void SetErrorHandler(const char* name); - // Enable/disable all members of the group. - void EnableGroup(const char* group, bool enable); - string_list* UnusedHandlers(); string_list* UsedHandlers(); void PrintDebug(); diff --git a/src/Finger.h b/src/Finger.h deleted file mode 100644 index 3c61c4ad2a..0000000000 --- a/src/Finger.h +++ /dev/null @@ -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 diff --git a/src/FlowSrc.cc b/src/FlowSrc.cc index 59ce3fd6a4..f5fb0bd1e6 100644 --- a/src/FlowSrc.cc +++ b/src/FlowSrc.cc @@ -9,7 +9,7 @@ #include "FlowSrc.h" #include "Net.h" -#include "netflow_pac.h" +#include "analyzer/protocol/netflow/netflow_pac.h" #include FlowSrc::FlowSrc() diff --git a/src/Func.cc b/src/Func.cc index 30db27fc71..f3718fe231 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -38,7 +38,7 @@ #include "Func.h" #include "Frame.h" #include "Var.h" -#include "Login.h" +#include "analyzer/protocol/login/Login.h" #include "Sessions.h" #include "RE.h" #include "Serializer.h" @@ -553,18 +553,15 @@ void builtin_error(const char* msg, BroObj* arg) #include "input.bif.func_h" #include "reporter.bif.func_h" #include "strings.bif.func_h" -#include "file_analysis.bif.func_h" #include "bro.bif.func_def" #include "logging.bif.func_def" #include "input.bif.func_def" #include "reporter.bif.func_def" #include "strings.bif.func_def" -#include "file_analysis.bif.func_def" void init_builtin_funcs() { - ftp_port = internal_type("ftp_port")->AsRecordType(); bro_resources = internal_type("bro_resources")->AsRecordType(); net_stats = internal_type("NetStats")->AsRecordType(); matcher_stats = internal_type("matcher_stats")->AsRecordType(); @@ -576,7 +573,6 @@ void init_builtin_funcs() #include "input.bif.func_init" #include "reporter.bif.func_init" #include "strings.bif.func_init" -#include "file_analysis.bif.func_init" did_builtin_init = true; } diff --git a/src/H3.h b/src/H3.h index 9e6f1c5c35..72d81d519f 100644 --- a/src/H3.h +++ b/src/H3.h @@ -66,7 +66,6 @@ template class H3 { T byte_lookup[N][H3_BYTE_RANGE]; public: H3(); - ~H3() { free(byte_lookup); } T operator()(const void* data, size_t size, size_t offset = 0) const { const unsigned char *p = static_cast(data); diff --git a/src/HTTP-binpac.cc b/src/HTTP-binpac.cc deleted file mode 100644 index 47b2c479ec..0000000000 --- a/src/HTTP-binpac.cc +++ /dev/null @@ -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); - } diff --git a/src/HTTP-binpac.h b/src/HTTP-binpac.h deleted file mode 100644 index ef7cc7dd7d..0000000000 --- a/src/HTTP-binpac.h +++ /dev/null @@ -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 diff --git a/src/ID.cc b/src/ID.cc index 959ad9b07d..a6e592146b 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -221,21 +221,7 @@ void ID::UpdateValAttrs() if ( Type()->Tag() == TYPE_FUNC ) { - Attr* attr = attrs->FindAttr(ATTR_GROUP); - - if ( attr ) - { - Val* group = attr->AttrExpr()->ExprVal(); - if ( group ) - { - if ( group->Type()->Tag() == TYPE_STRING ) - event_registry->SetGroup(Name(), group->AsString()->CheckString()); - else - Error("&group attribute takes string"); - } - } - - attr = attrs->FindAttr(ATTR_ERROR_HANDLER); + Attr* attr = attrs->FindAttr(ATTR_ERROR_HANDLER); if ( attr ) event_registry->SetErrorHandler(Name()); diff --git a/src/ID.h b/src/ID.h index 9c1f56e80f..57e1222511 100644 --- a/src/ID.h +++ b/src/ID.h @@ -26,6 +26,7 @@ public: bool IsGlobal() const { return scope != SCOPE_FUNCTION; } bool IsExport() const { return is_export; } + void SetExport() { is_export = true; } string ModuleName() const; diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 51fb37c4d5..7fd3755042 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -5,9 +5,10 @@ #include "IPAddr.h" #include "Reporter.h" #include "Conn.h" -#include "DPM.h" #include "bro_inet_ntop.h" +#include "analyzer/Manager.h" + const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; @@ -44,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id) return new HashKey(&key, sizeof(key)); } -HashKey* BuildExpectedConnHashKey(const ExpectedConn& c) - { - struct { - in6_addr orig; - in6_addr resp; - uint16 resp_p; - uint16 proto; - } key; - - key.orig = c.orig.in6; - key.resp = c.resp.in6; - key.resp_p = c.resp_p; - key.proto = c.proto; - - return new HashKey(&key, sizeof(key)); - } - void IPAddr::Mask(int top_bits_to_keep) { if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) diff --git a/src/IPAddr.h b/src/IPAddr.h index 5ddee70fb8..cc7b2baa6e 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -14,7 +14,7 @@ #include "threading/SerialTypes.h" struct ConnID; -class ExpectedConn; +namespace analyzer { class ExpectedConn; } typedef in_addr in4_addr; @@ -363,7 +363,6 @@ public: void ConvertToThreadingValue(threading::Value::addr_t* v) const; friend HashKey* BuildConnIDHashKey(const ConnID& id); - friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); unsigned int MemoryAllocation() const { return padded_sizeof(*this); } @@ -452,11 +451,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const */ HashKey* BuildConnIDHashKey(const ConnID& id); -/** - * Returns a hash key for a given ExpectedConn instance. Passes ownership to caller. - */ -HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); - /** * Class storing both IPv4 and IPv6 prefixes * (i.e., \c 192.168.1.1/16 and \c FD00::/8. diff --git a/src/Modbus.h b/src/Modbus.h deleted file mode 100644 index 5e3294d91c..0000000000 --- a/src/Modbus.h +++ /dev/null @@ -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 diff --git a/src/NetVar.cc b/src/NetVar.cc index 3a23e4c9fa..2f50ce528b 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -94,7 +94,6 @@ RecordType* http_stats_rec; RecordType* http_message_stat; int truncate_http_URI; -int pm_request; RecordType* pm_mapping; TableType* pm_mappings; RecordType* pm_port_request; @@ -209,7 +208,6 @@ TableType* irc_join_list; RecordType* irc_join_info; TableVal* irc_servers; -TableVal* dpd_config; int dpd_reassemble_first_packets; int dpd_buffer_size; int dpd_match_only_beginning; @@ -251,7 +249,6 @@ OpaqueType* entropy_type; #include "logging.bif.netvar_def" #include "input.bif.netvar_def" #include "reporter.bif.netvar_def" -#include "file_analysis.bif.netvar_def" void init_event_handlers() { @@ -319,7 +316,6 @@ void init_net_var() #include "logging.bif.netvar_init" #include "input.bif.netvar_init" #include "reporter.bif.netvar_init" -#include "file_analysis.bif.netvar_init" conn_id = internal_type("conn_id")->AsRecordType(); endpoint = internal_type("endpoint")->AsRecordType(); @@ -423,14 +419,6 @@ void init_net_var() http_message_stat = internal_type("http_message_stat")->AsRecordType(); truncate_http_URI = opt_internal_int("truncate_http_URI"); - pm_request = pm_request_null || pm_request_set || - pm_request_unset || pm_request_getport || - pm_request_dump || pm_request_callit || - pm_attempt_null || pm_attempt_set || - pm_attempt_unset || pm_attempt_getport || - pm_attempt_dump || pm_attempt_callit || - pm_bad_port; - pm_mapping = internal_type("pm_mapping")->AsRecordType(); pm_mappings = internal_type("pm_mappings")->AsTableType(); pm_port_request = internal_type("pm_port_request")->AsRecordType(); @@ -526,7 +514,6 @@ void init_net_var() opt_internal_double("remote_trace_sync_interval"); remote_trace_sync_peers = opt_internal_int("remote_trace_sync_peers"); - dpd_config = internal_val("dpd_config")->AsTableVal(); dpd_reassemble_first_packets = opt_internal_int("dpd_reassemble_first_packets"); dpd_buffer_size = opt_internal_int("dpd_buffer_size"); diff --git a/src/NetVar.h b/src/NetVar.h index 1a20adcaf2..ac825e7845 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -97,7 +97,6 @@ extern RecordType* http_stats_rec; extern RecordType* http_message_stat; extern int truncate_http_URI; -extern int pm_request; extern RecordType* pm_mapping; extern TableType* pm_mappings; extern RecordType* pm_port_request; @@ -213,7 +212,6 @@ extern TableType* irc_join_list; extern RecordType* irc_join_info; extern TableVal* irc_servers; -extern TableVal* dpd_config; extern int dpd_reassemble_first_packets; extern int dpd_buffer_size; extern int dpd_match_only_beginning; @@ -262,6 +260,5 @@ extern void init_net_var(); #include "logging.bif.netvar_h" #include "input.bif.netvar_h" #include "reporter.bif.netvar_h" -#include "file_analysis.bif.netvar_h" #endif diff --git a/src/RuleAction.cc b/src/RuleAction.cc index bf90c0681e..a13392ee40 100644 --- a/src/RuleAction.cc +++ b/src/RuleAction.cc @@ -8,8 +8,9 @@ using std::string; #include "Conn.h" #include "Event.h" #include "NetVar.h" -#include "DPM.h" -#include "PIA.h" +#include "analyzer/protocol/pia/PIA.h" + +#include "analyzer/Manager.h" void RuleActionEvent::DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) @@ -34,42 +35,45 @@ void RuleActionEvent::PrintDebug() fprintf(stderr, " RuleActionEvent: |%s|\n", msg); } -RuleActionDPM::RuleActionDPM(const char* arg_analyzer) +RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer) { string str(arg_analyzer); string::size_type pos = str.find(':'); string arg = str.substr(0, pos); - analyzer = Analyzer::GetTag(arg.c_str()); + analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str()); + + if ( ! analyzer ) + reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str()); if ( pos != string::npos ) { arg = str.substr(pos + 1); - child_analyzer = Analyzer::GetTag(arg.c_str()); + child_analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str()); + + if ( ! child_analyzer ) + reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str()); } else - child_analyzer = AnalyzerTag::Error; - - if ( analyzer != AnalyzerTag::Error ) - dpm->ActivateSigs(); + child_analyzer = analyzer::Tag(); } -void RuleActionDPM::PrintDebug() +void RuleActionAnalyzer::PrintDebug() { - if ( child_analyzer == AnalyzerTag::Error ) - fprintf(stderr, "|%s|\n", Analyzer::GetTagName(analyzer)); + if ( ! child_analyzer ) + fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer)); else fprintf(stderr, "|%s:%s|\n", - Analyzer::GetTagName(analyzer), - Analyzer::GetTagName(child_analyzer)); + analyzer_mgr->GetAnalyzerName(analyzer), + analyzer_mgr->GetAnalyzerName(child_analyzer)); } void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) { - if ( ChildAnalyzer() == AnalyzerTag::Error ) + if ( ! ChildAnalyzer() ) { - if ( ! Analyzer::IsAvailable(Analyzer()) ) + if ( ! analyzer_mgr->IsEnabled(Analyzer()) ) return; if ( state->PIA() ) @@ -77,7 +81,7 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state, } else { - if ( ! Analyzer::IsAvailable(ChildAnalyzer()) ) + if ( ! analyzer_mgr->IsEnabled(ChildAnalyzer()) ) return; // This is ugly and works only if there exists only one @@ -90,13 +94,13 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state, void RuleActionEnable::PrintDebug() { fprintf(stderr, " RuleActionEnable: "); - RuleActionDPM::PrintDebug(); + RuleActionAnalyzer::PrintDebug(); } void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) { - if ( ChildAnalyzer() == AnalyzerTag::Error ) + if ( ! ChildAnalyzer() ) { if ( state->PIA() ) state->PIA()->DeactivateAnalyzer(Analyzer()); @@ -109,5 +113,5 @@ void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state, void RuleActionDisable::PrintDebug() { fprintf(stderr, " RuleActionDisable: "); - RuleActionDPM::PrintDebug(); + RuleActionAnalyzer::PrintDebug(); } diff --git a/src/RuleAction.h b/src/RuleAction.h index a9feb0c314..67ceadc6f1 100644 --- a/src/RuleAction.h +++ b/src/RuleAction.h @@ -1,11 +1,12 @@ #ifndef ruleaction_h #define ruleaction_h -#include "AnalyzerTags.h" #include "BroString.h" #include "List.h" #include "util.h" +#include "analyzer/Tag.h" + class Rule; class RuleEndpointState; @@ -35,29 +36,27 @@ private: const char* msg; }; -// Base class for DPM enable/disable actions. -class RuleActionDPM : public RuleAction { +// Base class for enable/disable actions. +class RuleActionAnalyzer : public RuleAction { public: - RuleActionDPM(const char* analyzer); + RuleActionAnalyzer(const char* analyzer); virtual void DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) = 0; virtual void PrintDebug(); - AnalyzerTag::Tag Analyzer() const { return analyzer; } - AnalyzerTag::Tag ChildAnalyzer() const { return child_analyzer; } + analyzer::Tag Analyzer() const { return analyzer; } + analyzer::Tag ChildAnalyzer() const { return child_analyzer; } private: - // FIXME: This is in fact an AnalyzerID but we can't include "Analyzer.h" - // at this point due to circular dependenides. Fix that! - AnalyzerTag::Tag analyzer; - AnalyzerTag::Tag child_analyzer; + analyzer::Tag analyzer; + analyzer::Tag child_analyzer; }; -class RuleActionEnable : public RuleActionDPM { +class RuleActionEnable : public RuleActionAnalyzer { public: - RuleActionEnable(const char* analyzer) : RuleActionDPM(analyzer) {} + RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {} virtual void DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len); @@ -65,9 +64,9 @@ public: virtual void PrintDebug(); }; -class RuleActionDisable : public RuleActionDPM { +class RuleActionDisable : public RuleActionAnalyzer { public: - RuleActionDisable(const char* analyzer) : RuleActionDPM(analyzer) {} + RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {} virtual void DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len); diff --git a/src/RuleCondition.cc b/src/RuleCondition.cc index 410f6a1b3e..36d8cba39d 100644 --- a/src/RuleCondition.cc +++ b/src/RuleCondition.cc @@ -1,29 +1,29 @@ #include "config.h" #include "RuleCondition.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "Scope.h" -static inline bool is_established(const TCP_Endpoint* e) +static inline bool is_established(const analyzer::tcp::TCP_Endpoint* e) { // We more or less follow Snort here: an established session // is one for which the initial handshake has succeded (but we // add partial connections). The connection tear-down is part // of the connection. - return e->state != TCP_ENDPOINT_INACTIVE && - e->state != TCP_ENDPOINT_SYN_SENT && - e->state != TCP_ENDPOINT_SYN_ACK_SENT; + return e->state != analyzer::tcp::TCP_ENDPOINT_INACTIVE && + e->state != analyzer::tcp::TCP_ENDPOINT_SYN_SENT && + e->state != analyzer::tcp::TCP_ENDPOINT_SYN_ACK_SENT; } bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state, const u_char* data, int len) { - Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer(); + analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer(); - if ( ! root || root->GetTag() != AnalyzerTag::TCP ) + if ( ! root || ! root->IsAnalyzer("TCP") ) return false; - TCP_Analyzer* ta = static_cast(root); + analyzer::tcp::TCP_Analyzer* ta = static_cast(root); if ( tcpstates & STATE_STATELESS ) return true; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index c71f86108a..5b6f673a8a 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -3,7 +3,7 @@ #include "config.h" -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include "RuleMatcher.h" #include "DFA.h" #include "NetVar.h" @@ -159,9 +159,9 @@ void RuleHdrTest::PrintDebug() fprintf(stderr, "\n"); } -RuleEndpointState::RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig, +RuleEndpointState::RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig, RuleEndpointState* arg_opposite, - ::PIA* arg_PIA) + analyzer::pia::PIA* arg_PIA) { payload_size = -1; analyzer = arg_analyzer; @@ -562,10 +562,10 @@ static inline bool compare(const vector& prefixes, const IPAddr& a, return false; } -RuleEndpointState* RuleMatcher::InitEndpoint(Analyzer* analyzer, +RuleEndpointState* RuleMatcher::InitEndpoint(analyzer::Analyzer* analyzer, const IP_Hdr* ip, int caplen, RuleEndpointState* opposite, - bool from_orig, PIA* pia) + bool from_orig, analyzer::pia::PIA* pia) { RuleEndpointState* state = new RuleEndpointState(analyzer, from_orig, opposite, pia); @@ -1300,8 +1300,8 @@ uint32 id_to_uint(const char* id) return 0; } -void RuleMatcherState::InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip, - int caplen, bool from_orig, PIA* pia) +void RuleMatcherState::InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip, + int caplen, bool from_orig, analyzer::pia::PIA* pia) { if ( ! rule_matcher ) return; diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index b8895513b4..351c3c30bf 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -35,8 +35,10 @@ extern const char* current_rule_file; class RuleMatcher; extern RuleMatcher* rule_matcher; -class Analyzer; -class PIA; +namespace analyzer { + namespace pia { class PIA; } + class Analyzer; +} // RuleHdrTest and associated things: @@ -140,7 +142,7 @@ class RuleEndpointState { public: ~RuleEndpointState(); - Analyzer* GetAnalyzer() const { return analyzer; } + analyzer::Analyzer* GetAnalyzer() const { return analyzer; } bool IsOrig() { return is_orig; } // For flipping roles. @@ -152,15 +154,15 @@ public: // Returns -1 if no chunk has been fed yet at all. int PayloadSize() { return payload_size; } - ::PIA* PIA() const { return pia; } + analyzer::pia::PIA* PIA() const { return pia; } private: friend class RuleMatcher; // Constructor is private; use RuleMatcher::InitEndpoint() // for creating an instance. - RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig, - RuleEndpointState* arg_opposite, ::PIA* arg_PIA); + RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig, + RuleEndpointState* arg_opposite, analyzer::pia::PIA* arg_PIA); struct Matcher { RE_Match_State* state; @@ -171,9 +173,9 @@ private: typedef PList(Matcher) matcher_list; bool is_orig; - Analyzer* analyzer; + analyzer::Analyzer* analyzer; RuleEndpointState* opposite; - ::PIA* pia; + analyzer::pia::PIA* pia; matcher_list matchers; rule_hdr_test_list hdr_tests; @@ -207,8 +209,8 @@ public: // the given packet (which should be the first packet encountered for // this endpoint). If the matching is triggered by an PIA, a pointer to // it needs to be given. - RuleEndpointState* InitEndpoint(Analyzer* analyzer, const IP_Hdr* ip, - int caplen, RuleEndpointState* opposite, bool is_orig, PIA* pia); + RuleEndpointState* InitEndpoint(analyzer::Analyzer* analyzer, const IP_Hdr* ip, + int caplen, RuleEndpointState* opposite, bool is_orig, analyzer::pia::PIA* pia); // Finish matching for this stream. void FinishEndpoint(RuleEndpointState* state); @@ -310,8 +312,8 @@ public: { delete orig_match_state; delete resp_match_state; } // ip may be nil. - void InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip, - int caplen, bool from_orig, PIA* pia = 0); + void InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip, + int caplen, bool from_orig, analyzer::pia::PIA* pia = 0); // bol/eol should be set to false for type Rule::PAYLOAD; they're // deduced automatically. diff --git a/src/SSH.h b/src/SSH.h deleted file mode 100644 index ccdcd76929..0000000000 --- a/src/SSH.h +++ /dev/null @@ -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 diff --git a/src/Sessions.cc b/src/Sessions.cc index 00f3bd539c..b844dc614e 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -16,22 +16,25 @@ #include "Reporter.h" #include "OSFinger.h" -#include "ICMP.h" -#include "UDP.h" +#include "analyzer/protocol/icmp/ICMP.h" +#include "analyzer/protocol/udp/UDP.h" -#include "DNS-binpac.h" -#include "HTTP-binpac.h" - -#include "SteppingStone.h" -#include "BackDoor.h" -#include "InterConn.h" +#include "analyzer/protocol/stepping-stone/SteppingStone.h" +#include "analyzer/protocol/stepping-stone/events.bif.h" +#include "analyzer/protocol/backdoor/BackDoor.h" +#include "analyzer/protocol/backdoor/events.bif.h" +#include "analyzer/protocol/interconn/InterConn.h" +#include "analyzer/protocol/interconn/events.bif.h" +#include "analyzer/protocol/arp/ARP.h" +#include "analyzer/protocol/arp/events.bif.h" #include "Discard.h" #include "RuleMatcher.h" -#include "DPM.h" #include "PacketSort.h" #include "TunnelEncapsulation.h" +#include "analyzer/Manager.h" + // These represent NetBIOS services on ephemeral ports. They're numbered // so that we can use a single int to hold either an actual TCP/UDP server // port or one of these. @@ -104,7 +107,7 @@ NetSessions::NetSessions() fragments.SetDeleteFunc(bro_obj_delete_func); if ( stp_correlate_pair ) - stp_manager = new SteppingStoneManager(); + stp_manager = new analyzer::stepping_stone::SteppingStoneManager(); else stp_manager = 0; @@ -143,7 +146,7 @@ NetSessions::NetSessions() pkt_profiler = 0; if ( arp_request || arp_reply || bad_arp ) - arp_analyzer = new ARP_Analyzer(); + arp_analyzer = new analyzer::arp::ARP_Analyzer(); else arp_analyzer = 0; } @@ -256,7 +259,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0); } - else if ( ARP_Analyzer::IsARP(pkt, hdr_size) ) + else if ( analyzer::arp::ARP_Analyzer::IsARP(pkt, hdr_size) ) { if ( arp_analyzer ) arp_analyzer->NextPacket(t, hdr, pkt, hdr_size); @@ -523,9 +526,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const struct icmp* icmpp = (const struct icmp *) data; id.src_port = icmpp->icmp_type; - id.dst_port = ICMP4_counterpart(icmpp->icmp_type, - icmpp->icmp_code, - id.is_one_way); + id.dst_port = analyzer::icmp::ICMP4_counterpart(icmpp->icmp_type, + icmpp->icmp_code, + id.is_one_way); id.src_port = htons(id.src_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; id.src_port = icmpp->icmp_type; - id.dst_port = ICMP6_counterpart(icmpp->icmp_type, - icmpp->icmp_code, - id.is_one_way); + id.dst_port = analyzer::icmp::ICMP6_counterpart(icmpp->icmp_type, + icmpp->icmp_code, + id.is_one_way); id.src_port = htons(id.src_port); id.dst_port = htons(id.dst_port); @@ -964,12 +967,12 @@ void NetSessions::Remove(Connection* c) { c->CancelTimers(); - TCP_Analyzer* ta = (TCP_Analyzer*) c->GetRootAnalyzer(); + analyzer::tcp::TCP_Analyzer* ta = (analyzer::tcp::TCP_Analyzer*) c->GetRootAnalyzer(); if ( ta && c->ConnTransport() == TRANSPORT_TCP ) { - assert(ta->GetTag() == AnalyzerTag::TCP); - TCP_Endpoint* to = ta->Orig(); - TCP_Endpoint* tr = ta->Resp(); + assert(ta->IsAnalyzer("TCP")); + analyzer::tcp::TCP_Endpoint* to = ta->Orig(); + analyzer::tcp::TCP_Endpoint* tr = ta->Resp(); tcp_stats.StateLeft(to->state, tr->state); } @@ -1178,7 +1181,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation); conn->SetTransport(tproto); - dpm->BuildInitialAnalyzerTree(tproto, conn, data); + analyzer_mgr->BuildInitialAnalyzerTree(conn); bool external = conn->IsExternal(); diff --git a/src/Sessions.h b/src/Sessions.h index abaa8b49d0..27b052ba2d 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -6,12 +6,13 @@ #include "Dict.h" #include "CompHash.h" #include "IP.h" -#include "ARP.h" #include "Frag.h" #include "PacketFilter.h" #include "Stats.h" #include "NetVar.h" #include "TunnelEncapsulation.h" +#include "analyzer/protocol/tcp/Stats.h" + #include struct pcap_pkthdr; @@ -26,11 +27,12 @@ declare(PDict,Connection); declare(PDict,FragReassembler); class Discarder; -class SteppingStoneManager; class PacketFilter; - class PacketSortElement; +namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } } +namespace analyzer { namespace arp { class ARP_Analyzer; } } + struct SessionStats { int num_TCP_conns; int num_UDP_conns; @@ -127,7 +129,7 @@ public: void ExpireTimerMgrs(); - SteppingStoneManager* GetSTPManager() { return stp_manager; } + analyzer::stepping_stone::SteppingStoneManager* GetSTPManager() { return stp_manager; } unsigned int CurrentConnections() { @@ -183,7 +185,7 @@ public: unsigned int ConnectionMemoryUsage(); unsigned int ConnectionMemoryUsageConnVals(); unsigned int MemoryAllocation(); - TCPStateStats tcp_stats; // keeps statistics on TCP states + analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states protected: friend class RemoteSerializer; @@ -255,9 +257,9 @@ protected: typedef std::map IPTunnelMap; IPTunnelMap ip_tunnels; - ARP_Analyzer* arp_analyzer; + analyzer::arp::ARP_Analyzer* arp_analyzer; - SteppingStoneManager* stp_manager; + analyzer::stepping_stone::SteppingStoneManager* stp_manager; Discarder* discarder; PacketFilter* packet_filter; OSFingerprint* SYN_OS_Fingerprinter; diff --git a/src/Stats.cc b/src/Stats.cc index 1bccb8f9be..9b839ec672 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -389,84 +389,6 @@ void SegmentProfiler::Report() reporter->SegmentProfile(name, loc, dtime, dmem); } - -TCPStateStats::TCPStateStats() - { - for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i ) - for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j ) - state_cnt[i][j] = 0; - } - -void TCPStateStats::ChangeState(EndpointState o_prev, EndpointState o_now, - EndpointState r_prev, EndpointState r_now) - { - --state_cnt[o_prev][r_prev]; - ++state_cnt[o_now][r_now]; - } - -void TCPStateStats::FlipState(EndpointState orig, EndpointState resp) - { - --state_cnt[orig][resp]; - ++state_cnt[resp][orig]; - } - -unsigned int TCPStateStats::NumStatePartial() const - { - unsigned int sum = 0; - for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i ) - { - sum += state_cnt[TCP_ENDPOINT_PARTIAL][i]; - sum += state_cnt[i][TCP_ENDPOINT_PARTIAL]; - } - - return sum; - } - -void TCPStateStats::PrintStats(BroFile* file, const char* prefix) - { - file->Write(prefix); - file->Write(" Inact. Syn. SA Part. Est. Fin. Rst.\n"); - - for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i ) - { - file->Write(prefix); - - switch ( i ) { -#define STATE_STRING(state, str) \ - case state: \ - file->Write(str); \ - break; - - STATE_STRING(TCP_ENDPOINT_INACTIVE, "Inact."); - STATE_STRING(TCP_ENDPOINT_SYN_SENT, "Syn. "); - STATE_STRING(TCP_ENDPOINT_SYN_ACK_SENT, "SA "); - STATE_STRING(TCP_ENDPOINT_PARTIAL, "Part. "); - STATE_STRING(TCP_ENDPOINT_ESTABLISHED, "Est. "); - STATE_STRING(TCP_ENDPOINT_CLOSED, "Fin. "); - STATE_STRING(TCP_ENDPOINT_RESET, "Rst. "); - - } - - file->Write(" "); - - for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j ) - { - unsigned int n = state_cnt[i][j]; - if ( n > 0 ) - { - char buf[32]; - safe_snprintf(buf, sizeof(buf), "%-8d", state_cnt[i][j]); - file->Write(buf); - } - else - file->Write(" "); - } - - file->Write("\n"); - } - } - - PacketProfiler::PacketProfiler(unsigned int mode, double freq, BroFile* arg_file) { diff --git a/src/Stats.h b/src/Stats.h index a11d66828a..8137ad16cf 100644 --- a/src/Stats.h +++ b/src/Stats.h @@ -7,9 +7,6 @@ #include #include -#include "TCP_Endpoint.h" - - // Object called by SegmentProfiler when it is done and reports its // cumulative CPU/memory statistics. class SegmentStatsReporter { @@ -121,67 +118,6 @@ extern uint64 tot_ack_bytes; extern uint64 tot_gap_events; extern uint64 tot_gap_bytes; - -// A TCPStateStats object tracks the distribution of TCP states for -// the currently active connections. -class TCPStateStats { -public: - TCPStateStats(); - ~TCPStateStats() { } - - void ChangeState(EndpointState o_prev, EndpointState o_now, - EndpointState r_prev, EndpointState r_now); - void FlipState(EndpointState orig, EndpointState resp); - - void StateEntered (EndpointState o_state, EndpointState r_state) - { ++state_cnt[o_state][r_state]; } - void StateLeft (EndpointState o_state, EndpointState r_state) - { --state_cnt[o_state][r_state]; } - - unsigned int Cnt(EndpointState state) const - { return Cnt(state, state); } - unsigned int Cnt(EndpointState state1, EndpointState state2) const - { return state_cnt[state1][state2]; } - - unsigned int NumStateEstablished() const - { return Cnt(TCP_ENDPOINT_ESTABLISHED); } - unsigned int NumStateHalfClose() const - { // corresponds to S2,S3 - return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_CLOSED) + - Cnt(TCP_ENDPOINT_CLOSED, TCP_ENDPOINT_ESTABLISHED); - } - unsigned int NumStateHalfRst() const - { - return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_RESET) + - Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_ESTABLISHED); - } - unsigned int NumStateClosed() const - { return Cnt(TCP_ENDPOINT_CLOSED); } - unsigned int NumStateRequest() const - { - assert(Cnt(TCP_ENDPOINT_INACTIVE, TCP_ENDPOINT_SYN_SENT)==0); - return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_INACTIVE); - } - unsigned int NumStateSuccRequest() const - { - return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_SYN_ACK_SENT) + - Cnt(TCP_ENDPOINT_SYN_ACK_SENT, TCP_ENDPOINT_SYN_SENT); - } - unsigned int NumStateRstRequest() const - { - return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_RESET) + - Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_SYN_SENT); - } - unsigned int NumStateInactive() const - { return Cnt(TCP_ENDPOINT_INACTIVE); } - unsigned int NumStatePartial() const; - - void PrintStats(BroFile* file, const char* prefix); - -private: - unsigned int state_cnt[TCP_ENDPOINT_RESET+1][TCP_ENDPOINT_RESET+1]; -}; - class PacketProfiler { public: PacketProfiler(unsigned int mode, double freq, BroFile* arg_file); diff --git a/src/Syslog-binpac.h b/src/Syslog-binpac.h deleted file mode 100644 index fcd75edf0e..0000000000 --- a/src/Syslog-binpac.h +++ /dev/null @@ -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 diff --git a/src/Type.cc b/src/Type.cc index 6461bf2560..917c6f46b3 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1334,6 +1334,16 @@ EnumType::EnumType(const string& arg_name) counter = 0; } +EnumType::EnumType(EnumType* e) +: BroType(TYPE_ENUM) + { + name = e->name; + counter = e->counter; + + for ( NameMap::iterator it = e->names.begin(); it != e->names.end(); ++it ) + names[copy_string(it->first)] = it->second; + } + EnumType::~EnumType() { for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter ) diff --git a/src/Type.h b/src/Type.h index bad51776d9..b10e249745 100644 --- a/src/Type.h +++ b/src/Type.h @@ -523,6 +523,7 @@ protected: class EnumType : public BroType { public: EnumType(const string& arg_name); + EnumType(EnumType* e); ~EnumType(); // The value of this name is next internal counter value, starting @@ -567,6 +568,7 @@ protected: class CommentedEnumType: public EnumType { public: CommentedEnumType(const string& arg_name) : EnumType(arg_name) {} + CommentedEnumType(EnumType* e) : EnumType(e) {} ~CommentedEnumType(); void DescribeReST(ODesc* d) const; diff --git a/src/Val.cc b/src/Val.cc index 33b2d0eacd..3e69401918 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1049,6 +1049,11 @@ StringVal::StringVal(const char* s) : Val(TYPE_STRING) val.string_val = new BroString(s); } +StringVal::StringVal(const string& s) : Val(TYPE_STRING) + { + val.string_val = new BroString(s.c_str()); + } + StringVal* StringVal::ToUpper() { val.string_val->ToUpper(); diff --git a/src/Val.h b/src/Val.h index 4b2705c5b4..019c390699 100644 --- a/src/Val.h +++ b/src/Val.h @@ -608,6 +608,7 @@ class StringVal : public Val { public: StringVal(BroString* s); StringVal(const char* s); + StringVal(const string& s); StringVal(int length, const char* s); Val* SizeVal() const diff --git a/src/Var.cc b/src/Var.cc index b7f2c77203..e85b1ba124 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -156,6 +156,12 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, if ( do_init ) { + if ( c == INIT_NONE && dt == VAR_REDEF && t->IsTable() && + init && init->Tag() == EXPR_ASSIGN ) + // e.g. 'redef foo["x"] = 1' is missing an init class, but the + // intention clearly isn't to overwrite entire existing table val. + c = INIT_EXTRA; + if ( (c == INIT_EXTRA && id->FindAttr(ATTR_ADD_FUNC)) || (c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) ) // Just apply the function. diff --git a/src/Analyzer.cc b/src/analyzer/Analyzer.cc similarity index 62% rename from src/Analyzer.cc rename to src/analyzer/Analyzer.cc index 8bb05429c1..ecd3c9f686 100644 --- a/src/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -1,191 +1,45 @@ +// See the file "COPYING" in the main distribution directory for copyright. + #include #include "Analyzer.h" -#include "PIA.h" -#include "Event.h" +#include "Manager.h" -#include "AYIYA.h" -#include "BackDoor.h" -#include "BitTorrent.h" -#include "BitTorrentTracker.h" -#include "Finger.h" -#include "InterConn.h" -#include "NTP.h" -#include "HTTP.h" -#include "HTTP-binpac.h" -#include "ICMP.h" -#include "SteppingStone.h" -#include "IRC.h" -#include "SMTP.h" -#include "FTP.h" -#include "FileAnalyzer.h" -#include "DNS.h" -#include "DNS-binpac.h" -#include "DHCP-binpac.h" -#include "Telnet.h" -#include "Rlogin.h" -#include "RSH.h" -#include "DCE_RPC.h" -#include "Gnutella.h" -#include "Ident.h" -#include "Modbus.h" -#include "NCP.h" -#include "NetbiosSSN.h" -#include "SMB.h" -#include "NFS.h" -#include "Portmap.h" -#include "POP3.h" -#include "SOCKS.h" -#include "SSH.h" -#include "SSL.h" -#include "Syslog-binpac.h" -#include "Teredo.h" -#include "ConnSizeAnalyzer.h" -#include "GTPv1.h" +#include "analyzer/protocol/pia/PIA.h" +#include "../Event.h" -// Keep same order here as in AnalyzerTag definition! -const Analyzer::Config Analyzer::analyzer_configs[] = { - { AnalyzerTag::Error, "", 0, 0, 0, false }, +namespace analyzer { - { AnalyzerTag::PIA_TCP, "PIA_TCP", PIA_TCP::InstantiateAnalyzer, - PIA_TCP::Available, 0, false }, - { AnalyzerTag::PIA_UDP, "PIA_UDP", PIA_UDP::InstantiateAnalyzer, - PIA_UDP::Available, 0, false }, +class AnalyzerTimer : public Timer { +public: + AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer, + double arg_t, int arg_do_expire, TimerType arg_type); - { AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer, - ICMP_Analyzer::Available, 0, false }, + virtual ~AnalyzerTimer(); - { AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer, - TCP_Analyzer::Available, 0, false }, - { AnalyzerTag::UDP, "UDP", UDP_Analyzer::InstantiateAnalyzer, - UDP_Analyzer::Available, 0, false }, + void Dispatch(double t, int is_expire); - { AnalyzerTag::BitTorrent, "BITTORRENT", - BitTorrent_Analyzer::InstantiateAnalyzer, - BitTorrent_Analyzer::Available, 0, false }, - { AnalyzerTag::BitTorrentTracker, "BITTORRENTTRACKER", - BitTorrentTracker_Analyzer::InstantiateAnalyzer, - BitTorrentTracker_Analyzer::Available, 0, false }, - { AnalyzerTag::DCE_RPC, "DCE_RPC", - DCE_RPC_Analyzer::InstantiateAnalyzer, - DCE_RPC_Analyzer::Available, 0, false }, - { AnalyzerTag::DNS, "DNS", DNS_Analyzer::InstantiateAnalyzer, - DNS_Analyzer::Available, 0, false }, - { AnalyzerTag::Finger, "FINGER", Finger_Analyzer::InstantiateAnalyzer, - Finger_Analyzer::Available, 0, false }, - { AnalyzerTag::FTP, "FTP", FTP_Analyzer::InstantiateAnalyzer, - FTP_Analyzer::Available, 0, false }, - { AnalyzerTag::Gnutella, "GNUTELLA", - Gnutella_Analyzer::InstantiateAnalyzer, - Gnutella_Analyzer::Available, 0, false }, - { AnalyzerTag::HTTP, "HTTP", HTTP_Analyzer::InstantiateAnalyzer, - HTTP_Analyzer::Available, 0, false }, - { AnalyzerTag::Ident, "IDENT", Ident_Analyzer::InstantiateAnalyzer, - Ident_Analyzer::Available, 0, false }, - { AnalyzerTag::IRC, "IRC", IRC_Analyzer::InstantiateAnalyzer, - IRC_Analyzer::Available, 0, false }, - { AnalyzerTag::Login, "LOGIN", 0, 0, 0, false }, // just a base class - { AnalyzerTag::NCP, "NCP", NCP_Analyzer::InstantiateAnalyzer, - NCP_Analyzer::Available, 0, false }, - { AnalyzerTag::NetbiosSSN, "NetbiosSSN", - NetbiosSSN_Analyzer::InstantiateAnalyzer, - NetbiosSSN_Analyzer::Available, 0, false }, - { AnalyzerTag::NFS, "NFS", NFS_Analyzer::InstantiateAnalyzer, - NFS_Analyzer::Available, 0, false }, - { AnalyzerTag::NTP, "NTP", NTP_Analyzer::InstantiateAnalyzer, - NTP_Analyzer::Available, 0, false }, - { AnalyzerTag::POP3, "POP3", POP3_Analyzer::InstantiateAnalyzer, - POP3_Analyzer::Available, 0, false }, - { AnalyzerTag::Portmapper, "PORTMAPPER", - Portmapper_Analyzer::InstantiateAnalyzer, - Portmapper_Analyzer::Available, 0, false }, - { AnalyzerTag::Rlogin, "RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer, - Rlogin_Analyzer::Available, 0, false }, - { AnalyzerTag::RPC, "RPC", 0, 0, 0, false }, - { AnalyzerTag::Rsh, "RSH", Rsh_Analyzer::InstantiateAnalyzer, - Rsh_Analyzer::Available, 0, false }, - { AnalyzerTag::SMB, "SMB", SMB_Analyzer::InstantiateAnalyzer, - SMB_Analyzer::Available, 0, false }, - { AnalyzerTag::SMTP, "SMTP", SMTP_Analyzer::InstantiateAnalyzer, - SMTP_Analyzer::Available, 0, false }, - { AnalyzerTag::SSH, "SSH", SSH_Analyzer::InstantiateAnalyzer, - SSH_Analyzer::Available, 0, false }, - { AnalyzerTag::Telnet, "TELNET", Telnet_Analyzer::InstantiateAnalyzer, - Telnet_Analyzer::Available, 0, false }, +protected: + AnalyzerTimer() {} - { AnalyzerTag::DHCP_BINPAC, "DHCP_BINPAC", - DHCP_Analyzer_binpac::InstantiateAnalyzer, - DHCP_Analyzer_binpac::Available, 0, false }, - { AnalyzerTag::DNS_TCP_BINPAC, "DNS_TCP_BINPAC", - DNS_TCP_Analyzer_binpac::InstantiateAnalyzer, - DNS_TCP_Analyzer_binpac::Available, 0, false }, - { AnalyzerTag::DNS_UDP_BINPAC, "DNS_UDP_BINPAC", - DNS_UDP_Analyzer_binpac::InstantiateAnalyzer, - DNS_UDP_Analyzer_binpac::Available, 0, false }, - { AnalyzerTag::HTTP_BINPAC, "HTTP_BINPAC", - HTTP_Analyzer_binpac::InstantiateAnalyzer, - HTTP_Analyzer_binpac::Available, 0, false }, - { AnalyzerTag::SSL, "SSL", - SSL_Analyzer::InstantiateAnalyzer, - SSL_Analyzer::Available, 0, false }, - { AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC", - Syslog_Analyzer_binpac::InstantiateAnalyzer, - Syslog_Analyzer_binpac::Available, 0, false }, - { AnalyzerTag::Modbus, "MODBUS", - ModbusTCP_Analyzer::InstantiateAnalyzer, - ModbusTCP_Analyzer::Available, 0, false }, + void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire); - { AnalyzerTag::AYIYA, "AYIYA", - AYIYA_Analyzer::InstantiateAnalyzer, - AYIYA_Analyzer::Available, 0, false }, - { AnalyzerTag::SOCKS, "SOCKS", - SOCKS_Analyzer::InstantiateAnalyzer, - SOCKS_Analyzer::Available, 0, false }, - { AnalyzerTag::Teredo, "TEREDO", - Teredo_Analyzer::InstantiateAnalyzer, - Teredo_Analyzer::Available, 0, false }, - { AnalyzerTag::GTPv1, "GTPV1", - GTPv1_Analyzer::InstantiateAnalyzer, - GTPv1_Analyzer::Available, 0, false }, - - { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer, - File_Analyzer::Available, 0, false }, - { AnalyzerTag::IRC_Data, "IRC_DATA", IRC_Data::InstantiateAnalyzer, - IRC_Data::Available, 0, false }, - { AnalyzerTag::FTP_Data, "FTP_DATA", FTP_Data::InstantiateAnalyzer, - FTP_Data::Available, 0, false }, - { AnalyzerTag::Backdoor, "BACKDOOR", - BackDoor_Analyzer::InstantiateAnalyzer, - BackDoor_Analyzer::Available, 0, false }, - { AnalyzerTag::InterConn, "INTERCONN", - InterConn_Analyzer::InstantiateAnalyzer, - InterConn_Analyzer::Available, 0, false }, - { AnalyzerTag::SteppingStone, "STEPPINGSTONE", - SteppingStone_Analyzer::InstantiateAnalyzer, - SteppingStone_Analyzer::Available, 0, false }, - { AnalyzerTag::TCPStats, "TCPSTATS", - TCPStats_Analyzer::InstantiateAnalyzer, - TCPStats_Analyzer::Available, 0, false }, - { AnalyzerTag::ConnSize, "CONNSIZE", - ConnSize_Analyzer::InstantiateAnalyzer, - ConnSize_Analyzer::Available, 0, false }, - - { AnalyzerTag::Contents, "CONTENTS", 0, 0, 0, false }, - { AnalyzerTag::ContentLine, "CONTENTLINE", 0, 0, 0, false }, - { AnalyzerTag::NVT, "NVT", 0, 0, 0, false }, - { AnalyzerTag::Zip, "ZIP", 0, 0, 0, false }, - { AnalyzerTag::Contents_DNS, "CONTENTS_DNS", 0, 0, 0, false }, - { AnalyzerTag::Contents_NetbiosSSN, "CONTENTS_NETBIOSSSN", 0, 0, 0, false }, - { AnalyzerTag::Contents_NCP, "CONTENTS_NCP", 0, 0, 0, false }, - { AnalyzerTag::Contents_Rlogin, "CONTENTS_Rlogin", 0, 0, 0, false }, - { AnalyzerTag::Contents_Rsh, "CONTENTS_RSH", 0, 0, 0, false }, - { AnalyzerTag::Contents_DCE_RPC, "CONTENTS_DCE_RPC", 0, 0, 0, false }, - { AnalyzerTag::Contents_SMB, "CONTENTS_SMB", 0, 0, 0, false }, - { AnalyzerTag::Contents_RPC, "CONTENTS_RPC", 0, 0, 0, false }, - { AnalyzerTag::Contents_NFS, "CONTENTS_NFS", 0, 0, 0, false }, - { AnalyzerTag::FTP_ADAT, "FTP_ADAT", 0, 0, 0, false }, + Analyzer* analyzer; + analyzer_timer_func timer; + int do_expire; }; +} + +using namespace analyzer; + +AnalyzerTimer::AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer, + double arg_t, int arg_do_expire, TimerType arg_type) + : Timer(arg_t, arg_type) + { + Init(arg_analyzer, arg_timer, arg_do_expire); + } + AnalyzerTimer::~AnalyzerTimer() { analyzer->RemoveTimer(this); @@ -216,36 +70,53 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer, Ref(analyzer->Conn()); } -AnalyzerID Analyzer::id_counter = 0;; +analyzer::ID Analyzer::id_counter = 0;; -Analyzer* Analyzer::InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c) +const char* Analyzer::GetAnalyzerName() const { - Analyzer* a = analyzer_configs[tag].factory(c); - assert(a); - return a; + assert(tag); + return analyzer_mgr->GetAnalyzerName(tag); } -const char* Analyzer::GetTagName(AnalyzerTag::Tag tag) +void Analyzer::SetAnalyzerTag(const Tag& arg_tag) { - return analyzer_configs[tag].name; + assert(! tag || tag == arg_tag); + tag = arg_tag; } -AnalyzerTag::Tag Analyzer::GetTag(const char* name) +bool Analyzer::IsAnalyzer(const char* name) { - for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ ) - if ( strcasecmp(analyzer_configs[i].name, name) == 0 ) - return analyzer_configs[i].tag; - - return AnalyzerTag::Error; + assert(tag); + return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0; } // Used in debugging output. static string fmt_analyzer(Analyzer* a) { - return string(a->GetTagName()) + fmt("[%d]", a->GetID()); + return string(a->GetAnalyzerName()) + fmt("[%d]", a->GetID()); } -Analyzer::Analyzer(AnalyzerTag::Tag arg_tag, Connection* arg_conn) +Analyzer::Analyzer(const char* name, Connection* conn) + { + Tag tag = analyzer_mgr->GetAnalyzerTag(name); + + if ( ! tag ) + reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name); + + CtorInit(tag, conn); + } + +Analyzer::Analyzer(const Tag& tag, Connection* conn) + { + CtorInit(tag, conn); + } + +Analyzer::Analyzer(Connection* conn) + { + CtorInit(Tag(), conn); + } + +void Analyzer::CtorInit(const Tag& arg_tag, Connection* arg_conn) { // Don't Ref conn here to avoid circular ref'ing. It can't be deleted // before us. @@ -355,11 +226,6 @@ void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq, } } -const char* Analyzer::GetTagName() const - { - return GetTagName(tag); - } - void Analyzer::NextStream(int len, const u_char* data, bool is_orig) { if ( skip ) @@ -514,7 +380,7 @@ void Analyzer::ForwardEndOfData(bool orig) void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init) { - if ( HasChildAnalyzer(analyzer->GetTag()) ) + if ( HasChildAnalyzer(analyzer->GetAnalyzerTag()) ) { analyzer->Done(); delete analyzer; @@ -533,16 +399,19 @@ void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init) if ( init ) analyzer->Init(); - DBG_LOG(DBG_DPD, "%s added child %s", + DBG_LOG(DBG_ANALYZER, "%s added child %s", fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str()); } -Analyzer* Analyzer::AddChildAnalyzer(AnalyzerTag::Tag analyzer) +Analyzer* Analyzer::AddChildAnalyzer(Tag analyzer) { if ( ! HasChildAnalyzer(analyzer) ) { - Analyzer* a = InstantiateAnalyzer(analyzer, conn); - AddChildAnalyzer(a); + Analyzer* a = analyzer_mgr->InstantiateAnalyzer(analyzer, conn); + + if ( a ) + AddChildAnalyzer(a); + return a; } @@ -554,7 +423,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer) LOOP_OVER_CHILDREN(i) if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) ) { - DBG_LOG(DBG_DPD, "%s disabling child %s", + DBG_LOG(DBG_ANALYZER, "%s disabling child %s", fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str()); // We just flag it as being removed here but postpone // actually doing that to later. Otherwise, we'd need @@ -567,12 +436,12 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer) } } -void Analyzer::RemoveChildAnalyzer(AnalyzerID id) +void Analyzer::RemoveChildAnalyzer(ID id) { LOOP_OVER_CHILDREN(i) if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) ) { - DBG_LOG(DBG_DPD, "%s disabling child %s", GetTagName(), id, + DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName(), id, fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str()); // See comment above. (*i)->removing = true; @@ -580,7 +449,7 @@ void Analyzer::RemoveChildAnalyzer(AnalyzerID id) } } -bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag) +bool Analyzer::HasChildAnalyzer(Tag tag) { LOOP_OVER_CHILDREN(i) if ( (*i)->tag == tag ) @@ -593,7 +462,7 @@ bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag) return false; } -Analyzer* Analyzer::FindChild(AnalyzerID arg_id) +Analyzer* Analyzer::FindChild(ID arg_id) { if ( id == arg_id ) return this; @@ -608,7 +477,7 @@ Analyzer* Analyzer::FindChild(AnalyzerID arg_id) return 0; } -Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag) +Analyzer* Analyzer::FindChild(Tag arg_tag) { if ( tag == arg_tag ) return this; @@ -623,6 +492,12 @@ Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag) return 0; } +Analyzer* Analyzer::FindChild(const char* name) + { + Tag tag = analyzer_mgr->GetAnalyzerTag(name); + return tag ? FindChild(tag) : 0; + } + void Analyzer::DeleteChild(analyzer_list::iterator i) { Analyzer* child = *i; @@ -636,7 +511,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i) child->removing = false; } - DBG_LOG(DBG_DPD, "%s deleted child %s 3", + DBG_LOG(DBG_ANALYZER, "%s deleted child %s 3", fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str()); children.erase(i); @@ -645,9 +520,9 @@ void Analyzer::DeleteChild(analyzer_list::iterator i) void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer) { - if ( HasSupportAnalyzer(analyzer->GetTag(), analyzer->IsOrig()) ) + if ( HasSupportAnalyzer(analyzer->GetAnalyzerTag(), analyzer->IsOrig()) ) { - DBG_LOG(DBG_DPD, "%s already has %s %s", + DBG_LOG(DBG_ANALYZER, "%s already has %s %s", fmt_analyzer(this).c_str(), analyzer->IsOrig() ? "originator" : "responder", fmt_analyzer(analyzer).c_str()); @@ -675,7 +550,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer) analyzer->Init(); - DBG_LOG(DBG_DPD, "%s added %s support %s", + DBG_LOG(DBG_ANALYZER, "%s added %s support %s", fmt_analyzer(this).c_str(), analyzer->IsOrig() ? "originator" : "responder", fmt_analyzer(analyzer).c_str()); @@ -699,7 +574,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer) else *head = s->sibling; - DBG_LOG(DBG_DPD, "%s removed support %s", + DBG_LOG(DBG_ANALYZER, "%s removed support %s", fmt_analyzer(this).c_str(), analyzer->IsOrig() ? "originator" : "responder", fmt_analyzer(analyzer).c_str()); @@ -711,7 +586,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer) return; } -bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig) +bool Analyzer::HasSupportAnalyzer(Tag tag, bool orig) { SupportAnalyzer* s = orig ? orig_supporters : resp_supporters; for ( ; s; s = s->sibling ) @@ -724,33 +599,33 @@ bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig) void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) { - DBG_LOG(DBG_DPD, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) { - DBG_LOG(DBG_DPD, "%s DeliverStream(%d, %s) [%s%s]", + DBG_LOG(DBG_ANALYZER, "%s DeliverStream(%d, %s) [%s%s]", fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } void Analyzer::Undelivered(int seq, int len, bool is_orig) { - DBG_LOG(DBG_DPD, "%s Undelivered(%d, %d, %s)", + DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)", fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F"); } void Analyzer::EndOfData(bool is_orig) { - DBG_LOG(DBG_DPD, "%s EndOfData(%s)", + DBG_LOG(DBG_ANALYZER, "%s EndOfData(%s)", fmt_analyzer(this).c_str(), is_orig ? "T" : "F"); } void Analyzer::FlipRoles() { - DBG_LOG(DBG_DPD, "%s FlipRoles()"); + DBG_LOG(DBG_ANALYZER, "%s FlipRoles()"); LOOP_OVER_CHILDREN(i) (*i)->FlipRoles(); @@ -774,9 +649,12 @@ void Analyzer::ProtocolConfirmation() if ( protocol_confirmed ) return; + EnumVal* tval = tag.AsEnumVal(); + Ref(tval); + val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(new Val(tag, TYPE_COUNT)); + vl->append(tval); vl->append(new Val(id, TYPE_COUNT)); // We immediately raise the event so that the analyzer can quickly @@ -802,9 +680,12 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len) else r = new StringVal(reason); + EnumVal* tval = tag.AsEnumVal(); + Ref(tval); + val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(new Val(tag, TYPE_COUNT)); + vl->append(tval); vl->append(new Val(id, TYPE_COUNT)); vl->append(r); @@ -876,6 +757,31 @@ void Analyzer::UpdateConnVal(RecordVal *conn_val) (*i)->UpdateConnVal(conn_val); } +RecordVal* Analyzer::BuildConnVal() + { + return conn->BuildConnVal(); + } + +void Analyzer::Event(EventHandlerPtr f, const char* name) + { + conn->Event(f, this, name); + } + +void Analyzer::Event(EventHandlerPtr f, Val* v1, Val* v2) + { + conn->Event(f, this, v1, v2); + } + +void Analyzer::ConnectionEvent(EventHandlerPtr f, val_list* vl) + { + conn->ConnectionEvent(f, this, vl); + } + +void Analyzer::Weird(const char* name, const char* addl) + { + conn->Weird(name, addl); + } + void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) { diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h new file mode 100644 index 0000000000..396d45d60e --- /dev/null +++ b/src/analyzer/Analyzer.h @@ -0,0 +1,852 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_ANALYZER_H +#define ANALYZER_ANALYZER_H + +#include + +#include "Tag.h" + +#include "../Obj.h" +#include "../EventHandler.h" +#include "../Timer.h" + +class Rule; +class Connection; +class IP_Hdr; + +namespace analyzer { + +namespace tcp { class TCP_ApplicationAnalyzer; } +namespace pia { class PIA; } + +class Analyzer; +class AnalyzerTimer; +class SupportAnalyzer; +class OutputHandler; + +typedef list analyzer_list; +typedef uint32 ID; +typedef void (Analyzer::*analyzer_timer_func)(double t); + +/** + * Class to receive processed output from an anlyzer. + */ +class OutputHandler { +public: + /** + * Destructor. + */ + virtual ~OutputHandler() { } + + /** + * Hook for receiving packet data. Parameters are the same as for + * Analyzer::DeliverPacket(). + */ + virtual void DeliverPacket(int len, const u_char* data, + bool orig, int seq, + const IP_Hdr* ip, int caplen) + { } + + /** + * Hook for receiving stream data. Parameters are the same as for + * Analyzer::DeliverStream(). + */ + virtual void DeliverStream(int len, const u_char* data, + bool orig) { } + + /** + * Hook for receiving notification of stream gaps. Parameters are the + * same as for Analyzer::Undelivered(). + */ + virtual void Undelivered(int seq, int len, bool orig) { } +}; + +/** + * 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 + * SupportAnalyzer. All analyzer input first passes through this list of + * support analyzers, which can perform arbitrary preprocessing. + * + * When overiding any of the class' methods, always make sure to call the + * base-class version first. + */ +class Analyzer { +public: + /** + * Constructor. + * + * @param name The name for the type of analyzer. The name must match + * the one the corresponding Component registers. + * + * @param conn The connection the analyzer is associated with. + */ + Analyzer(const char* name, Connection* conn); + + /** + * Constructor. + * + * @param tag The tag for the type of analyzer. The tag must map to + * the name the corresponding Component registers. + * + * @param conn The connection the analyzer is associated with. + */ + Analyzer(const Tag& tag, Connection* conn); + + /** + * Constructor. As this version of the constructor does not receive a + * name or tag, setTag() must be called before the instance can be + * used. + * + * @param conn The connection the analyzer is associated with. + */ + Analyzer(Connection* conn); + + /** + * Destructor. + */ + virtual ~Analyzer(); + + /** + * Initializes the analyzer before input processing starts. + */ + virtual void Init(); + + /** + * Finishes the analyzer's operation after all input has been parsed. + */ + virtual void Done(); + + /** + * Passes packet input to the analyzer for processing. The analyzer + * will process the input with any support analyzers first and then + * forward the data to DeliverStream(), which derived classes can + * override. + * + * Note that there is a separate method for stream input, + * NextStream(). + * + * @param len The number of bytes passed in. + * + * @param data Pointer the input to process. + * + * @param is_orig True if this is originator-side input. + * + * @param seq Current sequence number, if available (only supported + * if the data is coming from the TCP analyzer. + * + * @param ip An IP packet header associated with the data, if + * available. + * + * @param caplen The packet's capture length, if available. + */ + void NextPacket(int len, const u_char* data, bool is_orig, + int seq = -1, const IP_Hdr* ip = 0, int caplen = 0); + + /** + * Passes stream input to the analyzer for processing. The analyzer + * will process the input with any support analyzers first and then + * forward the data to DeliverStream(), which derived classes can + * override. + * + * Note that there is a separate method for packet input, + * NextPacket(). + * + * @param len The number of bytes passed in. + * + * @param data Pointer the input to process. + * + * @param is_orig True if this is originator-side input. + */ + void NextStream(int len, const u_char* data, bool is_orig); + + /** + * Informs the analyzer about a gap in the TCP stream, i.e., data + * that can't be delivered. This method triggers Undelivered(), which + * derived classes can override. + * + * @param seq The sequence number of the first byte of gap. + * + * @param len The length of the gap. + * + * @param is_orig True if this is about originator-side input. + */ + void NextUndelivered(int seq, int len, bool is_orig); + + /** + * Reports a message boundary. This is a generic method that can be + * used by an Analyzer if all data of a PDU 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. A final EndOfData() + * is automatically generated by the analyzer's Done() method. This + * method triggers EndOfData(), which derived classes can override. + * + * @param is_orig True if this is about originator-side input. + */ + void NextEndOfData(bool is_orig); + + /** + * Forwards packet input on to all child analyzers. If the analyzer + * has an associated OutputHandlers, that one receives the input as + * well. + * + * Parameters are the same as for NextPacket(). + */ + virtual void ForwardPacket(int len, const u_char* data, + bool orig, int seq, + const IP_Hdr* ip, int caplen); + + /** + * Forwards stream input on to all child analyzers. If the analyzer + * has an associated OutputHandlers, that one receives the input as + * well. + * + * Parameters are the same as for NextStream(). + */ + virtual void ForwardStream(int len, const u_char* data, bool orig); + + /** + * Forwards a sequence gap on to all child analyzers. + * + * Parameters are the same as for NextUndelivered(). + */ + virtual void ForwardUndelivered(int seq, int len, bool orig); + + /** + * Forwards an end-of-data notification on to all child analyzers. + * + * Parameters are the same as for NextPacket(). + */ + virtual void ForwardEndOfData(bool orig); + + /** + * Hook for accessing packet input for parsing. This is called by + * NextDeliverPacket() and can be overridden by derived classes. + * Parameters are the same. + */ + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + /** + * Hook for accessing stream input for parsing. This is called by + * NextDeliverStream() and can be overridden by derived classes. + * Parameters are the same. + */ + virtual void DeliverStream(int len, const u_char* data, bool orig); + + /** + * Hook for accessing input gap during parsing. This is called by + * NextUndelivered() and can be overridden by derived classes. + * Parameters are the same. + */ + virtual void Undelivered(int seq, int len, bool orig); + + /** + * Hook for accessing end-of-data notifications. This is called by + * NextEndOfData() and can be overridden by derived classes. + * Parameters are the same. + */ + virtual void EndOfData(bool is_orig); + + /** + * Signals the analyzer that its associated connection had its + * endpoint flipped. This can happen if during analysis it turns out + * 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(); + + /** + * Returns the analyzer instance's internal ID. These IDs are unique + * across all analyzer instantiated and can thus be used to indentify + * a specific instance. + */ + ID GetID() const { return id; } + + /** + * Returns the connection that the analyzer is associated with. + */ + Connection* Conn() const { return conn; } + + /** + * Returns the OutputHandler associated with the connection, or null + * if none. + */ + OutputHandler* GetOutputHandler() const { return output_handler; } + + /** + * Associates an OutputHandler with the connnection. + * + * @param handler The handler. + */ + void SetOutputHandler(OutputHandler* handler) + { output_handler = handler; } + + /** + * If this analyzer was activated by a signature match, this returns + * the signature that did so. Returns null otherwise. + */ + const Rule* Signature() const { return signature; } + + /** + * Sets the signature that activated this analyzer, if any. + * + * @param sig The signature. + */ + void SetSignature(const Rule* sig) { signature = sig; } + + /** + * Signals the analyzer to skip all further input processsing. The \a + * Next*() methods check this flag and discard the input if its set. + * + * @param do_skipe If true, further processing will be skipped. + */ + void SetSkip(bool do_skip) { skip = do_skip; } + + /** + * Returns true if the analyzer has been told to skip processing all + * further input. + */ + bool Skipping() const { return skip; } + + /** + * Returns true if Done() has been called. + */ + bool IsFinished() const { return finished; } + + /** + * Returns the tag associated with the analyzer's type. + */ + Tag GetAnalyzerTag() const { assert(tag); return tag; } + + /** + * Sets the tag associated with the analyzer's type. Note that this + * can be called only right after construction, if the constructor + * did not receive a name or tag. The method cannot be used to change + * an existing tag. + */ + void SetAnalyzerTag(const Tag& tag); + + /** + * Returns a textual description of the analyzer's type. This is + * what's passed to the constructor and usally corresponds to the + * protocol name, e.g., "HTTP". + */ + const char* GetAnalyzerName() const; + + /** + * Returns true if this analyzer's type matches the name passes in. + * This is shortcut for comparing GetAnalyzerName() with the given + * name. + * + * @param name The name to check. + */ + bool IsAnalyzer(const char* name); + + /** + * Adds a new child analyzer to the analyzer tree. If an analyzer of + * the same type already exists, the one passes in is silenty + * discarded. + * + * @param analyzer The ananlyzer to add. Takes ownership. + */ + void AddChildAnalyzer(Analyzer* analyzer) + { AddChildAnalyzer(analyzer, true); } + + /** + * Adds a new child analyzer to the analyzer tree. If an analyzer of + * the same type already exists, the one passes in is silenty + * discarded. + * + * @param tag The type of analyzer to add. + */ + Analyzer* AddChildAnalyzer(Tag tag); + + /** + * Removes a child analyzer. It's ok for the analyzer to not to be a + * child, in which case the method does nothing. + * + * @param analyzer The analyzer to remove. + */ + void RemoveChildAnalyzer(Analyzer* analyzer); + + /** + * Removes a child analyzer. It's ok for the analyzer to not to be a + * child, in which case the method does nothing. + * + * @param tag The type of analyzer to remove. + */ + void RemoveChildAnalyzer(ID id); + + /** + * Returns true if analyzer has a direct child of a given type. + * + * @param tag The type of analyzer to check for. + */ + bool HasChildAnalyzer(Tag tag); + + /** + * Recursively searches all (direct or indirect) childs of the + * analyzer for an analyzer with a specific ID. + * + * @param id The analyzer id to search. This is the ID that GetID() + * returns. + * + * @return The analyzer, or null if not found. + */ + Analyzer* FindChild(ID id); + + /** + * Recursively searches all (direct or indirect) childs of the + * analyzer for an analyzer of a given type. + * + * @param tag The analyzer type to search. + * + * @return The first analyzer of the given type found, or null if + * none. + */ + Analyzer* FindChild(Tag tag); + + /** + * Recursively searches all (direct or indirect) childs of the + * analyzer for an analyzer of a given type. + * + * @param name The naem of the analyzer type to search (e.g., + * "HTTP"). + * + * @return The first analyzer of the given type found, or null if + * none. + */ + Analyzer* FindChild(const char* name); + + /** + * Returns a list of all direct child analyzers. + */ + const analyzer_list& GetChildren() { return children; } + + /** + * Returns a pointer to the parent analyzer, or null if this instance + * has not yet been added to an analyzer tree. + */ + Analyzer* Parent() const { return parent; } + + /** + * Sets the parent analyzer. + * + * @param p The new parent. + */ + void SetParent(Analyzer* p) { parent = p; } + + /** + * Remove the analyzer form its parent. The analyzer must have a + * parent associated with it. + */ + void Remove() { assert(parent); parent->RemoveChildAnalyzer(this); } + + /** + * Appends a support analyzer to the current list. + * + * @param analyzer The support analyzer to add. + */ + void AddSupportAnalyzer(SupportAnalyzer* analyzer); + + /** + * Remove a support analyzer. + * + * @param analyzer The analyzer to remove. The function is a no-op if + * that analyzer is not part of the list of support analyzer. + */ + void RemoveSupportAnalyzer(SupportAnalyzer* analyzer); + + /** + * Signals Bro's protocol detection that the analyzer has recognized + * the input to indeed conform to the expected protocol. This should + * be called as early as possible during a connection's life-time. It + * may turn into \c protocol_confirmed event at the script-layer (but + * only once per analyzer for each connection, even if the method is + * called multiple times). + */ + virtual void ProtocolConfirmation(); + + /** + * Signals Bro's protocol detection that the analyzer has found a + * severe protocol violation that could indicate that it's not + * parsing the expected protocol. This turns into \c + * protocol_violation events at the script-layer (one such event is + * raised for each call to this method so that the script-layer can + * built up a notion of how prevalent protocol violations are; the + * more, the less likely it's the right protocol). + * + * @param reason A textual description of the error encountered. + * + * @param data An optional pointer to the malformed data. + * + * @param len If \a data is given, the length of it. + */ + virtual void ProtocolViolation(const char* reason, + const char* data = 0, int len = 0); + + /** + * Returns true if ProtocolConfirmation() has been called at least + * once. + */ + bool ProtocolConfirmed() const + { return protocol_confirmed; } + + /** + * Called whenever the connection value is 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(). + * + * @param conn_val The connenction value being updated. + */ + virtual void UpdateConnVal(RecordVal *conn_val); + + /** + * Convenience function that forwards directly to + * Connection::BuildConnVal(). + */ + RecordVal* BuildConnVal(); + + /** + * Convenience function that forwards directly to the corresponding + * Connection::Event(). + */ + void Event(EventHandlerPtr f, const char* name = 0); + + /** + * Convenience function that forwards directly to the corresponding + * Connection::Event(). + */ + void Event(EventHandlerPtr f, Val* v1, Val* v2 = 0); + + /** + * Convenience function that forwards directly to + * Connection::ConnectionEvent(). + */ + void ConnectionEvent(EventHandlerPtr f, val_list* vl); + + /** + * Convenience function that forwards directly to the corresponding + * Connection::Weird(). + */ + void Weird(const char* name, const char* addl = ""); + + /** + * Internal method. + */ + virtual unsigned int MemoryAllocation() const; + +protected: + friend class AnalyzerTimer; + friend class Manager; + friend class ::Connection; + friend class tcp::TCP_ApplicationAnalyzer; + + /** + * Associates a connection with this analyzer. Must be called if + * using the default ctor. + * + * @param c The connection. + */ + void SetConnection(Connection* c) { conn = c; } + + /** + * Instantiates a new timer associated with the analyzer. + * + * @param timer The callback function to execute when the timer + * fires. + * + * @param t The absolute time when the timer will fire. + * + * @param do_expire If true, the timer will also fire when Bro + * terminates even if \a t has not been reache yet. + * + * @param type The timer's type. + */ + void AddTimer(analyzer_timer_func timer, double t, int do_expire, + TimerType type); + + /** + * Cancels all timers added previously via AddTimer(). + */ + void CancelTimers(); + + /** + * Removes a given timer. This is an internal method and shouldn't be + * used by derived class. It does not cancel the timer. + */ + void RemoveTimer(Timer* t); + + /** + * Returnsn true if the analyzer has associated an SupportAnalyzer of a given type. + * + * @param tag The type to check for. + * + * @param orig True if asking about the originator side. + */ + bool HasSupportAnalyzer(Tag tag, bool orig); + + /** + * Adds a a new child analyzer with the option whether to intialize + * it. This is an internal method. + * + * @param analyzer The analyzer to add. Takes ownership. + * + * @param init If true, Init() will be calle.d + */ + void AddChildAnalyzer(Analyzer* analyzer, bool init); + + /** + * Inits all child analyzers. This is an internal method. + */ + void InitChildren(); + + /** + * Reorganizes the child data structure. This is an internal method. + */ + void AppendNewChildren(); + +private: + // Internal method to eventually delete a child analyzer that's + // already Done(). + void DeleteChild(analyzer_list::iterator i); + + // Helper for the ctors. + void CtorInit(const Tag& tag, Connection* conn); + + Tag tag; + ID 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 ID id_counter; +}; + +/** + * Convenience macro to add a new timer. + */ +#define ADD_ANALYZER_TIMER(timer, t, do_expire, type) \ + AddTimer(analyzer::analyzer_timer_func(timer), (t), (do_expire), (type)) + +/** + * Internal convenience macro to iterate over the list of child analyzers. + */ +#define LOOP_OVER_CHILDREN(var) \ + for ( analyzer::analyzer_list::iterator var = children.begin(); \ + var != children.end(); var++ ) + +/** + * Internal convenience macro to iterate over the constant list of child + * analyzers. + */ +#define LOOP_OVER_CONST_CHILDREN(var) \ + for ( analyzer::analyzer_list::const_iterator var = children.begin(); \ + var != children.end(); var++ ) + +/** + * Convenience macro to iterate over a given list of child analyzers. + */ +#define LOOP_OVER_GIVEN_CHILDREN(var, the_kids) \ + for ( analyzer::analyzer_list::iterator var = the_kids.begin(); \ + var != the_kids.end(); var++ ) + +/** + * Convenience macro to iterate over a given constant list of child + * analyzers. + */ +#define LOOP_OVER_GIVEN_CONST_CHILDREN(var, the_kids) \ + for ( analyzer::analyzer_list::const_iterator var = the_kids.begin(); \ + var != the_kids.end(); var++ ) + +/** + * Support analyzer preprocess input before it reaches an analyzer's main + * processing. They share the input interface with of an Analyzer but they + * are uni-directional: they receive data only from one side of a connection. + * + */ +class SupportAnalyzer : public Analyzer { +public: + /** + * Constructor. + * + * @param name A name for the protocol the analyzer is parsing. The + * name must match the one the corresponding Component registers. + * + * @param conn The connection the analyzer is associated with. + * + * @param arg_orig: If true, this is a support analyzer for the + * connection originator side, and otherwise for the responder side. + */ + SupportAnalyzer(const char* name, Connection* conn, bool arg_orig) + : Analyzer(name, conn) { orig = arg_orig; sibling = 0; } + + /** + * Destructor. + */ + virtual ~SupportAnalyzer() {} + + /** + * Returns true if this is a support analyzer for the connection's + * originator side. + */ + bool IsOrig() const { return orig; } + + /** + * Passes packet input to the next sibling SupportAnalyzer if any, or + * on to the associated main analyzer if none. If however there's an + * output handler associated with this support analyzer, the data is + * passed only to there. + * + * Parameters same as for Analyzer::ForwardPacket. + */ + virtual void ForwardPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + /** + * Passes stream input to the next sibling SupportAnalyzer if any, or + * on to the associated main analyzer if none. If however there's an + * output handler associated with this support analyzer, the data is + * passed only to there. + * + * Parameters same as for Analyzer::ForwardStream. + */ + virtual void ForwardStream(int len, const u_char* data, bool orig); + + /** + * Passes gap information to the next sibling SupportAnalyzer if any, + * or on to the associated main analyzer if none. If however there's + * an output handler associated with this support analyzer, the gap is + * passed only to there. + * + * Parameters same as for Analyzer::ForwardPacket. + */ + virtual void ForwardUndelivered(int seq, int len, bool orig); + + /** + * Returns the analyzer next sibling, or null if none. + */ + SupportAnalyzer* Sibling() const { return sibling; } + +protected: + friend class Analyzer; + +private: + bool orig; + + // Points to next support analyzer in chain. The list is managed by + // parent analyzer. + SupportAnalyzer* sibling; +}; + +// The following need to be consistent with bro.init. +#define CONTENTS_NONE 0 +#define CONTENTS_ORIG 1 +#define CONTENTS_RESP 2 +#define CONTENTS_BOTH 3 + +/** + * Base class for analyzers parsing transport-layer protocols. + */ +class TransportLayerAnalyzer : public Analyzer { +public: + /** + * Constructor. + * + * @param name A name for the protocol the analyzer is parsing. The + * name must match the one the corresponding Component registers. + * + * @param conn The connection the analyzer is associated with. + */ + TransportLayerAnalyzer(const char* name, Connection* conn) + : Analyzer(name, conn) { pia = 0; } + + /** + * Overridden from parent class. + */ + virtual void Done(); + + /** + * Returns true if the analyzer determines that in fact a new + * connection has started without the connection statement having + * terminated the previous one, i.e., the new data is arriving at + * what's the analyzer for the previous instance. This is used only + * for TCP. + */ + virtual bool IsReuse(double t, const u_char* pkt) = 0; + + /** + * Associates a file with the analyzer in which to record all + * analyzed input. This must only be called with derived classes that + * overide the method; the default implementation will abort. + * + * @param direction One of the CONTENTS_* constants indicating which + * direction of the input stream is to be recorded. + * + * @param f The file to record to. + * + */ + virtual void SetContentsFile(unsigned int direction, BroFile* f); + + /** + * Returns an associated contents file, if any. This must only be + * called with derived classes that overide the method; the default + * implementation will abort. + * + * @param direction One of the CONTENTS_* constants indicating which + * direction the query is for. + */ + virtual BroFile* GetContentsFile(unsigned int direction) const; + + /** + * Associates a PIA with this analyzer. A PIA takes the + * transport-layer input and determine which protocol analyzer(s) to + * use for parsing it. + */ + void SetPIA(pia::PIA* arg_PIA) { pia = arg_PIA; } + + /** + * Returns the associated PIA, or null of none. Does not take + * ownership. + */ + pia::PIA* GetPIA() const { return pia; } + + /** + * Helper to raise a \c packet_contents event. + * + * @param data The dass to pass to the event. + * + * @param len The length of \a data. + */ + void PacketContents(const u_char* data, int len); + +private: + pia::PIA* pia; +}; + +} + +#endif diff --git a/src/analyzer/CMakeLists.txt b/src/analyzer/CMakeLists.txt new file mode 100644 index 0000000000..20b53d7ca8 --- /dev/null +++ b/src/analyzer/CMakeLists.txt @@ -0,0 +1,22 @@ + +include(BroSubdir) + +include_directories(BEFORE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_subdirectory(protocol) + +set(analyzer_SRCS + Analyzer.cc + Manager.cc + Component.cc + Tag.cc +) + +bif_target(analyzer.bif) + +bro_add_subdir_library(analyzer ${analyzer_SRCS} ${BIF_OUTPUT_CC}) +add_dependencies(bro_analyzer generate_outputs) + diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc new file mode 100644 index 0000000000..cbb0f40c20 --- /dev/null +++ b/src/analyzer/Component.cc @@ -0,0 +1,76 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Component.h" +#include "Manager.h" + +#include "../Desc.h" +#include "../util.h" + +using namespace analyzer; + +Tag::type_t Component::type_counter = 0; + +Component::Component(const char* arg_name, factory_callback arg_factory, Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial) + : plugin::Component(plugin::component::ANALYZER) + { + name = copy_string(arg_name); + canon_name = canonify_name(arg_name); + factory = arg_factory; + enabled = arg_enabled; + partial = arg_partial; + + tag = analyzer::Tag(++type_counter, arg_subtype); + } + +Component::Component(const Component& other) + : plugin::Component(Type()) + { + name = copy_string(other.name); + canon_name = copy_string(other.canon_name); + factory = other.factory; + enabled = other.enabled; + partial = other.partial; + tag = other.tag; + } + +Component::~Component() + { + delete [] name; + delete [] canon_name; + } + +analyzer::Tag Component::Tag() const + { + return tag; + } + +void Component::Describe(ODesc* d) const + { + plugin::Component::Describe(d); + d->Add(name); + d->Add(" ("); + + if ( factory ) + { + d->Add("ANALYZER_"); + d->Add(canon_name); + d->Add(", "); + } + + d->Add(enabled ? "enabled" : "disabled"); + d->Add(")"); + } + +Component& Component::operator=(const Component& other) + { + if ( &other != this ) + { + name = copy_string(other.name); + factory = other.factory; + enabled = other.enabled; + partial = other.partial; + tag = other.tag; + } + + return *this; + } diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h new file mode 100644 index 0000000000..f3d91c7f90 --- /dev/null +++ b/src/analyzer/Component.h @@ -0,0 +1,140 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_PLUGIN_COMPONENT_H +#define ANALYZER_PLUGIN_COMPONENT_H + +#include "Tag.h" +#include "plugin/Component.h" + +#include "../config.h" +#include "../util.h" + +class Connection; + +namespace analyzer { + +class Analyzer; + +/** + * Component description for plugins providing analyzers. + * + * A plugin can provide a specific protocol analyzer by registering this + * analyzer component, describing the analyzer. + */ +class Component : public plugin::Component { +public: + typedef Analyzer* (*factory_callback)(Connection* conn); + + /** + * Constructor. + * + * @param name The name of the provided analyzer. This name is used + * across the system to identify the analyzer, e.g., when calling + * analyzer::Manager::InstantiateAnalyzer with a name. + * + * @param factory A factory function to instantiate instances of the + * analyzer's class, which must be derived directly or indirectly + * from analyzer::Analyzer. This is typically a static \c + * Instatiate() method inside the class that just allocates and + * returns a new instance. + * + * @param subtype A subtype associated with this component that + * further distinguishes it. The subtype will be integrated into + * the analyzer::Tag that the manager associates with this analyzer, + * and analyzer instances can accordingly access it via analyzer::Tag(). + * If not used, leave at zero. + * + * @param enabled If false the analyzer starts out as disabled and + * hence won't be used. It can still be enabled later via the + * manager, including from script-land. + * + * @param partial If true, the analyzer can deal with payload from + * partial connections, i.e., when Bro enters the stream mid-way + * after not seeing the beginning. Note that handling of partial + * connections has generally not seen much testing yet as virtually + * no existing analyzer supports it. + */ + Component(const char* name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true, bool partial = false); + + /** + * Copy constructor. + */ + Component(const Component& other); + + /** + * Destructor. + */ + ~Component(); + + /** + * Returns the name of the analyzer. This name is unique across all + * analyzers and used to identify it. The returned name is derived + * from what's passed to the constructor but upper-cased and + * canonified to allow being part of a script-level ID. + */ + const char* Name() const { return name; } + + /** + * Returns a canonocalized version of the analyzer's name. The + * returned name is derived from what's passed to the constructor but + * upper-cased and transformed to allow being part of a script-level + * ID. + */ + const char* CanonicalName() const { return canon_name; } + + /** + * Returns the analyzer's factory function. + */ + factory_callback Factory() const { return factory; } + + /** + * Returns whether the analyzer supports partial connections. Partial + * connections are those where Bro starts processing payload + * mid-stream, after missing the beginning. + */ + bool Partial() const { return partial; } + + /** + * Returns true if the analyzer is currently enabled and hence + * available for use. + */ + bool Enabled() const { return enabled; } + + /** + * Returns the analyzer's tag. Note that this is automatically + * generated for each new Components, and hence unique across all of + * them. + */ + analyzer::Tag Tag() const; + + /** + * Enables or disables this analyzer. + * + * @param arg_enabled True to enabled, false to disable. + * + */ + void SetEnabled(bool arg_enabled) { enabled = arg_enabled; } + + /** + * Generates a human-readable description of the component's main + * parameters. This goes into the output of \c "bro -NN". + */ + virtual void Describe(ODesc* d) const; + + Component& operator=(const Component& other); + +private: + const char* name; // The analyzer's name. + const char* canon_name; // The analyzer's canonical name. + factory_callback factory; // The analyzer's factory callback. + bool partial; // True if the analyzer supports partial connections. + analyzer::Tag tag; // The automatically assigned analyzer tag. + bool enabled; // True if the analyzer is enabled. + + // Global counter used to generate unique tags. + static analyzer::Tag::type_t type_counter; +}; + +} + +#endif diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc new file mode 100644 index 0000000000..5695dec625 --- /dev/null +++ b/src/analyzer/Manager.cc @@ -0,0 +1,697 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Manager.h" + +#include "Hash.h" +#include "Val.h" + +#include "protocol/backdoor/BackDoor.h" +#include "protocol/conn-size/ConnSize.h" +#include "protocol/icmp/ICMP.h" +#include "protocol/interconn/InterConn.h" +#include "protocol/pia/PIA.h" +#include "protocol/stepping-stone/SteppingStone.h" +#include "protocol/tcp/TCP.h" +#include "protocol/udp/UDP.h" + +#include "plugin/Manager.h" + +#include "protocol/tcp/events.bif.h" + +using namespace analyzer; + +Manager::ConnIndex::ConnIndex(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; + } + +Manager::ConnIndex::ConnIndex() + { + orig = resp = IPAddr("0.0.0.0"); + resp_p = 0; + proto = 0; + } + +bool Manager::ConnIndex::operator<(const ConnIndex& other) const + { + if ( orig != other.orig ) + return orig < other.orig; + + if ( resp != other.resp ) + return resp < other.resp; + + if ( proto != other.proto ) + return proto < other.proto; + + if ( resp_p != other.resp_p ) + return resp_p < other.resp_p; + + return false; + } + +Manager::Manager() + { + tag_enum_type = new EnumType("Analyzer::Tag"); + ::ID* id = install_ID("Tag", "Analyzer", true, true); + add_type(id, tag_enum_type, 0, 0); + } + +Manager::~Manager() + { + for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_tcp.begin(); i != analyzers_by_port_tcp.end(); i++ ) + delete i->second; + + for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_udp.begin(); i != analyzers_by_port_udp.end(); i++ ) + delete i->second; + + analyzers_by_port_udp.clear(); + analyzers_by_port_tcp.clear(); + + // Clean up expected-connection table. + while ( conns_by_timeout.size() ) + { + ScheduledAnalyzer* a = conns_by_timeout.top(); + conns_by_timeout.pop(); + delete a; + } + } + +void Manager::InitPreScript() + { + std::list analyzers = plugin_mgr->Components(); + + for ( std::list::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ ) + RegisterAnalyzerComponent(*i); + + // Cache these tags. + analyzer_backdoor = GetAnalyzerTag("BACKDOOR"); + analyzer_connsize = GetAnalyzerTag("CONNSIZE"); + analyzer_interconn = GetAnalyzerTag("INTERCONN"); + analyzer_stepping = GetAnalyzerTag("STEPPINGSTONE"); + analyzer_tcpstats = GetAnalyzerTag("TCPSTATS"); + } + +void Manager::InitPostScript() + { + #include "analyzer.bif.init.cc" + } + +void Manager::DumpDebug() + { +#ifdef DEBUG + DBG_LOG(DBG_ANALYZER, "Available analyzers after bro_init():"); + for ( analyzer_map_by_name::const_iterator i = analyzers_by_name.begin(); i != analyzers_by_name.end(); i++ ) + DBG_LOG(DBG_ANALYZER, " %s (%s)", i->second->Name(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled"); + + DBG_LOG(DBG_ANALYZER, ""); + DBG_LOG(DBG_ANALYZER, "Analyzers by port:"); + + for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_tcp.begin(); i != analyzers_by_port_tcp.end(); i++ ) + { + string s; + + for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ ) + s += string(GetAnalyzerName(*j)) + " "; + + DBG_LOG(DBG_ANALYZER, " %d/tcp: %s", i->first, s.c_str()); + } + + for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_udp.begin(); i != analyzers_by_port_udp.end(); i++ ) + { + string s; + + for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ ) + s += string(GetAnalyzerName(*j)) + " "; + + DBG_LOG(DBG_ANALYZER, " %d/udp: %s", i->first, s.c_str()); + } + +#endif + } + +void Manager::Done() + { + } + +void Manager::RegisterAnalyzerComponent(Component* component) + { + const char* cname = component->CanonicalName(); + + if ( Lookup(cname) ) + reporter->FatalError("Analyzer %s defined more than once", cname); + + DBG_LOG(DBG_ANALYZER, "Registering analyzer %s (tag %s)", + component->Name(), component->Tag().AsString().c_str()); + + analyzers_by_name.insert(std::make_pair(cname, component)); + analyzers_by_tag.insert(std::make_pair(component->Tag(), component)); + analyzers_by_val.insert(std::make_pair(component->Tag().AsEnumVal()->InternalInt(), component)); + + // Install enum "Analyzer::ANALYZER_*" + string id = fmt("ANALYZER_%s", cname); + tag_enum_type->AddName("Analyzer", id.c_str(), component->Tag().AsEnumVal()->InternalInt(), true); + } + +bool Manager::EnableAnalyzer(Tag tag) + { + Component* p = Lookup(tag); + + if ( ! p ) + return false; + + DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name()); + p->SetEnabled(true); + + return true; + } + +bool Manager::EnableAnalyzer(EnumVal* val) + { + Component* p = Lookup(val); + + if ( ! p ) + return false; + + DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name()); + p->SetEnabled(true); + + return true; + } + +bool Manager::DisableAnalyzer(Tag tag) + { + Component* p = Lookup(tag); + + if ( ! p ) + return false; + + DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name()); + p->SetEnabled(false); + + return true; + } + +bool Manager::DisableAnalyzer(EnumVal* val) + { + Component* p = Lookup(val); + + if ( ! p ) + return false; + + DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name()); + p->SetEnabled(false); + + return true; + } + +void Manager::DisableAllAnalyzers() + { + DBG_LOG(DBG_ANALYZER, "Disabling all analyzers"); + + for ( analyzer_map_by_tag::const_iterator i = analyzers_by_tag.begin(); i != analyzers_by_tag.end(); i++ ) + i->second->SetEnabled(false); + } + +bool Manager::IsEnabled(Tag tag) + { + if ( ! tag ) + return false; + + Component* p = Lookup(tag); + + if ( ! p ) + return false; + + return p->Enabled(); + } + +bool Manager::IsEnabled(EnumVal* val) + { + Component* p = Lookup(val); + + if ( ! p ) + return false; + + return p->Enabled(); + } + + +bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port) + { + Component* p = Lookup(val); + + if ( ! p ) + return false; + + return RegisterAnalyzerForPort(p->Tag(), port->PortType(), port->Port()); + } + +bool Manager::UnregisterAnalyzerForPort(EnumVal* val, PortVal* port) + { + Component* p = Lookup(val); + + if ( ! p ) + return false; + + return UnregisterAnalyzerForPort(p->Tag(), port->PortType(), port->Port()); + } + +bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port) + { + tag_set* l = LookupPort(proto, port, true); + +#ifdef DEBUG + const char* name = GetAnalyzerName(tag); + DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, proto); +#endif + + l->insert(tag); + return true; + } + +bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port) + { + tag_set* l = LookupPort(proto, port, true); + +#ifdef DEBUG + const char* name = GetAnalyzerName(tag); + DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, proto); +#endif + + l->erase(tag); + return true; + } + +Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn) + { + Component* c = Lookup(tag); + + if ( ! c ) + reporter->InternalError("request to instantiate unknown analyzer"); + + if ( ! c->Enabled() ) + return 0; + + if ( ! c->Factory() ) + reporter->InternalError("analyzer %s cannot be instantiated dynamically", GetAnalyzerName(tag)); + + Analyzer* a = c->Factory()(conn); + + if ( ! a ) + reporter->InternalError("analyzer instantiation failed"); + + a->SetAnalyzerTag(tag); + + return a; + } + +Analyzer* Manager::InstantiateAnalyzer(const char* name, Connection* conn) + { + Tag tag = GetAnalyzerTag(name); + return tag ? InstantiateAnalyzer(tag, conn) : 0; + } + +const char* Manager::GetAnalyzerName(Tag tag) + { + static const char* error = ""; + + if ( ! tag ) + return error; + + Component* c = Lookup(tag); + + if ( ! c ) + reporter->InternalError("request for name of unknown analyzer tag %s", tag.AsString().c_str()); + + return c->CanonicalName(); + } + +const char* Manager::GetAnalyzerName(Val* val) + { + return GetAnalyzerName(Tag(val->AsEnumVal())); + } + +Tag Manager::GetAnalyzerTag(const char* name) + { + Component* c = Lookup(name); + return c ? c->Tag() : Tag(); + } + +EnumType* Manager::GetTagEnumType() + { + return tag_enum_type; + } + +Component* Manager::Lookup(const char* name) + { + analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name)); + return i != analyzers_by_name.end() ? i->second : 0; + } + +Component* Manager::Lookup(const Tag& tag) + { + analyzer_map_by_tag::const_iterator i = analyzers_by_tag.find(tag); + return i != analyzers_by_tag.end() ? i->second : 0; + } + +Component* Manager::Lookup(EnumVal* val) + { + analyzer_map_by_val::const_iterator i = analyzers_by_val.find(val->InternalInt()); + return i != analyzers_by_val.end() ? i->second : 0; + } + +Manager::tag_set* Manager::LookupPort(TransportProto proto, uint32 port, bool add_if_not_found) + { + analyzer_map_by_port* m = 0; + + switch ( proto ) { + case TRANSPORT_TCP: + m = &analyzers_by_port_tcp; + break; + + case TRANSPORT_UDP: + m = &analyzers_by_port_udp; + break; + + default: + reporter->InternalError("unsupport transport protocol in analyzer::Manager::LookupPort"); + } + + analyzer_map_by_port::const_iterator i = m->find(port); + + if ( i != m->end() ) + return i->second; + + if ( ! add_if_not_found ) + return 0; + + tag_set* l = new tag_set; + m->insert(std::make_pair(port, l)); + return l; + } + +Manager::tag_set* Manager::LookupPort(PortVal* val, bool add_if_not_found) + { + return LookupPort(val->PortType(), val->Port(), add_if_not_found); + } + +bool Manager::BuildInitialAnalyzerTree(Connection* conn) + { + Analyzer* analyzer = 0; + tcp::TCP_Analyzer* tcp = 0; + udp::UDP_Analyzer* udp = 0; + icmp::ICMP_Analyzer* icmp = 0; + TransportLayerAnalyzer* root = 0; + tag_set expected; + pia::PIA* pia = 0; + bool analyzed = false; + bool check_port = false; + + switch ( conn->ConnTransport() ) { + + case TRANSPORT_TCP: + root = tcp = new tcp::TCP_Analyzer(conn); + pia = new pia::PIA_TCP(conn); + expected = GetScheduled(conn); + check_port = true; + DBG_ANALYZER(conn, "activated TCP analyzer"); + break; + + case TRANSPORT_UDP: + root = udp = new udp::UDP_Analyzer(conn); + pia = new pia::PIA_UDP(conn); + expected = GetScheduled(conn); + check_port = true; + DBG_ANALYZER(conn, "activated UDP analyzer"); + break; + + case TRANSPORT_ICMP: { + root = icmp = new icmp::ICMP_Analyzer(conn); + DBG_ANALYZER(conn, "activated ICMP analyzer"); + analyzed = true; + break; + } + + default: + reporter->InternalError("unknown protocol"); + } + + if ( ! root ) + { + DBG_ANALYZER(conn, "cannot build analyzer tree"); + return false; + } + + // Any scheduled analyzer? + for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ ) + { + Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(*i, conn); + + if ( analyzer ) + { + root->AddChildAnalyzer(analyzer, false); + + DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled", + analyzer_mgr->GetAnalyzerName(*i)); + } + + } + + // Hmm... Do we want *just* the expected analyzer, or all + // other potential analyzers as well? For now we only take + // the scheduled ones. + if ( expected.size() == 0 ) + { // Let's see if it's a port we know. + if ( check_port && ! dpd_ignore_ports ) + { + int resp_port = ntohs(conn->RespPort()); + tag_set* ports = LookupPort(conn->ConnTransport(), resp_port, false); + + if ( ports ) + { + for ( tag_set::const_iterator j = ports->begin(); j != ports->end(); ++j ) + { + Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(*j, conn); + + if ( ! analyzer ) + continue; + + root->AddChildAnalyzer(analyzer, false); + DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d", + analyzer_mgr->GetAnalyzerName(*j), resp_port); + } + } + } + } + + 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(); + + if ( IsEnabled(analyzer_backdoor) ) + // Add a BackDoor analyzer if requested. This analyzer + // can handle both reassembled and non-reassembled input. + tcp->AddChildAnalyzer(new backdoor::BackDoor_Analyzer(conn), false); + + if ( IsEnabled(analyzer_interconn) ) + // Add a InterConn analyzer if requested. This analyzer + // can handle both reassembled and non-reassembled input. + tcp->AddChildAnalyzer(new interconn::InterConn_Analyzer(conn), false); + + if ( IsEnabled(analyzer_stepping) ) + { + // 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 ( resp_port == 22 || resp_port == 23 || resp_port == 513 ) + { + AddrVal src(conn->OrigAddr()); + if ( ! stp_skip_src->Lookup(&src) ) + tcp->AddChildAnalyzer(new stepping_stone::SteppingStone_Analyzer(conn), false); + } + } + + if ( IsEnabled(analyzer_tcpstats) ) + // Add TCPStats analyzer. This needs to see packets so + // we cannot add it as a normal child. + tcp->AddChildPacketAnalyzer(new tcp::TCPStats_Analyzer(conn)); + + if ( IsEnabled(analyzer_connsize) ) + // Add ConnSize analyzer. Needs to see packets, not stream. + tcp->AddChildPacketAnalyzer(new conn_size::ConnSize_Analyzer(conn)); + } + + else + { + if ( IsEnabled(analyzer_connsize) ) + // Add ConnSize analyzer. Needs to see packets, not stream. + root->AddChildAnalyzer(new conn_size::ConnSize_Analyzer(conn)); + } + + if ( pia ) + root->AddChildAnalyzer(pia->AsAnalyzer()); + + if ( root->GetChildren().size() ) + analyzed = true; + + conn->SetRootAnalyzer(root, pia); + root->Init(); + root->InitChildren(); + + if ( ! analyzed ) + conn->SetLifetime(non_analyzed_lifetime); + + for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ ) + { + EnumVal* tag = i->AsEnumVal(); + Ref(tag); + conn->Event(scheduled_analyzer_applied, 0, tag); + } + + return true; + } + +void Manager::ExpireScheduledAnalyzers() + { + if ( ! network_time ) + return; + + while ( conns_by_timeout.size() ) + { + ScheduledAnalyzer* a = conns_by_timeout.top(); + + if ( a->timeout > network_time ) + return; + + conns_by_timeout.pop(); + + std::pair all = conns.equal_range(a->conn); + + bool found = false; + + for ( conns_map::iterator i = all.first; i != all.second; i++ ) + { + if ( i->second != a ) + continue; + + conns.erase(i); + + DBG_LOG(DBG_ANALYZER, "Expiring expected analyzer %s for connection %s", + analyzer_mgr->GetAnalyzerName(a->analyzer), + fmt_conn_id(a->conn.orig, 0, a->conn.resp, a->conn.resp_p)); + + delete a; + found = true; + break; + } + + assert(found); + } + } + +void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, + uint16 resp_p, + TransportProto proto, Tag analyzer, + double timeout) + { + if ( ! network_time ) + { + reporter->Warning("cannot schedule analyzers before processing begins; ignored"); + return; + } + + assert(timeout); + + // Use the chance to see if the oldest entry is already expired. + ExpireScheduledAnalyzers(); + + ScheduledAnalyzer* a = new ScheduledAnalyzer; + a->conn = ConnIndex(orig, resp, resp_p, proto); + a->analyzer = analyzer; + a->timeout = network_time + timeout; + + conns.insert(std::make_pair(a->conn, a)); + conns_by_timeout.push(a); + } + +void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, + uint16 resp_p, + TransportProto proto, const char* analyzer, + double timeout) + { + Tag tag = GetAnalyzerTag(analyzer); + + if ( tag != Tag() ) + ScheduleAnalyzer(orig, resp, resp_p, proto, tag, timeout); + } + +void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p, + Val* analyzer, double timeout) + { + EnumVal* ev = analyzer->AsEnumVal(); + return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(), Tag(ev), timeout); + } + +Manager::tag_set Manager::GetScheduled(const Connection* conn) + { + ConnIndex c(conn->OrigAddr(), conn->RespAddr(), + ntohs(conn->RespPort()), conn->ConnTransport()); + + std::pair all = conns.equal_range(c); + + tag_set result; + + for ( conns_map::iterator i = all.first; i != all.second; i++ ) + result.insert(i->second->analyzer); + + // Try wildcard for originator. + c.orig = IPAddr(string("::")); + all = conns.equal_range(c); + + for ( conns_map::iterator i = all.first; i != all.second; i++ ) + { + if ( i->second->timeout > network_time ) + result.insert(i->second->analyzer); + } + + // We don't delete scheduled analyzers here. They will be expired + // eventually. + return result; + } diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h new file mode 100644 index 0000000000..efae629971 --- /dev/null +++ b/src/analyzer/Manager.h @@ -0,0 +1,443 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +/** + * The central management unit for registering and instantiating analyzers. + * + * For each protocol that Bro supports, there's one class derived from + * analyzer::Analyzer. Once we have decided that a connection's payload is to + * be parsed as a given protocol, we instantiate the corresponding + * analyzer-derived class and add the new instance as a child node into the + * connection's analyzer tree. + * + * In addition to the analyzer-derived class itself, for each protocol + * there's also "meta-class" derived from analyzer::Component that describes + * the analyzer, including status information on if that particular protocol + * analysis is currently enabled. + * + * To identify an analyzer (or to be precise: a component), the manager + * maintains mappings of (1) analyzer::Tag to component, and (2) + * human-readable analyzer name to component. + */ +#ifndef ANALYZER_MANAGER_H +#define ANALYZER_MANAGER_H + +#include + +#include "Analyzer.h" +#include "Component.h" +#include "Tag.h" + +#include "../Dict.h" +#include "../net_util.h" +#include "../IP.h" + +#include "analyzer/analyzer.bif.h" + +namespace analyzer { + +/** + * Class maintaining and scheduling available protocol analyzers. + * + * The manager maintains a registry of all available protocol analyzers, + * including a mapping between their textual names and analyzer::Tag. It + * instantantiates new analyzers on demand. For new connections, the manager + * sets up their initial analyzer tree, including adding the right \c PIA, + * respecting well-known ports, and tracking any analyzers specifically + * scheduled for individidual connections. + * + * Note that we keep the public interface of this class free of std::* + * classes. This allows to external analyzer code to potentially use a + * different C++ standard library. + */ +class Manager { +public: + /** + * Constructor. + */ + Manager(); + + /** + * Destructor. + */ + ~Manager(); + + /** + * First-stage initializion of the manager. This is called early on + * during Bro's initialization, before any scripts are processed. + */ + void InitPreScript(); + + /** + * Second-stage initialization of the manager. This is called late + * during Bro's initialization after any scripts are processed. + */ + void InitPostScript(); + + /** + * Finished the manager's operations. + */ + void Done(); + + /** + * Dumps out the state of all registered analyzers to the \c analyzer + * debug stream. Should be called only after any \c bro_init events + * have executed to ensure that any of their changes are applied. + */ + void DumpDebug(); // Called after bro_init() events. + + /** + * Enables an analyzer type. Only enabled analyzers will be + * instantiated for new connections. + * + * @param tag The analyzer's tag. + * + * @return True if successful. + */ + bool EnableAnalyzer(Tag tag); + + /** + * Enables an analyzer type. Only enabled analyzers will be + * instantiated for new connections. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + * + * @return True if successful. + */ + bool EnableAnalyzer(EnumVal* tag); + + /** + * Enables an analyzer type. Disabled analyzers will not be + * instantiated for new connections. + * + * @param tag The analyzer's tag. + * + * @return True if successful. + */ + bool DisableAnalyzer(Tag tag); + + /** + * Enables an analyzer type. Disabled analyzers will not be + * instantiated for new connections. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + * + * @return True if successful. + */ + bool DisableAnalyzer(EnumVal* tag); + + /** + * Disables all currently registered analyzers. + */ + void DisableAllAnalyzers(); + + /** + * Returns true if an analyzer is enabled. + * + * @param tag The analyzer's tag. + */ + bool IsEnabled(Tag tag); + + /** + * Returns true if an analyzer is enabled. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + */ + bool IsEnabled(EnumVal* tag); + + /** + * Registers a well-known port for an analyzer. Once registered, + * connection on that port will start with a corresponding analyzer + * assigned. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + * + * @param port The well-known port. + * + * @return True if successful. + */ + bool RegisterAnalyzerForPort(EnumVal* tag, PortVal* port); + + /** + * Registers a well-known port for an analyzer. Once registered, + * connection on that port will start with a corresponding analyzer + * assigned. + * + * @param tag The analyzer's tag. + * + * @param proto The port's protocol. + * + * @param port The port's number. + * + * @return True if successful. + */ + bool RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port); + + /** + * Unregisters a well-known port for an anlyzers. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + * + * @param port The well-known port. + * + * @return True if successful (incl. when the port wasn't actually + * registered for the analyzer). + * + */ + bool UnregisterAnalyzerForPort(EnumVal* tag, PortVal* port); + + /** + * Unregisters a well-known port for an anlyzers. + * + * @param tag The analyzer's tag. + * + * @param proto The port's protocol. + * + * @param port The port's number. + * + * @param tag The analyzer's tag as an enum of script type \c + * Analyzer::Tag. + */ + bool UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port); + + /** + * Instantiates a new analyzer instance for a connection. + * + * @param tag The analyzer's tag. + * + * @param conn The connection the analyzer is to be associated with. + * + * @return The new analyzer instance. Note that the analyzer will not + * have been added to the connection's analyzer tree yet. Returns + * null if tag is invalid or the requested analyzer is disabled. + */ + Analyzer* InstantiateAnalyzer(Tag tag, Connection* c); + + /** + * Instantiates a new analyzer instance for a connection. + * + * @param name The name of the analyzer. + * + * @param conn The connection the analyzer is to be associated with. + * + * @return The new analyzer instance. Note that the analyzer will not + * have been added to the connection's analyzer tree yet. Returns + * null if the name is not known or if the requested analyzer that is + * disabled. + */ + Analyzer* InstantiateAnalyzer(const char* name, Connection* c); + + /** + * Translates an analyzer tag into corresponding analyzer name. + * + * @param tag The analyzer tag. + * + * @return The name, or an empty string if the tag is invalid. + */ + const char* GetAnalyzerName(Tag tag); + + /** + * Translates an script-level analyzer tag into corresponding + * analyzer name. + * + * @param val The analyzer tag as an script-level enum value of type + * \c Analyzer::Tag. + * + * @return The name, or an empty string if the tag is invalid. + */ + const char* GetAnalyzerName(Val* val); + + /** + * Translates an analyzer name into the corresponding tag. + * + * @param name The name. + * + * @return The tag. If the name does not correspond to a valid + * analyzer, the returned tag will evaluate to false. + */ + Tag GetAnalyzerTag(const char* name); + + /** + * Returns the enum type that corresponds to the script-level type \c + * Analyzer::Tag. + */ + EnumType* GetTagEnumType(); + + /** + * Given the first packet of a connection, builds its initial + * analyzer tree. + * + * @param conn The connection to add the initial set of analyzers to. + * + * @return False if the tree cannot be build; that's usually an + * internally error. + */ + bool BuildInitialAnalyzerTree(Connection* conn); + + /** + * Schedules a particular analyzer for an upcoming connection. Once + * the connection is seen, BuildInitAnalyzerTree() will add the + * specified analyzer to its tree. + * + * @param orig The connection's anticipated originator address. + * 0.0.0.0 can be used as a wildcard matching any originator. + * + * @param resp The connection's anticipated responder address (no + * wilcard). + * + * @param resp_p The connection's anticipated responder port. + * + * @param proto The connection's anticipated transport protocol. + * + * @param analyzer The analyzer to use once the connection is seen. + * + * @param timeout An interval after which to timeout the request to + * schedule this analyzer. Must be non-zero. + */ + void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, + TransportProto proto, Tag analyzer, double timeout); + + /** + * Schedules a particular analyzer for an upcoming connection. Once + * the connection is seen, BuildInitAnalyzerTree() will add the + * specified analyzer to its tree. + * + * @param orig The connection's anticipated originator address. 0 can + * be used as a wildcard matching any originator. + * + * @param resp The The connection's anticipated responder address (no + * wilcard). + * + * @param resp_p The connection's anticipated responder port. + * + * @param proto The connection's anticipated transport protocol. + * + * @param analyzer The name of the analyzer to use once the + * connection is seen. + * + * @param timeout An interval after which to timeout the request to + * schedule this analyzer. Must be non-zero. + */ + void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, + TransportProto proto, const char* analyzer, + double timeout); + + /** + * Schedules a particular analyzer for an upcoming connection. Once + * the connection is seen, BuildInitAnalyzerTree() will add the + * specified analyzer to its tree. + * + * @param orig The connection's anticipated originator address. 0 can + * be used as a wildcard matching any originator. + * + * @param resp The connection's anticipated responder address (no + * wilcard). + * + * @param resp_p The connection's anticipated responder port. + * + * @param analyzer The analyzer to use once the connection is seen as + * an enum value of script-type \c Analyzer::Tag. + * + * @param timeout An interval after which to timeout the request to + * schedule this analyzer. Must be non-zero. + */ + void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p, + Val* analyzer, double timeout); + +private: + typedef set tag_set; + typedef map analyzer_map_by_name; + typedef map analyzer_map_by_tag; + typedef map analyzer_map_by_val; + typedef map analyzer_map_by_port; + + void RegisterAnalyzerComponent(Component* component); // Takes ownership. + + Component* Lookup(const string& name); + Component* Lookup(const char* name); + Component* Lookup(const Tag& tag); + Component* Lookup(EnumVal* val); + + tag_set* LookupPort(PortVal* val, bool add_if_not_found); + tag_set* LookupPort(TransportProto proto, uint32 port, bool add_if_not_found); + + tag_set GetScheduled(const Connection* conn); + void ExpireScheduledAnalyzers(); + + analyzer_map_by_port analyzers_by_port_tcp; + analyzer_map_by_port analyzers_by_port_udp; + analyzer_map_by_name analyzers_by_name; + analyzer_map_by_tag analyzers_by_tag; + analyzer_map_by_val analyzers_by_val; + + Tag analyzer_backdoor; + Tag analyzer_connsize; + Tag analyzer_interconn; + Tag analyzer_stepping; + Tag analyzer_tcpstats; + + EnumType* tag_enum_type; + + //// Data structures to track analyzed scheduled for future connections. + + // The index for a scheduled connection. + struct ConnIndex { + IPAddr orig; + IPAddr resp; + uint16 resp_p; + uint16 proto; + + ConnIndex(const IPAddr& _orig, const IPAddr& _resp, + uint16 _resp_p, uint16 _proto); + ConnIndex(); + + bool operator<(const ConnIndex& other) const; + }; + + // Information associated with a scheduled connection. + struct ScheduledAnalyzer { + ConnIndex conn; + Tag analyzer; + double timeout; + + struct Comparator { + bool operator() (ScheduledAnalyzer* a, ScheduledAnalyzer* b) { + return a->timeout > b->timeout; + } + }; + }; + + typedef std::multimap conns_map; + typedef std::priority_queue, + ScheduledAnalyzer::Comparator> conns_queue; + + conns_map conns; + conns_queue conns_by_timeout; +}; + +} + +extern analyzer::Manager* analyzer_mgr; + +// Macros for anayzer debug logging which include the connection id into the +// message. +#ifdef DEBUG +# define DBG_ANALYZER(conn, txt) \ + DBG_LOG(DBG_ANALYZER, "%s " txt, \ + fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \ + conn->RespAddr(), ntohs(conn->RespPort()))); +# define DBG_ANALYZER_ARGS(conn, fmt, args...) \ + DBG_LOG(DBG_ANALYZER, "%s " fmt, \ + fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \ + conn->RespAddr(), ntohs(conn->RespPort())), ##args); +#else +# define DBG_ANALYZER(conn, txt) +# define DBG_ANALYZER_ARGS(conn, fmt, args...) +#endif + +#endif diff --git a/src/analyzer/Tag.cc b/src/analyzer/Tag.cc new file mode 100644 index 0000000000..2f04ff17da --- /dev/null +++ b/src/analyzer/Tag.cc @@ -0,0 +1,92 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Tag.h" +#include "Manager.h" + +#include "../NetVar.h" + +using namespace analyzer; + +Tag Tag::Error; + +Tag::Tag(type_t arg_type, subtype_t arg_subtype) + { + assert(arg_type > 0); + + type = arg_type; + subtype = arg_subtype; + int64_t i = (int64)(type) | ((int64)subtype << 31); + + EnumType* etype = analyzer_mgr->GetTagEnumType(); + Ref(etype); + val = new EnumVal(i, etype); + } + +Tag::Tag(EnumVal* arg_val) + { + assert(arg_val); + + val = arg_val; + Ref(val); + + int64 i = val->InternalInt(); + type = i & 0xffffffff; + subtype = (i >> 31) & 0xffffffff; + } + +Tag::Tag(const Tag& other) + { + type = other.type; + subtype = other.subtype; + val = other.val; + + if ( val ) + Ref(val); + } + +Tag::Tag() + { + type = 0; + subtype = 0; + val = 0; + } + +Tag::~Tag() + { + Unref(val); + val = 0; + } + +Tag& Tag::operator=(const Tag& other) + { + if ( this != &other ) + { + type = other.type; + subtype = other.subtype; + val = other.val; + + if ( val ) + Ref(val); + } + + return *this; + } + +EnumVal* Tag::AsEnumVal() const + { + if ( ! val ) + { + assert(analyzer_mgr); + assert(type == 0 && subtype == 0); + EnumType* etype = analyzer_mgr->GetTagEnumType(); + Ref(etype); + val = new EnumVal(0, etype); + } + + return val; + } + +std::string Tag::AsString() const + { + return fmt("%" PRIu32 "/%" PRIu32, type, subtype); + } diff --git a/src/analyzer/Tag.h b/src/analyzer/Tag.h new file mode 100644 index 0000000000..edb0ade8a7 --- /dev/null +++ b/src/analyzer/Tag.h @@ -0,0 +1,159 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_TAG_H +#define ANALYZER_TAG_H + +#include "config.h" +#include "util.h" + +class EnumVal; + +namespace file_analysis { +class Manager; +class Component; +} + +namespace analyzer { + +class Manager; +class Component; + +/** + * Class to identify an analyzer type. + * + * Each analyzer type gets a tag consisting of a main type and subtype. The + * former is an identifier that's unique all analyzer classes. The latter is + * passed through to the analyzer instances for their use, yet not further + * interpreted by the analyzer infrastructure; it allows an analyzer to + * branch out into a set of sub-analyzers internally. Jointly, main type and + * subtype form an analyzer "tag". Each unique tag corresponds to a single + * "analyzer" from the user's perspective. At the script layer, these tags + * are mapped into enums of type \c Analyzer::Tag. Internally, the + * analyzer::Manager maintains the mapping of tag to analyzer (and it also + * assigns them their main types), and analyzer::Component creates new + * tags. + * + * The Tag class supports all operations necessary to act as an index in a + * \c std::map. + */ +class Tag { +public: + /** + * Type for the analyzer's main type. + */ + typedef uint32 type_t; + + /** + * Type for the analyzer's subtype. + */ + typedef uint32 subtype_t; + + /* + * Copy constructor. + */ + Tag(const Tag& other); + + /** + * Default constructor. This initializes the tag with an error value + * that will make \c operator \c bool return false. + */ + Tag(); + + /** + * Destructor. + */ + ~Tag(); + + /** + * Returns the tag's main type. + */ + type_t Type() const { return type; } + + /** + * Returns the tag's subtype. + */ + subtype_t Subtype() const { return subtype; } + + /** + * Returns the \c Analyzer::Tag enum that corresponds to this tag. + * The returned value is \a does not have its ref-count increased. + */ + EnumVal* AsEnumVal() const; + + /** + * Returns the numerical values for main and subtype inside a string + * suitable for printing. This is primarily for debugging. + */ + std::string AsString() const; + + /** + * Returns false if the tag represents an error value rather than a + * legal analyzer type. + */ + operator bool() const { return *this != Tag(); } + + /** + * Assignment operator. + */ + Tag& operator=(const Tag& other); + + /** + * Compares two tags for equality. + */ + bool operator==(const Tag& other) const + { + return type == other.type && subtype == other.subtype; + } + + /** + * Compares two tags for inequality. + */ + bool operator!=(const Tag& other) const + { + return type != other.type || subtype != other.subtype; + } + + /** + * Compares two tags for less-than relationship. + */ + bool operator<(const Tag& other) const + { + return type != other.type ? type < other.type : (subtype < other.subtype); + } + + static Tag Error; + +protected: + friend class analyzer::Manager; + friend class analyzer::Component; + friend class file_analysis::Manager; + friend class file_analysis::Component; + + /** + * Constructor. + * + * @param type The main type. Note that the \a analyzer::Manager + * manages the value space internally, so noone else should assign + * any main tyoes. + * + * @param subtype The sub type, which is left to an analyzer for + * interpretation. By default it's set to zero. + */ + Tag(type_t type, subtype_t subtype = 0); + + /** + * Constructor. + * + * @param val An enuam value of script type \c Analyzer::Tag. + */ + Tag(EnumVal* val); + +private: + type_t type; // Main type. + subtype_t subtype; // Subtype. + mutable EnumVal* val; // Analyzer::Tag value. +}; + +} + +#endif diff --git a/src/analyzer/analyzer.bif b/src/analyzer/analyzer.bif new file mode 100644 index 0000000000..7f3cc6ed94 --- /dev/null +++ b/src/analyzer/analyzer.bif @@ -0,0 +1,45 @@ +##! Internal functions and types used by the analyzer framework. + +module Analyzer; + +%%{ +#include "NetVar.h" + +#include "analyzer/Manager.h" +%%} + +function Analyzer::__enable_analyzer%(id: Analyzer::Tag%) : bool + %{ + bool result = analyzer_mgr->EnableAnalyzer(id->AsEnumVal()); + return new Val(result, TYPE_BOOL); + %} + +function Analyzer::__disable_analyzer%(id: Analyzer::Tag%) : bool + %{ + bool result = analyzer_mgr->DisableAnalyzer(id->AsEnumVal()); + return new Val(result, TYPE_BOOL); + %} + +function Analyzer::__disable_all_analyzers%(%) : any + %{ + analyzer_mgr->DisableAllAnalyzers(); + return 0; + %} + +function Analyzer::__register_for_port%(id: Analyzer::Tag, p: port%) : bool + %{ + bool result = analyzer_mgr->RegisterAnalyzerForPort(id->AsEnumVal(), p); + return new Val(result, TYPE_BOOL); + %} + +function Analyzer::__schedule_analyzer%(orig: addr, resp: addr, resp_p: port, + analyzer: Analyzer::Tag, tout: interval%) : bool + %{ + analyzer_mgr->ScheduleAnalyzer(orig->AsAddr(), resp->AsAddr(), resp_p, analyzer->AsEnumVal(), tout); + return new Val(true, TYPE_BOOL); + %} + +function __name%(atype: Analyzer::Tag%) : string + %{ + return new StringVal(analyzer_mgr->GetAnalyzerName(atype)); + %} diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt new file mode 100644 index 0000000000..a4e170f52b --- /dev/null +++ b/src/analyzer/protocol/CMakeLists.txt @@ -0,0 +1,40 @@ + +add_subdirectory(arp) +add_subdirectory(ayiya) +add_subdirectory(backdoor) +add_subdirectory(bittorrent) +add_subdirectory(conn-size) +add_subdirectory(dce-rpc) +add_subdirectory(dhcp) +add_subdirectory(dns) +add_subdirectory(file) +add_subdirectory(finger) +add_subdirectory(ftp) +add_subdirectory(gnutella) +add_subdirectory(gtpv1) +add_subdirectory(http) +add_subdirectory(icmp) +add_subdirectory(ident) +add_subdirectory(interconn) +add_subdirectory(irc) +add_subdirectory(login) +add_subdirectory(modbus) +add_subdirectory(mime) +add_subdirectory(ncp) +add_subdirectory(netflow) +add_subdirectory(netbios) +add_subdirectory(ntp) +add_subdirectory(pia) +add_subdirectory(pop3) +add_subdirectory(rpc) +add_subdirectory(smb) +add_subdirectory(smtp) +add_subdirectory(socks) +add_subdirectory(ssh) +add_subdirectory(ssl) +add_subdirectory(stepping-stone) +add_subdirectory(syslog) +add_subdirectory(tcp) +add_subdirectory(teredo) +add_subdirectory(udp) +add_subdirectory(zip) diff --git a/src/ARP.cc b/src/analyzer/protocol/arp/ARP.cc similarity index 99% rename from src/ARP.cc rename to src/analyzer/protocol/arp/ARP.cc index 7ffd82764c..b3ef5383ce 100644 --- a/src/ARP.cc +++ b/src/analyzer/protocol/arp/ARP.cc @@ -1,10 +1,12 @@ // See the file "COPYING" in the main distribution directory for copyright. - #include "ARP.h" #include "Event.h" #include "Reporter.h" +#include "events.bif.h" + +using namespace analyzer::arp; ARP_Analyzer::ARP_Analyzer() { diff --git a/src/ARP.h b/src/analyzer/protocol/arp/ARP.h similarity index 89% rename from src/ARP.h rename to src/analyzer/protocol/arp/ARP.h index f4b623c513..f09dc6c398 100644 --- a/src/ARP.h +++ b/src/analyzer/protocol/arp/ARP.h @@ -1,7 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef arp_h -#define arp_h +#ifndef ANALYZER_PROTOCOL_ARP_ARP_H +#define ANALYZER_PROTOCOL_ARP_ARP_H #include "config.h" #include @@ -24,7 +24,9 @@ #endif #include "NetVar.h" +#include "PacketSort.h" +namespace analyzer { namespace arp { class ARP_Analyzer : public BroObj { public: @@ -53,4 +55,6 @@ protected: EventHandlerPtr arp_reply; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/arp/CMakeLists.txt b/src/analyzer/protocol/arp/CMakeLists.txt new file mode 100644 index 0000000000..eec6755a18 --- /dev/null +++ b/src/analyzer/protocol/arp/CMakeLists.txt @@ -0,0 +1,15 @@ + +# This is not an actual analyzer, but used by the core. We still +# maintain it here along with the other analyzers because conceptually +# it's also parsing a protocol just like them. The current structure +# is merely a left-over from when this code was written. + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro ARP) +bro_plugin_cc(ARP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() + diff --git a/src/analyzer/protocol/arp/Plugin.cc b/src/analyzer/protocol/arp/Plugin.cc new file mode 100644 index 0000000000..9045ef412f --- /dev/null +++ b/src/analyzer/protocol/arp/Plugin.cc @@ -0,0 +1,7 @@ + +#include "plugin/Plugin.h" + +BRO_PLUGIN_BEGIN(Bro, ARP) + BRO_PLUGIN_DESCRIPTION("ARP Parsing Code"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/arp/events.bif b/src/analyzer/protocol/arp/events.bif new file mode 100644 index 0000000000..efee33d7f4 --- /dev/null +++ b/src/analyzer/protocol/arp/events.bif @@ -0,0 +1,63 @@ +## Generated for ARP requests. +## +## See `Wikipedia `__ +## for more information about the ARP protocol. +## +## mac_src: The request's source MAC address. +## +## mac_dst: The request's destination MAC address. +## +## SPA: The sender protocol address. +## +## SHA: The sender hardware address. +## +## TPA: The target protocol address. +## +## THA: The target hardware address. +## +## .. bro:see:: arp_reply bad_arp +event arp_request%(mac_src: string, mac_dst: string, SPA: addr, SHA: string, + TPA: addr, THA: string%); + +## Generated for ARP replies. +## +## See `Wikipedia `__ +## for more information about the ARP protocol. +## +## mac_src: The reply's source MAC address. +## +## mac_dst: The reply's destination MAC address. +## +## SPA: The sender protocol address. +## +## SHA: The sender hardware address. +## +## TPA: The target protocol address. +## +## THA: The target hardware address. +## +## .. bro:see:: arp_request bad_arp +event arp_reply%(mac_src: string, mac_dst: string, SPA: addr, SHA: string, + TPA: addr, THA: string%); + +## Generated for ARP packets that Bro cannot interpret. Examples are packets +## with non-standard hardware address formats or hardware addresses that do not +## match the originator of the packet. +## +## SPA: The sender protocol address. +## +## SHA: The sender hardware address. +## +## TPA: The target protocol address. +## +## THA: The target hardware address. +## +## explanation: A short description of why the ARP packet is considered "bad". +## +## .. bro:see:: arp_reply arp_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event bad_arp%(SPA: addr, SHA: string, TPA: addr, THA: string, explanation: string%); diff --git a/src/AYIYA.cc b/src/analyzer/protocol/ayiya/AYIYA.cc similarity index 85% rename from src/AYIYA.cc rename to src/analyzer/protocol/ayiya/AYIYA.cc index 79fa44e743..070a3ef3e1 100644 --- a/src/AYIYA.cc +++ b/src/analyzer/protocol/ayiya/AYIYA.cc @@ -1,7 +1,12 @@ + #include "AYIYA.h" +#include "Func.h" +#include "events.bif.h" + +using namespace analyzer::ayiya; AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) -: Analyzer(AnalyzerTag::AYIYA, conn) +: Analyzer("AYIYA", conn) { interp = new binpac::AYIYA::AYIYA_Conn(this); } diff --git a/src/AYIYA.h b/src/analyzer/protocol/ayiya/AYIYA.h similarity index 56% rename from src/AYIYA.h rename to src/analyzer/protocol/ayiya/AYIYA.h index 79b41553c7..f5bb379cf4 100644 --- a/src/AYIYA.h +++ b/src/analyzer/protocol/ayiya/AYIYA.h @@ -1,9 +1,11 @@ -#ifndef AYIYA_h -#define AYIYA_h +#ifndef ANALYZER_PROTOCOL_AYIYA_AYIYA_H +#define ANALYZER_PROTOCOL_AYIYA_AYIYA_H #include "ayiya_pac.h" -class AYIYA_Analyzer : public Analyzer { +namespace analyzer { namespace ayiya { + +class AYIYA_Analyzer : public analyzer::Analyzer { public: AYIYA_Analyzer(Connection* conn); virtual ~AYIYA_Analyzer(); @@ -12,18 +14,15 @@ public: virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new AYIYA_Analyzer(conn); } - static bool Available() - { return BifConst::Tunnel::enable_ayiya && - BifConst::Tunnel::max_depth > 0; } - protected: - friend class AnalyzerTimer; void ExpireTimer(double t); binpac::AYIYA::AYIYA_Conn* interp; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/ayiya/CMakeLists.txt b/src/analyzer/protocol/ayiya/CMakeLists.txt new file mode 100644 index 0000000000..ae23c25e2d --- /dev/null +++ b/src/analyzer/protocol/ayiya/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro AYIYA) +bro_plugin_cc(AYIYA.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(ayiya.pac ayiya-protocol.pac ayiya-analyzer.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/ayiya/Plugin.cc b/src/analyzer/protocol/ayiya/Plugin.cc new file mode 100644 index 0000000000..0fc96eff3c --- /dev/null +++ b/src/analyzer/protocol/ayiya/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "AYIYA.h" + +BRO_PLUGIN_BEGIN(Bro, AYIYA) + BRO_PLUGIN_DESCRIPTION("AYIYA Analyzer"); + BRO_PLUGIN_ANALYZER("AYIYA", ayiya::AYIYA_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/ayiya-analyzer.pac b/src/analyzer/protocol/ayiya/ayiya-analyzer.pac similarity index 100% rename from src/ayiya-analyzer.pac rename to src/analyzer/protocol/ayiya/ayiya-analyzer.pac diff --git a/src/ayiya-protocol.pac b/src/analyzer/protocol/ayiya/ayiya-protocol.pac similarity index 100% rename from src/ayiya-protocol.pac rename to src/analyzer/protocol/ayiya/ayiya-protocol.pac diff --git a/src/ayiya.pac b/src/analyzer/protocol/ayiya/ayiya.pac similarity index 81% rename from src/ayiya.pac rename to src/analyzer/protocol/ayiya/ayiya.pac index 58fa196c15..b1f3a6ef77 100644 --- a/src/ayiya.pac +++ b/src/analyzer/protocol/ayiya/ayiya.pac @@ -1,6 +1,11 @@ + %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer AYIYA withcontext { connection: AYIYA_Conn; flow: AYIYA_Flow; diff --git a/src/analyzer/protocol/ayiya/events.bif b/src/analyzer/protocol/ayiya/events.bif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/BackDoor.cc b/src/analyzer/protocol/backdoor/BackDoor.cc similarity index 98% rename from src/BackDoor.cc rename to src/analyzer/protocol/backdoor/BackDoor.cc index c218a98ce2..a466938ff6 100644 --- a/src/BackDoor.cc +++ b/src/analyzer/protocol/backdoor/BackDoor.cc @@ -5,9 +5,13 @@ #include "BackDoor.h" #include "Event.h" #include "Net.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" -BackDoorEndpoint::BackDoorEndpoint(TCP_Endpoint* e) +#include "events.bif.h" + +using namespace analyzer::backdoor; + +BackDoorEndpoint::BackDoorEndpoint(tcp::TCP_Endpoint* e) { endp = e; is_partial = 0; @@ -53,7 +57,7 @@ int BackDoorEndpoint::DataSent(double /* t */, int seq, if ( len <= 0 ) return 0; - if ( endp->state == TCP_ENDPOINT_PARTIAL ) + if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; int ack = endp->AckSeq() - endp->StartSeq(); @@ -681,7 +685,7 @@ int BackDoorEndpoint::CheckForString(const char* str, BackDoor_Analyzer::BackDoor_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::Backdoor, c) +: tcp::TCP_ApplicationAnalyzer("BACKDOOR", c) { orig_endp = resp_endp = 0; @@ -701,7 +705,7 @@ BackDoor_Analyzer::~BackDoor_Analyzer() void BackDoor_Analyzer::Init() { - TCP_ApplicationAnalyzer::Init(); + tcp::TCP_ApplicationAnalyzer::Init(); assert(TCP()); orig_endp = new BackDoorEndpoint(TCP()->Orig()); @@ -740,7 +744,7 @@ void BackDoor_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) void BackDoor_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( ! IsFinished() ) { diff --git a/src/BackDoor.h b/src/analyzer/protocol/backdoor/BackDoor.h similarity index 82% rename from src/BackDoor.h rename to src/analyzer/protocol/backdoor/BackDoor.h index 40ea3bbaa3..5bc8a67381 100644 --- a/src/BackDoor.h +++ b/src/analyzer/protocol/backdoor/BackDoor.h @@ -1,16 +1,18 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef backdoor_h -#define backdoor_h +#ifndef ANALYZER_PROTOCOL_BACKDOOR_BACKDOOR_H +#define ANALYZER_PROTOCOL_BACKDOOR_BACKDOOR_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "Timer.h" #include "NetVar.h" -#include "Login.h" +#include "analyzer/protocol/login/Login.h" + +namespace analyzer { namespace backdoor { class BackDoorEndpoint { public: - BackDoorEndpoint(TCP_Endpoint* e); + BackDoorEndpoint(tcp::TCP_Endpoint* e); int DataSent(double t, int seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); @@ -44,7 +46,7 @@ protected: int CheckForFullString(const char* str, const u_char* data, int len); int CheckForString(const char* str, const u_char* data, int len); - TCP_Endpoint* endp; + tcp::TCP_Endpoint* endp; int is_partial; int max_top_seq; @@ -62,7 +64,7 @@ protected: uint32 num_7bit_ascii; }; -class BackDoor_Analyzer : public TCP_ApplicationAnalyzer { +class BackDoor_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: BackDoor_Analyzer(Connection* c); ~BackDoor_Analyzer(); @@ -71,18 +73,9 @@ public: virtual void Done(); void StatTimer(double t, int is_expire); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new BackDoor_Analyzer(conn); } - static bool Available() - { - return backdoor_stats || rlogin_signature_found || - telnet_signature_found || ssh_signature_found || - root_backdoor_signature_found || ftp_signature_found || - napster_signature_found || kazaa_signature_found || - http_signature_found || http_proxy_signature_found; - } - protected: // We support both packet and stream input, and can be instantiated // even if the TCP analyzer is not yet reassembling. @@ -114,4 +107,6 @@ protected: BackDoor_Analyzer* analyzer; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/backdoor/CMakeLists.txt b/src/analyzer/protocol/backdoor/CMakeLists.txt new file mode 100644 index 0000000000..5df04769f6 --- /dev/null +++ b/src/analyzer/protocol/backdoor/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro BackDoor) +bro_plugin_cc(BackDoor.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/backdoor/Plugin.cc b/src/analyzer/protocol/backdoor/Plugin.cc new file mode 100644 index 0000000000..0983aaf5d3 --- /dev/null +++ b/src/analyzer/protocol/backdoor/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "BackDoor.h" + +BRO_PLUGIN_BEGIN(Bro, BackDoor) + BRO_PLUGIN_DESCRIPTION("Backdoor Analyzer (deprecated)"); + BRO_PLUGIN_ANALYZER("BackDoor", backdoor::BackDoor_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/backdoor/events.bif b/src/analyzer/protocol/backdoor/events.bif new file mode 100644 index 0000000000..81676ee43b --- /dev/null +++ b/src/analyzer/protocol/backdoor/events.bif @@ -0,0 +1,32 @@ +## Deprecated. Will be removed. +event backdoor_stats%(c: connection, os: backdoor_endp_stats, rs: backdoor_endp_stats%); + +## Deprecated. Will be removed. +event backdoor_remove_conn%(c: connection%); + +## Deprecated. Will be removed. +event ftp_signature_found%(c: connection%); + +## Deprecated. Will be removed. +event gnutella_signature_found%(c: connection%); + +## Deprecated. Will be removed. +event http_signature_found%(c: connection%); + +## Deprecated. Will be removed. +event irc_signature_found%(c: connection%); + +## Deprecated. Will be removed. +event telnet_signature_found%(c: connection, is_orig: bool, len: count%); + +## Deprecated. Will be removed. +event ssh_signature_found%(c: connection, is_orig: bool%); + +## Deprecated. Will be removed. +event rlogin_signature_found%(c: connection, is_orig: bool, num_null: count, len: count%); + +## Deprecated. Will be removed. +event smtp_signature_found%(c: connection%); + +## Deprecated. Will be removed. +event http_proxy_signature_found%(c: connection%); diff --git a/src/BitTorrent.cc b/src/analyzer/protocol/bittorrent/BitTorrent.cc similarity index 89% rename from src/BitTorrent.cc rename to src/analyzer/protocol/bittorrent/BitTorrent.cc index fa8fb09e43..99fd9dc132 100644 --- a/src/BitTorrent.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrent.cc @@ -1,10 +1,14 @@ // This code contributed by Nadi Sarrar. #include "BitTorrent.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" + +using namespace analyzer::bittorrent; BitTorrent_Analyzer::BitTorrent_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::BitTorrent, c) +: tcp::TCP_ApplicationAnalyzer("BITTORRENT", c) { interp = new binpac::BitTorrent::BitTorrent_Conn(this); stop_orig = stop_resp = false; @@ -18,7 +22,7 @@ BitTorrent_Analyzer::~BitTorrent_Analyzer() void BitTorrent_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); interp->FlowEOF(true); interp->FlowEOF(false); @@ -29,7 +33,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig) uint64& this_stream_len = orig ? stream_len_orig : stream_len_resp; bool& this_stop = orig ? stop_orig : stop_resp; - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); @@ -66,7 +70,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig) void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); // TODO: Code commented out for now. I think that shoving data that // is definitely wrong into the parser seems like a really bad idea. @@ -108,7 +112,7 @@ void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrent_Analyzer::EndpointEOF(bool is_orig) { - TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); interp->FlowEOF(is_orig); } diff --git a/src/BitTorrent.h b/src/analyzer/protocol/bittorrent/BitTorrent.h similarity index 62% rename from src/BitTorrent.h rename to src/analyzer/protocol/bittorrent/BitTorrent.h index f083cf4fc7..7739463052 100644 --- a/src/BitTorrent.h +++ b/src/analyzer/protocol/bittorrent/BitTorrent.h @@ -1,13 +1,15 @@ // This code contributed by Nadi Sarrar. -#ifndef bittorrent_h -#define bittorrent_h +#ifndef ANALYZER_PROTOCOL_BITTORRENT_BITTORRENT_H +#define ANALYZER_PROTOCOL_BITTORRENT_BITTORRENT_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "bittorrent_pac.h" -class BitTorrent_Analyzer : public TCP_ApplicationAnalyzer { +namespace analyzer { namespace bittorrent { + +class BitTorrent_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: BitTorrent_Analyzer(Connection* conn); virtual ~BitTorrent_Analyzer(); @@ -17,12 +19,9 @@ public: virtual void Undelivered(int seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new BitTorrent_Analyzer(conn); } - static bool Available() - { return bittorrent_peer_handshake || bittorrent_peer_piece; } - protected: void DeliverWeird(const char* msg, bool orig); @@ -31,4 +30,6 @@ protected: uint64 stream_len_orig, stream_len_resp; }; +} } // namespace analyzer::* + #endif diff --git a/src/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc similarity index 97% rename from src/BitTorrentTracker.cc rename to src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 12c5a199de..b32db9a8bd 100644 --- a/src/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -1,7 +1,9 @@ // This code contributed by Nadi Sarrar. #include "BitTorrentTracker.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" #include #include @@ -11,6 +13,8 @@ # define FMT_INT "%" PRId64 # define FMT_UINT "%" PRIu64 +using namespace analyzer::bittorrent; + static TableType* bt_tracker_headers = 0; static RecordType* bittorrent_peer; static TableType* bittorrent_peer_set; @@ -18,7 +22,7 @@ static RecordType* bittorrent_benc_value; static TableType* bittorrent_benc_dir; BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::BitTorrentTracker, c) +: tcp::TCP_ApplicationAnalyzer("BITTORRENT", c) { if ( ! bt_tracker_headers ) { @@ -74,13 +78,13 @@ BitTorrentTracker_Analyzer::~BitTorrentTracker_Analyzer() void BitTorrentTracker_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); } void BitTorrentTracker_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); @@ -205,7 +209,7 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data) void BitTorrentTracker_Analyzer::Undelivered(int seq, int len, bool orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); ProtocolViolation("BitTorrentTracker: cannot recover from content gap"); @@ -217,7 +221,7 @@ void BitTorrentTracker_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrentTracker_Analyzer::EndpointEOF(bool is_orig) { - TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); } void BitTorrentTracker_Analyzer::InitBencParser(void) diff --git a/src/BitTorrentTracker.h b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h similarity index 88% rename from src/BitTorrentTracker.h rename to src/analyzer/protocol/bittorrent/BitTorrentTracker.h index 3b9efe0430..b041e556b7 100644 --- a/src/BitTorrentTracker.h +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h @@ -1,12 +1,14 @@ // This code contributed by Nadi Sarrar. -#ifndef bittorrenttracker_h -#define bittorrenttracker_h +#ifndef ANALYZER_PROTOCOL_BITTORRENT_BITTORRENTTRACKER_H +#define ANALYZER_PROTOCOL_BITTORRENT_BITTORRENTTRACKER_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #define BTTRACKER_BUF 2048 +namespace analyzer { namespace bittorrent { + // If the following is defined, then the analyzer will store all of // the headers seen in tracker messages. //#define BTTRACKER_STORE_HEADERS 1 @@ -40,7 +42,7 @@ enum btt_benc_states { BENC_STATE_STR2, }; -class BitTorrentTracker_Analyzer : public TCP_ApplicationAnalyzer { +class BitTorrentTracker_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: BitTorrentTracker_Analyzer(Connection* conn); virtual ~BitTorrentTracker_Analyzer(); @@ -50,12 +52,9 @@ public: virtual void Undelivered(int seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new BitTorrentTracker_Analyzer(conn); } - static bool Available() - { return bt_tracker_request || bt_tracker_response; } - protected: void ClientRequest(int len, const u_char* data); void ServerReply(int len, const u_char* data); @@ -129,4 +128,6 @@ protected: bool stop_orig, stop_resp; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/bittorrent/CMakeLists.txt b/src/analyzer/protocol/bittorrent/CMakeLists.txt new file mode 100644 index 0000000000..630ea03498 --- /dev/null +++ b/src/analyzer/protocol/bittorrent/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro BitTorrent) +bro_plugin_cc(BitTorrent.cc BitTorrentTracker.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(bittorrent.pac bittorrent-analyzer.pac bittorrent-protocol.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/bittorrent/Plugin.cc b/src/analyzer/protocol/bittorrent/Plugin.cc new file mode 100644 index 0000000000..2da9972d0d --- /dev/null +++ b/src/analyzer/protocol/bittorrent/Plugin.cc @@ -0,0 +1,12 @@ + +#include "plugin/Plugin.h" + +#include "BitTorrent.h" +#include "BitTorrentTracker.h" + +BRO_PLUGIN_BEGIN(Bro, BitTorrent) + BRO_PLUGIN_DESCRIPTION("BitTorrent Analyzer"); + BRO_PLUGIN_ANALYZER("BitTorrent", bittorrent::BitTorrent_Analyzer); + BRO_PLUGIN_ANALYZER("BitTorrentTracker", bittorrent::BitTorrent_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/bittorrent-analyzer.pac b/src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac similarity index 100% rename from src/bittorrent-analyzer.pac rename to src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac diff --git a/src/bittorrent-protocol.pac b/src/analyzer/protocol/bittorrent/bittorrent-protocol.pac similarity index 100% rename from src/bittorrent-protocol.pac rename to src/analyzer/protocol/bittorrent/bittorrent-protocol.pac diff --git a/src/bittorrent.pac b/src/analyzer/protocol/bittorrent/bittorrent.pac similarity index 92% rename from src/bittorrent.pac rename to src/analyzer/protocol/bittorrent/bittorrent.pac index f6255902dd..39e53596dd 100644 --- a/src/bittorrent.pac +++ b/src/analyzer/protocol/bittorrent/bittorrent.pac @@ -5,6 +5,8 @@ %extern{ #define MSGLEN_LIMIT 0x40000 + +#include "events.bif.h" %} analyzer BitTorrent withcontext { diff --git a/src/analyzer/protocol/bittorrent/events.bif b/src/analyzer/protocol/bittorrent/events.bif new file mode 100644 index 0000000000..8c4ddc146f --- /dev/null +++ b/src/analyzer/protocol/bittorrent/events.bif @@ -0,0 +1,226 @@ +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_have bittorrent_peer_interested bittorrent_peer_keep_alive +## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_handshake%(c: connection, is_orig: bool, + reserved: string, info_hash: string, peer_id: string%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_keep_alive%(c: connection, is_orig: bool%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bittorrent_peer_choke%(c: connection, is_orig: bool%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request +## bittorrent_peer_unknown bittorrent_peer_weird +event bittorrent_peer_unchoke%(c: connection, is_orig: bool%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_keep_alive +## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_interested%(c: connection, is_orig: bool%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_not_interested%(c: connection, is_orig: bool%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_interested bittorrent_peer_keep_alive +## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_have%(c: connection, is_orig: bool, piece_index: count%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_cancel bittorrent_peer_choke bittorrent_peer_handshake +## bittorrent_peer_have bittorrent_peer_interested bittorrent_peer_keep_alive +## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_bitfield%(c: connection, is_orig: bool, bitfield: string%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_request%(c: connection, is_orig: bool, index: count, + begin: count, length: count%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_port +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_piece%(c: connection, is_orig: bool, index: count, + begin: count, piece_length: count%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bittorrent_peer_cancel%(c: connection, is_orig: bool, index: count, + begin: count, length: count%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown +## bittorrent_peer_weird +event bittorrent_peer_port%(c: connection, is_orig: bool, listen_port: port%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_weird +event bittorrent_peer_unknown%(c: connection, is_orig: bool, message_id: count, + data: string%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown +event bittorrent_peer_weird%(c: connection, is_orig: bool, msg: string%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bt_tracker_request%(c: connection, uri: string, + headers: bt_tracker_headers%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bt_tracker_response%(c: connection, status: count, + headers: bt_tracker_headers, + peers: bittorrent_peer_set, + benc: bittorrent_benc_dir%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bt_tracker_response_not_ok%(c: connection, status: count, + headers: bt_tracker_headers%); + +## TODO. +## +## See `Wikipedia `__ for +## more information about the BitTorrent protocol. +## +## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke +## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested +## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece +## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke +## bittorrent_peer_unknown bittorrent_peer_weird +event bt_tracker_weird%(c: connection, is_orig: bool, msg: string%); + diff --git a/src/analyzer/protocol/conn-size/CMakeLists.txt b/src/analyzer/protocol/conn-size/CMakeLists.txt new file mode 100644 index 0000000000..efaadef401 --- /dev/null +++ b/src/analyzer/protocol/conn-size/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro ConnSize) +bro_plugin_cc(ConnSize.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/ConnSizeAnalyzer.cc b/src/analyzer/protocol/conn-size/ConnSize.cc similarity index 92% rename from src/ConnSizeAnalyzer.cc rename to src/analyzer/protocol/conn-size/ConnSize.cc index a1b892f4db..b912fe3d2d 100644 --- a/src/ConnSizeAnalyzer.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -3,13 +3,15 @@ // See ConnSize.h for more extensive comments. -#include "ConnSizeAnalyzer.h" -#include "TCP.h" +#include "ConnSize.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "events.bif.h" +using namespace analyzer::conn_size; ConnSize_Analyzer::ConnSize_Analyzer(Connection* c) -: Analyzer(AnalyzerTag::ConnSize, c) +: Analyzer("CONNSIZE", c) { } diff --git a/src/ConnSizeAnalyzer.h b/src/analyzer/protocol/conn-size/ConnSize.h similarity index 65% rename from src/ConnSizeAnalyzer.h rename to src/analyzer/protocol/conn-size/ConnSize.h index 1fdd57bb15..25f096dd32 100644 --- a/src/ConnSizeAnalyzer.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -1,14 +1,15 @@ // See the file "COPYING" in the main distribution directory for copyright. // -#ifndef CONNSTATS_H -#define CONNSTATS_H +#ifndef ANALYZER_PROTOCOL_CONN_SIZE_CONNSIZE_H +#define ANALYZER_PROTOCOL_CONN_SIZE_CONNSIZE_H -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include "NetVar.h" +namespace analyzer { namespace conn_size { -class ConnSize_Analyzer : public Analyzer { +class ConnSize_Analyzer : public analyzer::Analyzer { public: ConnSize_Analyzer(Connection* c); virtual ~ConnSize_Analyzer(); @@ -20,11 +21,9 @@ public: virtual void UpdateConnVal(RecordVal *conn_val); virtual void FlipRoles(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new ConnSize_Analyzer(conn); } - static bool Available() { return BifConst::use_conn_size_analyzer ; } - protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen); @@ -36,4 +35,6 @@ protected: uint64_t resp_pkts; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/conn-size/Plugin.cc b/src/analyzer/protocol/conn-size/Plugin.cc new file mode 100644 index 0000000000..6993e15ff8 --- /dev/null +++ b/src/analyzer/protocol/conn-size/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "ConnSize.h" + +BRO_PLUGIN_BEGIN(Bro, ConnSize) + BRO_PLUGIN_DESCRIPTION("Connection size analyzer"); + BRO_PLUGIN_ANALYZER("ConnSize", conn_size::ConnSize_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/conn-size/events.bif b/src/analyzer/protocol/conn-size/events.bif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/analyzer/protocol/dce-rpc/CMakeLists.txt b/src/analyzer/protocol/dce-rpc/CMakeLists.txt new file mode 100644 index 0000000000..d9baa08acf --- /dev/null +++ b/src/analyzer/protocol/dce-rpc/CMakeLists.txt @@ -0,0 +1,12 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro DCE_RPC) +bro_plugin_cc(DCE_RPC.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(dce_rpc.pac dce_rpc-protocol.pac dce_rpc-analyzer.pac) +bro_plugin_pac(dce_rpc_simple.pac dce_rpc-protocol.pac epmapper.pac) +bro_plugin_end() + diff --git a/src/DCE_RPC.cc b/src/analyzer/protocol/dce-rpc/DCE_RPC.cc similarity index 95% rename from src/DCE_RPC.cc rename to src/analyzer/protocol/dce-rpc/DCE_RPC.cc index 21cb3be9a0..dd31cfa8a7 100644 --- a/src/DCE_RPC.cc +++ b/src/analyzer/protocol/dce-rpc/DCE_RPC.cc @@ -10,7 +10,12 @@ using namespace std; #include "DCE_RPC.h" #include "Sessions.h" -#include "DPM.h" + +#include "analyzer/Manager.h" + +#include "events.bif.h" + +using namespace analyzer::dce_rpc; #define xbyte(b, n) (((const u_char*) (b))[n]) @@ -26,7 +31,7 @@ static int uuid_index[] = { 12, 13, 14, 15 }; -const char* uuid_to_string(const u_char* uuid_data) +const char* analyzer::dce_rpc::uuid_to_string(const u_char* uuid_data) { static char s[1024]; char* sp = s; @@ -160,11 +165,11 @@ static void add_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr, // of the dce_rpc_endpoints table. // FIXME: Don't hard-code the timeout. - dpm->ExpectConnection(IPAddr(), addr.addr, addr.port, addr.proto, - AnalyzerTag::DCE_RPC, 5 * 60, 0); + analyzer_mgr->ScheduleAnalyzer(IPAddr(), addr.addr, addr.port, addr.proto, + "DCE_RPC", 5 * 60); } -DCE_RPC_Header::DCE_RPC_Header(Analyzer* a, const u_char* b) +DCE_RPC_Header::DCE_RPC_Header(analyzer::Analyzer* a, const u_char* b) { analyzer = a; bytes = b; @@ -183,7 +188,7 @@ DCE_RPC_Header::DCE_RPC_Header(Analyzer* a, const u_char* b) frag_len = extract_uint16(LittleEndian(), bytes + 8); } -DCE_RPC_Session::DCE_RPC_Session(Analyzer* a) +DCE_RPC_Session::DCE_RPC_Session(analyzer::Analyzer* a) : analyzer(a), if_uuid("00000000-0000-0000-0000-000000000000"), if_id(BifEnum::DCE_RPC_unknown_if) @@ -442,7 +447,7 @@ void DCE_RPC_Session::DeliverEpmapperMapResponse( Contents_DCE_RPC_Analyzer::Contents_DCE_RPC_Analyzer(Connection* conn, bool orig, DCE_RPC_Session* arg_session, bool speculative) -: TCP_SupportAnalyzer(AnalyzerTag::Contents_DCE_RPC, conn, orig) +: tcp::TCP_SupportAnalyzer("CONTENTS_DCE_RPC", conn, orig) { session = arg_session; msg_buf = 0; @@ -474,10 +479,10 @@ Contents_DCE_RPC_Analyzer::~Contents_DCE_RPC_Analyzer() void Contents_DCE_RPC_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); - TCP_Analyzer* tcp = - static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = + static_cast(Parent())->TCP(); if ( tcp->HadGap(orig) || tcp->IsPartial() ) return; @@ -566,7 +571,7 @@ bool Contents_DCE_RPC_Analyzer::ParseHeader() } DCE_RPC_Analyzer::DCE_RPC_Analyzer(Connection* conn, bool arg_speculative) -: TCP_ApplicationAnalyzer(AnalyzerTag::DCE_RPC, conn) +: tcp::TCP_ApplicationAnalyzer("DCE_RPC", conn) { session = new DCE_RPC_Session(this); speculative = arg_speculative; diff --git a/src/DCE_RPC.h b/src/analyzer/protocol/dce-rpc/DCE_RPC.h similarity index 87% rename from src/DCE_RPC.h rename to src/analyzer/protocol/dce-rpc/DCE_RPC.h index acdbf1637d..2abfb584b5 100644 --- a/src/DCE_RPC.h +++ b/src/analyzer/protocol/dce-rpc/DCE_RPC.h @@ -1,17 +1,21 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef dce_rpc_h -#define dce_rpc_h +#ifndef ANALYZER_PROTOCOL_DCE_RPC_DCE_RPC_H +#define ANALYZER_PROTOCOL_DCE_RPC_DCE_RPC_H // NOTE: This is a somewhat crude analyzer for DCE/RPC (used on Microsoft // Windows systems) and shouldn't be considered as stable. #include "NetVar.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/dce-rpc/events.bif.h" #include "IPAddr.h" #include "dce_rpc_simple_pac.h" + +namespace analyzer { namespace dce_rpc { + class UUID { public: UUID(); @@ -88,7 +92,7 @@ enum DCE_RPC_PTYPE { class DCE_RPC_Header { public: - DCE_RPC_Header(Analyzer* a, const u_char* bytes); + DCE_RPC_Header(analyzer::Analyzer* a, const u_char* bytes); BifEnum::dce_rpc_ptype PTYPE() const { return ptype; } int FragLen() const { return frag_len; } @@ -99,7 +103,7 @@ public: void SetBytes(const u_char* b) { bytes = b; } protected: - Analyzer* analyzer; + analyzer::Analyzer* analyzer; const u_char* bytes; BifEnum::dce_rpc_ptype ptype; int frag_len; @@ -112,7 +116,7 @@ protected: class DCE_RPC_Session { public: - DCE_RPC_Session(Analyzer* a); + DCE_RPC_Session(analyzer::Analyzer* a); virtual ~DCE_RPC_Session() {} virtual void DeliverPDU(int is_orig, int len, const u_char* data); @@ -135,7 +139,7 @@ protected: const binpac::DCE_RPC_Simple::DCE_RPC_PDU* pdu, const binpac::DCE_RPC_Simple::DCE_RPC_Response* resp); - Analyzer* analyzer; + analyzer::Analyzer* analyzer; UUID if_uuid; BifEnum::dce_rpc_if_id if_id; int opnum; @@ -145,7 +149,7 @@ protected: } mapped; }; -class Contents_DCE_RPC_Analyzer : public TCP_SupportAnalyzer { +class Contents_DCE_RPC_Analyzer : public tcp::TCP_SupportAnalyzer { public: Contents_DCE_RPC_Analyzer(Connection* conn, bool orig, DCE_RPC_Session* session, bool speculative); @@ -169,20 +173,19 @@ protected: DCE_RPC_Session* session; }; -class DCE_RPC_Analyzer : public TCP_ApplicationAnalyzer { +class DCE_RPC_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: DCE_RPC_Analyzer(Connection* conn, bool speculative = false); ~DCE_RPC_Analyzer(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new DCE_RPC_Analyzer(conn); } - static bool Available() - { return DCE_RPC_Session::any_dce_rpc_event(); } - protected: DCE_RPC_Session* session; bool speculative; }; +} } // namespace analyzer::* + #endif /* dce_rpc_h */ diff --git a/src/analyzer/protocol/dce-rpc/Plugin.cc b/src/analyzer/protocol/dce-rpc/Plugin.cc new file mode 100644 index 0000000000..d9f3ce16c8 --- /dev/null +++ b/src/analyzer/protocol/dce-rpc/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "DCE_RPC.h" + +BRO_PLUGIN_BEGIN(Bro, DCE_RPC) + BRO_PLUGIN_DESCRIPTION("DCE-RPC analyzer"); + BRO_PLUGIN_ANALYZER("DCE_RPC", dce_rpc::DCE_RPC_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_DCE_RPC"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/dce_rpc-analyzer.pac b/src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac similarity index 100% rename from src/dce_rpc-analyzer.pac rename to src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac diff --git a/src/dce_rpc-protocol.pac b/src/analyzer/protocol/dce-rpc/dce_rpc-protocol.pac similarity index 100% rename from src/dce_rpc-protocol.pac rename to src/analyzer/protocol/dce-rpc/dce_rpc-protocol.pac diff --git a/src/dce_rpc.pac b/src/analyzer/protocol/dce-rpc/dce_rpc.pac similarity index 83% rename from src/dce_rpc.pac rename to src/analyzer/protocol/dce-rpc/dce_rpc.pac index cbcd0cbdc4..632d2304a1 100644 --- a/src/dce_rpc.pac +++ b/src/analyzer/protocol/dce-rpc/dce_rpc.pac @@ -1,6 +1,10 @@ %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer DCE_RPC withcontext { connection: DCE_RPC_Conn; flow: DCE_RPC_Flow; diff --git a/src/dce_rpc_simple.pac b/src/analyzer/protocol/dce-rpc/dce_rpc_simple.pac similarity index 92% rename from src/dce_rpc_simple.pac rename to src/analyzer/protocol/dce-rpc/dce_rpc_simple.pac index f31c2a078b..1bf0387b1d 100644 --- a/src/dce_rpc_simple.pac +++ b/src/analyzer/protocol/dce-rpc/dce_rpc_simple.pac @@ -1,5 +1,9 @@ %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer DCE_RPC_Simple withcontext {}; %include dce_rpc-protocol.pac diff --git a/src/epmapper.pac b/src/analyzer/protocol/dce-rpc/epmapper.pac similarity index 100% rename from src/epmapper.pac rename to src/analyzer/protocol/dce-rpc/epmapper.pac diff --git a/src/analyzer/protocol/dce-rpc/events.bif b/src/analyzer/protocol/dce-rpc/events.bif new file mode 100644 index 0000000000..bdabb674fa --- /dev/null +++ b/src/analyzer/protocol/dce-rpc/events.bif @@ -0,0 +1,55 @@ +## TODO. +## +## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_request +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dce_rpc_message%(c: connection, is_orig: bool, ptype: dce_rpc_ptype, msg: string%); + +## TODO. +## +## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_message dce_rpc_request +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dce_rpc_bind%(c: connection, uuid: string%); + +## TODO. +## +## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dce_rpc_request%(c: connection, opnum: count, stub: string%); + +## TODO. +## +## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message +## dce_rpc_request rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dce_rpc_response%(c: connection, opnum: count, stub: string%); + +## TODO. +## +## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message +## dce_rpc_request dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event epm_map_response%(c: connection, uuid: string, p: port, h: addr%); + diff --git a/src/analyzer/protocol/dhcp/CMakeLists.txt b/src/analyzer/protocol/dhcp/CMakeLists.txt new file mode 100644 index 0000000000..646a11f9ab --- /dev/null +++ b/src/analyzer/protocol/dhcp/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro DHCP) +bro_plugin_cc(DHCP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(dhcp.pac dhcp-protocol.pac dhcp-analyzer.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/dhcp/DHCP.cc b/src/analyzer/protocol/dhcp/DHCP.cc new file mode 100644 index 0000000000..8d05aef37d --- /dev/null +++ b/src/analyzer/protocol/dhcp/DHCP.cc @@ -0,0 +1,29 @@ + +#include "DHCP.h" + +#include "events.bif.h" + +using namespace analyzer::dhcp; + +DHCP_Analyzer::DHCP_Analyzer(Connection* conn) +: Analyzer("DHCP", conn) + { + interp = new binpac::DHCP::DHCP_Conn(this); + } + +DHCP_Analyzer::~DHCP_Analyzer() + { + delete interp; + } + +void DHCP_Analyzer::Done() + { + Analyzer::Done(); + } + +void DHCP_Analyzer::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); + } diff --git a/src/analyzer/protocol/dhcp/DHCP.h b/src/analyzer/protocol/dhcp/DHCP.h new file mode 100644 index 0000000000..a1c06e8b85 --- /dev/null +++ b/src/analyzer/protocol/dhcp/DHCP.h @@ -0,0 +1,28 @@ +#ifndef ANALYZER_PROTOCOL_DHCP_DHCP_H +#define ANALYZER_PROTOCOL_DHCP_DHCP_H + +#include "analyzer/protocol/udp/UDP.h" + +#include "dhcp_pac.h" + +namespace analyzer { namespace dhcp { + +class DHCP_Analyzer : public analyzer::Analyzer { +public: + DHCP_Analyzer(Connection* conn); + virtual ~DHCP_Analyzer(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new DHCP_Analyzer(conn); } + +protected: + binpac::DHCP::DHCP_Conn* interp; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/dhcp/Plugin.cc b/src/analyzer/protocol/dhcp/Plugin.cc new file mode 100644 index 0000000000..73603f8cb1 --- /dev/null +++ b/src/analyzer/protocol/dhcp/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "DHCP.h" + +BRO_PLUGIN_BEGIN(Bro, DHCP) + BRO_PLUGIN_DESCRIPTION("DHCP analyzer"); + BRO_PLUGIN_ANALYZER("DHCP", dhcp::DHCP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/dhcp-analyzer.pac b/src/analyzer/protocol/dhcp/dhcp-analyzer.pac similarity index 100% rename from src/dhcp-analyzer.pac rename to src/analyzer/protocol/dhcp/dhcp-analyzer.pac diff --git a/src/dhcp-protocol.pac b/src/analyzer/protocol/dhcp/dhcp-protocol.pac similarity index 100% rename from src/dhcp-protocol.pac rename to src/analyzer/protocol/dhcp/dhcp-protocol.pac diff --git a/src/dhcp.pac b/src/analyzer/protocol/dhcp/dhcp.pac similarity index 79% rename from src/dhcp.pac rename to src/analyzer/protocol/dhcp/dhcp.pac index 9e9d7755a4..c4a684badc 100644 --- a/src/dhcp.pac +++ b/src/analyzer/protocol/dhcp/dhcp.pac @@ -1,5 +1,9 @@ %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer DHCP withcontext { connection: DHCP_Conn; flow: DHCP_Flow; diff --git a/src/analyzer/protocol/dhcp/events.bif b/src/analyzer/protocol/dhcp/events.bif new file mode 100644 index 0000000000..741504185e --- /dev/null +++ b/src/analyzer/protocol/dhcp/events.bif @@ -0,0 +1,239 @@ +## Generated for DHCP messages of type *discover*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## req_addr: The specific address requested by the client. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_discover%(c: connection, msg: dhcp_msg, req_addr: addr%); + +## Generated for DHCP messages of type *offer*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: TODO. +## +## mask: The subnet mask specified by the message. +## +## router: The list of routers specified by the message. +## +## lease: The least interval specified by the message. +## +## serv_addr: The server address specified by the message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_offer%(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr%); + +## Generated for DHCP messages of type *request*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## req_addr: The client address specified by the message. +## +## serv_addr: The server address specified by the message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_request%(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr%); + +## Generated for DHCP messages of type *decline*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_decline%(c: connection, msg: dhcp_msg%); + +## Generated for DHCP messages of type *acknowledgment*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## mask: The subnet mask specified by the message. +## +## router: The list of routers specified by the message. +## +## lease: The least interval specified by the message. +## +## serv_addr: The server address specified by the message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_ack%(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr%); + +## Generated for DHCP messages of type *negative acknowledgment*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_nak%(c: connection, msg: dhcp_msg%); + +## Generated for DHCP messages of type *release*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_release%(c: connection, msg: dhcp_msg%); + +## Generated for DHCP messages of type *inform*. +## +## See `Wikipedia +## `__ for +## more information about the DHCP protocol. +## +## c: The connection record describing the underlying UDP flow. +## +## msg: The parsed type-independent part of the DHCP message. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request +## +## .. note:: Bro does not support broadcast packets (as used by the DHCP +## protocol). It treats broadcast addresses just like any other and +## associates packets into transport-level flows in the same way as usual. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event dhcp_inform%(c: connection, msg: dhcp_msg%); + diff --git a/src/analyzer/protocol/dns/CMakeLists.txt b/src/analyzer/protocol/dns/CMakeLists.txt new file mode 100644 index 0000000000..c63b2dc690 --- /dev/null +++ b/src/analyzer/protocol/dns/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro DNS) +bro_plugin_cc(DNS.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/DNS.cc b/src/analyzer/protocol/dns/DNS.cc similarity index 98% rename from src/DNS.cc rename to src/analyzer/protocol/dns/DNS.cc index a3b0b62ef3..4901df4417 100644 --- a/src/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -12,7 +12,11 @@ #include "Sessions.h" #include "Event.h" -DNS_Interpreter::DNS_Interpreter(Analyzer* arg_analyzer) +#include "events.bif.h" + +using namespace analyzer::dns; + +DNS_Interpreter::DNS_Interpreter(analyzer::Analyzer* arg_analyzer) { analyzer = arg_analyzer; } @@ -993,7 +997,7 @@ Val* DNS_MsgInfo::BuildTSIG_Val() Contents_DNS::Contents_DNS(Connection* conn, bool orig, DNS_Interpreter* arg_interp) -: TCP_SupportAnalyzer(AnalyzerTag::Contents_DNS, conn, orig) +: tcp::TCP_SupportAnalyzer("CONTENTS_DNS", conn, orig) { interp = arg_interp; @@ -1080,7 +1084,7 @@ void Contents_DNS::DeliverStream(int len, const u_char* data, bool orig) } DNS_Analyzer::DNS_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::DNS, conn) +: tcp::TCP_ApplicationAnalyzer("DNS", conn) { interp = new DNS_Interpreter(this); contents_dns_orig = contents_dns_resp = 0; @@ -1112,7 +1116,7 @@ void DNS_Analyzer::Init() void DNS_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( Conn()->ConnTransport() == TRANSPORT_UDP && ! did_session_done ) Event(udp_session_done); @@ -1123,7 +1127,7 @@ void DNS_Analyzer::Done() void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { - TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); if ( orig ) { @@ -1141,10 +1145,10 @@ void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, } -void DNS_Analyzer::ConnectionClosed(TCP_Endpoint* endpoint, TCP_Endpoint* peer, +void DNS_Analyzer::ConnectionClosed(tcp::TCP_Endpoint* endpoint, tcp::TCP_Endpoint* peer, int gen_event) { - TCP_ApplicationAnalyzer::ConnectionClosed(endpoint, peer, gen_event); + tcp::TCP_ApplicationAnalyzer::ConnectionClosed(endpoint, peer, gen_event); assert(contents_dns_orig && contents_dns_resp); contents_dns_orig->Flush(); diff --git a/src/DNS.h b/src/analyzer/protocol/dns/DNS.h similarity index 93% rename from src/DNS.h rename to src/analyzer/protocol/dns/DNS.h index 83ca80911e..373250e8f4 100644 --- a/src/DNS.h +++ b/src/analyzer/protocol/dns/DNS.h @@ -1,11 +1,13 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef dns_h -#define dns_h +#ifndef ANALYZER_PROTOCOL_DNS_DNS_H +#define ANALYZER_PROTOCOL_DNS_DNS_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "binpac_bro.h" +namespace analyzer { namespace dns { + typedef enum { DNS_OP_QUERY = 0, ///< standard query DNS_OP_IQUERY = 1, ///< reverse query @@ -149,7 +151,7 @@ public: class DNS_Interpreter { public: - DNS_Interpreter(Analyzer* analyzer); + DNS_Interpreter(analyzer::Analyzer* analyzer); int ParseMessage(const u_char* data, int len, int is_query); @@ -217,7 +219,7 @@ protected: const u_char*& data, int& len, BroString* question_name); - Analyzer* analyzer; + analyzer::Analyzer* analyzer; }; @@ -229,7 +231,7 @@ typedef enum { // Support analyzer which chunks the TCP stream into "packets". // ### This should be merged with TCP_Contents_RPC. -class Contents_DNS : public TCP_SupportAnalyzer { +class Contents_DNS : public tcp::TCP_SupportAnalyzer { public: Contents_DNS(Connection* c, bool orig, DNS_Interpreter* interp); ~Contents_DNS(); @@ -251,7 +253,7 @@ protected: }; // Works for both TCP and UDP. -class DNS_Analyzer : public TCP_ApplicationAnalyzer { +class DNS_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: DNS_Analyzer(Connection* conn); ~DNS_Analyzer(); @@ -261,20 +263,14 @@ public: virtual void Init(); virtual void Done(); - virtual void ConnectionClosed(TCP_Endpoint* endpoint, - TCP_Endpoint* peer, int gen_event); + virtual void ConnectionClosed(tcp::TCP_Endpoint* endpoint, + tcp::TCP_Endpoint* peer, int gen_event); void ExpireTimer(double t); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new DNS_Analyzer(conn); } - static bool Available() - { - return (dns_request || dns_full_request) && - ! FLAGS_use_binpac; - } - protected: DNS_Interpreter* interp; Contents_DNS* contents_dns_orig; @@ -285,4 +281,6 @@ protected: // FIXME: Doesn't really fit into new analyzer structure. What to do? int IsReuse(double t, const u_char* pkt); +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/dns/Plugin.cc b/src/analyzer/protocol/dns/Plugin.cc new file mode 100644 index 0000000000..bb96692cd0 --- /dev/null +++ b/src/analyzer/protocol/dns/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "DNS.h" + +BRO_PLUGIN_BEGIN(Bro, DNS) + BRO_PLUGIN_DESCRIPTION("DNS analyzer"); + BRO_PLUGIN_ANALYZER("DNS", dns::DNS_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_DNS"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/dns/events.bif b/src/analyzer/protocol/dns/events.bif new file mode 100644 index 0000000000..95c604a8b8 --- /dev/null +++ b/src/analyzer/protocol/dns/events.bif @@ -0,0 +1,482 @@ +## Generated for all DNS messages. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## msg: The parsed DNS message header. +## +## len: The length of the message's raw representation (i.e., the DNS payload). +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_query_reply dns_rejected +## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%); + +## Generated for DNS requests. For requests with multiple queries, this event +## is raised once for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## query: The queried name. +## +## qtype: The queried resource record type. +## +## qclass: The queried resource record class. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%); + +## Generated for DNS replies that reject a query. This event is raised if a DNS +## reply either indicates failure via its status code or does not pass on any +## answers to a query. Note that all of the event's parameters are parsed out of +## the reply; there's no stateful correlation with the query. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## query: The queried name. +## +## qtype: The queried resource record type. +## +## qclass: The queried resource record class. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%); + +## Generated for DNS replies with an *ok* status code but no question section. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## query: The queried name. +## +## qtype: The queried resource record type. +## +## qclass: The queried resource record class. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end +## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_rejected +## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_query_reply%(c: connection, msg: dns_msg, query: string, + qtype: count, qclass: count%); + +## Generated for DNS replies of type *A*. For replies with multiple answers, an +## individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## a: The address returned by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply +## dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_A_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%); + +## Generated for DNS replies of type *AAAA*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## a: The address returned by the reply. +## +## .. bro:see:: dns_A_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_AAAA_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%); + +## Generated for DNS replies of type *A6*. For replies with multiple answers, an +## individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## a: The address returned by the reply. +## +## .. bro:see:: dns_A_reply dns_AAAA_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_A6_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%); + +## Generated for DNS replies of type *NS*. For replies with multiple answers, an +## individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## name: The name returned by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_NS_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%); + +## Generated for DNS replies of type *CNAME*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## name: The name returned by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_CNAME_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%); + +## Generated for DNS replies of type *PTR*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## name: The name returned by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_SOA_reply dns_SRV_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_PTR_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%); + +## Generated for DNS replies of type *CNAME*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## soa: The parsed SOA value. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SRV_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_SOA_reply%(c: connection, msg: dns_msg, ans: dns_answer, soa: dns_soa%); + +## Generated for DNS replies of type *WKS*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_WKS_reply%(c: connection, msg: dns_msg, ans: dns_answer%); + +## Generated for DNS replies of type *HINFO*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_HINFO_reply%(c: connection, msg: dns_msg, ans: dns_answer%); + +## Generated for DNS replies of type *MX*. For replies with multiple answers, an +## individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## name: The name returned by the reply. +## +## preference: The preference for *name* specified by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, preference: count%); + +## Generated for DNS replies of type *TXT*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## str: The textual information returned by the reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%); + +## Generated for DNS replies of type *SRV*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_SRV_reply%(c: connection, msg: dns_msg, ans: dns_answer%); + +## Generated for DNS replies of type *EDNS*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The parsed EDNS reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_HINFO_reply dns_MX_reply +## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl +## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered +## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request +## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl +## dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_EDNS_addl%(c: connection, msg: dns_msg, ans: dns_edns_additional%); + +## Generated for DNS replies of type *TSIG*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The parsed TSIG reply. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TXT_reply dns_WKS_reply dns_end dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_TSIG_addl%(c: connection, msg: dns_msg, ans: dns_tsig_additional%); + +## Generated at the end of processing a DNS packet. This event is the last +## ``dns_*`` event that will be raised for a DNS query/reply and signals that +## all resource records have been passed on. +## +## See `Wikipedia `__ for more +## information about the DNS protocol. Bro analyzes both UDP and TCP DNS +## sessions. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl +## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply +## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_full_request +## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply +## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout +## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth +event dns_end%(c: connection, msg: dns_msg%); + +## Deprecated. Will be removed. +## +## .. todo:: Unclear what this event is for; it's never raised. We should just +## remove it. +event dns_full_request%(%); + +## msg: The raw DNS payload. +## +## .. note:: This event is deprecated and superseded by Bro's dynamic protocol +## detection framework. +event non_dns_request%(c: connection, msg: string%); diff --git a/src/analyzer/protocol/file/CMakeLists.txt b/src/analyzer/protocol/file/CMakeLists.txt new file mode 100644 index 0000000000..978c28c9c4 --- /dev/null +++ b/src/analyzer/protocol/file/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro File) +bro_plugin_cc(File.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/FileAnalyzer.cc b/src/analyzer/protocol/file/File.cc similarity index 71% rename from src/FileAnalyzer.cc rename to src/analyzer/protocol/file/File.cc index a43bba2246..d05e85df5d 100644 --- a/src/FileAnalyzer.cc +++ b/src/analyzer/protocol/file/File.cc @@ -1,19 +1,24 @@ #include +#include "File.h" + #include "file_analysis/Manager.h" -#include "FileAnalyzer.h" #include "Reporter.h" #include "util.h" -File_Analyzer::File_Analyzer(AnalyzerTag::Tag tag, Connection* conn) -: TCP_ApplicationAnalyzer(tag, conn) +#include "events.bif.h" + +using namespace analyzer::file; + +File_Analyzer::File_Analyzer(const char* name, Connection* conn) + : TCP_ApplicationAnalyzer(name, conn) { buffer_len = 0; } void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); int n = min(len, BUFFER_SIZE - buffer_len); @@ -35,7 +40,7 @@ void File_Analyzer::Undelivered(int seq, int len, bool orig) void File_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( buffer_len && buffer_len != BUFFER_SIZE ) Identify(); @@ -55,47 +60,47 @@ void File_Analyzer::Identify() } IRC_Data::IRC_Data(Connection* conn) - : File_Analyzer(AnalyzerTag::IRC_Data, conn) + : File_Analyzer("IRC_Data", conn) { } void IRC_Data::Done() { File_Analyzer::Done(); - file_mgr->EndOfFile(GetTag(), Conn()); + file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); } void IRC_Data::DeliverStream(int len, const u_char* data, bool orig) { File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetTag(), Conn(), orig); + file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); } void IRC_Data::Undelivered(int seq, int len, bool orig) { File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetTag(), Conn(), orig); + file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); } FTP_Data::FTP_Data(Connection* conn) - : File_Analyzer(AnalyzerTag::FTP_Data, conn) + : File_Analyzer("FTP_Data", conn) { } void FTP_Data::Done() { File_Analyzer::Done(); - file_mgr->EndOfFile(GetTag(), Conn()); + file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); } void FTP_Data::DeliverStream(int len, const u_char* data, bool orig) { File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetTag(), Conn(), orig); + file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); } void FTP_Data::Undelivered(int seq, int len, bool orig) { File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetTag(), Conn(), orig); + file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); } diff --git a/src/FileAnalyzer.h b/src/analyzer/protocol/file/File.h similarity index 61% rename from src/FileAnalyzer.h rename to src/analyzer/protocol/file/File.h index 59ec5cdb37..7afbd569c4 100644 --- a/src/FileAnalyzer.h +++ b/src/analyzer/protocol/file/File.h @@ -1,15 +1,17 @@ // Analyzer for connections that transfer binary data. -#ifndef FILEANALYZER_H -#define FILEANALYZER_H +#ifndef ANALYZER_PROTOCOL_FILE_FILE_H +#define ANALYZER_PROTOCOL_FILE_FILE_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include -class File_Analyzer : public TCP_ApplicationAnalyzer { +namespace analyzer { namespace file { + +class File_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: - File_Analyzer(AnalyzerTag::Tag tag, Connection* conn); + File_Analyzer(const char* name, Connection* conn); virtual void Done(); @@ -17,14 +19,10 @@ public: void Undelivered(int seq, int len, bool orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) - { return new File_Analyzer(AnalyzerTag::File, conn); } - - static bool Available() { return file_transferred; } +// static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) +// { return new File_Analyzer(conn); } protected: - File_Analyzer() {} - void Identify(); static const int BUFFER_SIZE = 1024; @@ -34,36 +32,32 @@ protected: class IRC_Data : public File_Analyzer { public: - IRC_Data(Connection* conn); virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(int seq, int len, bool orig); static Analyzer* InstantiateAnalyzer(Connection* conn) { return new IRC_Data(conn); } - - static bool Available() { return true; } }; class FTP_Data : public File_Analyzer { public: - FTP_Data(Connection* conn); virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(int seq, int len, bool orig); static Analyzer* InstantiateAnalyzer(Connection* conn) { return new FTP_Data(conn); } - - static bool Available() { return true; } }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/file/Plugin.cc b/src/analyzer/protocol/file/Plugin.cc new file mode 100644 index 0000000000..6e6adae90c --- /dev/null +++ b/src/analyzer/protocol/file/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "./File.h" + +BRO_PLUGIN_BEGIN(Bro, File) + BRO_PLUGIN_DESCRIPTION("Generic file analyzer"); + BRO_PLUGIN_ANALYZER("FTP_Data", file::FTP_Data); + BRO_PLUGIN_ANALYZER("IRC_Data", file::IRC_Data); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/file/events.bif b/src/analyzer/protocol/file/events.bif new file mode 100644 index 0000000000..4277f1975f --- /dev/null +++ b/src/analyzer/protocol/file/events.bif @@ -0,0 +1,3 @@ +## TODO. +## +event file_transferred%(c: connection, prefix: string, descr: string, mime_type: string%); diff --git a/src/analyzer/protocol/finger/CMakeLists.txt b/src/analyzer/protocol/finger/CMakeLists.txt new file mode 100644 index 0000000000..52dd3816f9 --- /dev/null +++ b/src/analyzer/protocol/finger/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Finger) +bro_plugin_cc(Finger.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/Finger.cc b/src/analyzer/protocol/finger/Finger.cc similarity index 80% rename from src/Finger.cc rename to src/analyzer/protocol/finger/Finger.cc index be0f3754b5..bf9bdcc68a 100644 --- a/src/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -7,27 +7,31 @@ #include "NetVar.h" #include "Finger.h" #include "Event.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +#include "events.bif.h" + +using namespace analyzer::finger; Finger_Analyzer::Finger_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::Finger, conn) +: tcp::TCP_ApplicationAnalyzer("FINGER", conn) { did_deliver = 0; - content_line_orig = new ContentLine_Analyzer(conn, true); + content_line_orig = new tcp::ContentLine_Analyzer(conn, true); content_line_orig->SetIsNULSensitive(true); - content_line_resp = new ContentLine_Analyzer(conn, false); + content_line_resp = new tcp::ContentLine_Analyzer(conn, false); AddSupportAnalyzer(content_line_orig); AddSupportAnalyzer(content_line_resp); } void Finger_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( TCP() ) if ( (! did_deliver || content_line_orig->HasPartialLine()) && - (TCP()->OrigState() == TCP_ENDPOINT_CLOSED || - TCP()->OrigPrevState() == TCP_ENDPOINT_CLOSED) ) + (TCP()->OrigState() == tcp::TCP_ENDPOINT_CLOSED || + TCP()->OrigPrevState() == tcp::TCP_ENDPOINT_CLOSED) ) // ### should include the partial text Weird("partial_finger_request"); } diff --git a/src/analyzer/protocol/finger/Finger.h b/src/analyzer/protocol/finger/Finger.h new file mode 100644 index 0000000000..efea0fae6b --- /dev/null +++ b/src/analyzer/protocol/finger/Finger.h @@ -0,0 +1,31 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_PROTOCOL_FINGER_FINGER_H +#define ANALYZER_PROTOCOL_FINGER_FINGER_H + +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +namespace analyzer { namespace finger { + +class Finger_Analyzer : public tcp::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::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new Finger_Analyzer(conn); } + +protected: + tcp::ContentLine_Analyzer* content_line_orig; + tcp::ContentLine_Analyzer* content_line_resp; + int did_deliver; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/finger/Plugin.cc b/src/analyzer/protocol/finger/Plugin.cc new file mode 100644 index 0000000000..6cf909ca54 --- /dev/null +++ b/src/analyzer/protocol/finger/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Finger.h" + +BRO_PLUGIN_BEGIN(Bro, Finger) + BRO_PLUGIN_DESCRIPTION("Finger analyzer"); + BRO_PLUGIN_ANALYZER("Finger", finger::Finger_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/finger/events.bif b/src/analyzer/protocol/finger/events.bif new file mode 100644 index 0000000000..e495263b12 --- /dev/null +++ b/src/analyzer/protocol/finger/events.bif @@ -0,0 +1,38 @@ +## Generated for Finger requests. +## +## See `Wikipedia `__ for more +## information about the Finger protocol. +## +## c: The connection. +## +## full: True if verbose information is requested (``/W`` switch). +## +## username: The request's user name. +## +## hostname: The request's host name. +## +## .. bro:see:: finger_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event finger_request%(c: connection, full: bool, username: string, hostname: string%); + +## Generated for Finger replies. +## +## See `Wikipedia `__ for more +## information about the Finger protocol. +## +## c: The connection. +## +## reply_line: The reply as returned by the server +## +## .. bro:see:: finger_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event finger_reply%(c: connection, reply_line: string%); + diff --git a/src/analyzer/protocol/ftp/CMakeLists.txt b/src/analyzer/protocol/ftp/CMakeLists.txt new file mode 100644 index 0000000000..ab657f9260 --- /dev/null +++ b/src/analyzer/protocol/ftp/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro FTP) +bro_plugin_cc(FTP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() diff --git a/src/FTP.cc b/src/analyzer/protocol/ftp/FTP.cc similarity index 89% rename from src/FTP.cc rename to src/analyzer/protocol/ftp/FTP.cc index 5e7a66e304..91afe6f8a4 100644 --- a/src/FTP.cc +++ b/src/analyzer/protocol/ftp/FTP.cc @@ -6,23 +6,27 @@ #include "NetVar.h" #include "FTP.h" -#include "NVT.h" #include "Event.h" -#include "SSL.h" #include "Base64.h" +#include "analyzer/Manager.h" +#include "analyzer/protocol/login/NVT.h" + +#include "events.bif.h" + +using namespace analyzer::ftp; FTP_Analyzer::FTP_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::FTP, conn) +: tcp::TCP_ApplicationAnalyzer("FTP", conn) { pending_reply = 0; - nvt_orig = new NVT_Analyzer(conn, true); + nvt_orig = new login::NVT_Analyzer(conn, true); nvt_orig->SetIsNULSensitive(true); nvt_orig->SetIsNULSensitive(true); nvt_orig->SetCRLFAsEOL(LF_as_EOL); nvt_orig->SetIsNULSensitive(LF_as_EOL); - nvt_resp = new NVT_Analyzer(conn, false); + nvt_resp = new login::NVT_Analyzer(conn, false); nvt_resp->SetIsNULSensitive(true); nvt_resp->SetIsNULSensitive(true); nvt_resp->SetCRLFAsEOL(LF_as_EOL); @@ -37,11 +41,11 @@ FTP_Analyzer::FTP_Analyzer(Connection* conn) void FTP_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( nvt_orig->HasPartialLine() && - (TCP()->OrigState() == TCP_ENDPOINT_CLOSED || - TCP()->OrigPrevState() == TCP_ENDPOINT_CLOSED) ) + (TCP()->OrigState() == tcp::TCP_ENDPOINT_CLOSED || + TCP()->OrigPrevState() == tcp::TCP_ENDPOINT_CLOSED) ) // ### should include the partial text Weird("partial_ftp_request"); } @@ -56,7 +60,7 @@ static uint32 get_reply_code(int len, const char* line) void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, data, orig); if ( (orig && ! ftp_request) || (! orig && ! ftp_reply) ) return; @@ -154,10 +158,13 @@ void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig) // Server wants to proceed with an ADAT exchange and we // know how to analyze the GSI mechanism, so attach analyzer // to look for that. - SSL_Analyzer* ssl = new SSL_Analyzer(Conn()); - ssl->AddSupportAnalyzer(new FTP_ADAT_Analyzer(Conn(), true)); - ssl->AddSupportAnalyzer(new FTP_ADAT_Analyzer(Conn(), false)); - AddChildAnalyzer(ssl); + Analyzer* ssl = analyzer_mgr->InstantiateAnalyzer("SSL", Conn()); + if ( ssl ) + { + ssl->AddSupportAnalyzer(new FTP_ADAT_Analyzer(Conn(), true)); + ssl->AddSupportAnalyzer(new FTP_ADAT_Analyzer(Conn(), false)); + AddChildAnalyzer(ssl); + } } vl->append(new Val(reply_code, TYPE_COUNT)); @@ -176,7 +183,7 @@ void FTP_ADAT_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { // Don't know how to parse anything but the ADAT exchanges of GSI GSSAPI, // which is basically just TLS/SSL. - if ( ! Parent()->GetTag() == AnalyzerTag::SSL ) + if ( ! Parent()->IsAnalyzer("SSL") ) { Parent()->Remove(); return; diff --git a/src/FTP.h b/src/analyzer/protocol/ftp/FTP.h similarity index 68% rename from src/FTP.h rename to src/analyzer/protocol/ftp/FTP.h index f8d7644808..1cffa19b1d 100644 --- a/src/FTP.h +++ b/src/analyzer/protocol/ftp/FTP.h @@ -1,31 +1,28 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef ftp_h -#define ftp_h +#ifndef ANALYZER_PROTOCOL_FTP_FTP_H +#define ANALYZER_PROTOCOL_FTP_FTP_H -#include "NVT.h" -#include "TCP.h" +#include "analyzer/protocol/login/NVT.h" +#include "analyzer/protocol/tcp/TCP.h" -class FTP_Analyzer : public TCP_ApplicationAnalyzer { +namespace analyzer { namespace ftp { + +class FTP_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: FTP_Analyzer(Connection* conn); virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new FTP_Analyzer(conn); } - static bool Available() { return ftp_request || ftp_reply; } - - protected: - FTP_Analyzer() {} - - NVT_Analyzer* nvt_orig; - NVT_Analyzer* nvt_resp; + login::NVT_Analyzer* nvt_orig; + login::NVT_Analyzer* nvt_resp; uint32 pending_reply; // code associated with multi-line reply, or 0 string auth_requested; // AUTH method requested }; @@ -37,10 +34,10 @@ protected: * analyzer just decodes the tokens and passes them on to the parent, which must * be an SSL analyzer instance. */ -class FTP_ADAT_Analyzer : public SupportAnalyzer { +class FTP_ADAT_Analyzer : public analyzer::SupportAnalyzer { public: FTP_ADAT_Analyzer(Connection* conn, bool arg_orig) - : SupportAnalyzer(AnalyzerTag::FTP_ADAT, conn, arg_orig), + : SupportAnalyzer("FTP_ADAT", conn, arg_orig), first_token(true) { } void DeliverStream(int len, const u_char* data, bool orig); @@ -52,4 +49,6 @@ protected: bool first_token; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/ftp/Plugin.cc b/src/analyzer/protocol/ftp/Plugin.cc new file mode 100644 index 0000000000..db8e20e7ed --- /dev/null +++ b/src/analyzer/protocol/ftp/Plugin.cc @@ -0,0 +1,12 @@ + +#include "plugin/Plugin.h" + +#include "FTP.h" + +BRO_PLUGIN_BEGIN(Bro, FTP) + BRO_PLUGIN_DESCRIPTION("FTP analyzer"); + BRO_PLUGIN_ANALYZER("FTP", ftp::FTP_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("FTP_ADAT"); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/ftp/events.bif b/src/analyzer/protocol/ftp/events.bif new file mode 100644 index 0000000000..16faa417d3 --- /dev/null +++ b/src/analyzer/protocol/ftp/events.bif @@ -0,0 +1,35 @@ +## Generated for client-side FTP commands. +## +## See `Wikipedia `__ for +## more information about the FTP protocol. +## +## c: The connection. +## +## command: The FTP command issued by the client (without any arguments). +## +## arg: The arguments going with the command. +## +## .. bro:see:: ftp_reply fmt_ftp_port parse_eftp_port +## parse_ftp_epsv parse_ftp_pasv parse_ftp_port +event ftp_request%(c: connection, command: string, arg: string%); + +## Generated for server-side FTP replies. +## +## See `Wikipedia `__ for +## more information about the FTP protocol. +## +## c: The connection. +## +## code: The numerical response code the server responded with. +## +## msg: The textual message of the response. +## +## cont_resp: True if the reply line is tagged as being continued to the next +## line. If so, further events will be raised and a handler may want +## to reassemble the pieces before processing the response any +## further. +## +## .. bro:see:: ftp_request fmt_ftp_port parse_eftp_port +## parse_ftp_epsv parse_ftp_pasv parse_ftp_port +event ftp_reply%(c: connection, code: count, msg: string, cont_resp: bool%); + diff --git a/src/analyzer/protocol/ftp/functions.bif b/src/analyzer/protocol/ftp/functions.bif new file mode 100644 index 0000000000..a667d8ca88 --- /dev/null +++ b/src/analyzer/protocol/ftp/functions.bif @@ -0,0 +1,220 @@ + +type ftp_port: record; + +%%{ + +static Val* parse_port(const char* line) + { + RecordVal* r = new RecordVal(BifType::Record::ftp_port); + + int bytes[6]; + if ( line && sscanf(line, "%d,%d,%d,%d,%d,%d", + &bytes[0], &bytes[1], &bytes[2], + &bytes[3], &bytes[4], &bytes[5]) == 6 ) + { + int good = 1; + + for ( int i = 0; i < 6; ++i ) + if ( bytes[i] < 0 || bytes[i] > 255 ) + { + good = 0; + break; + } + + uint32 addr = (bytes[0] << 24) | (bytes[1] << 16) | + (bytes[2] << 8) | bytes[3]; + uint32 port = (bytes[4] << 8) | bytes[5]; + + // Since port is unsigned, no need to check for < 0. + if ( port > 65535 ) + { + port = 0; + good = 0; + } + + r->Assign(0, new AddrVal(htonl(addr))); + r->Assign(1, new PortVal(port, TRANSPORT_TCP)); + r->Assign(2, new Val(good, TYPE_BOOL)); + } + else + { + r->Assign(0, new AddrVal(uint32(0))); + r->Assign(1, new PortVal(0, TRANSPORT_TCP)); + r->Assign(2, new Val(0, TYPE_BOOL)); + } + + return r; + } + +static Val* parse_eftp(const char* line) + { + RecordVal* r = new RecordVal(BifType::Record::ftp_port); + + int net_proto = 0; // currently not used + IPAddr addr; // unspecified IPv6 address (all 128 bits zero) + int port = 0; + int good = 0; + + if ( line ) + { + while ( isspace(*line) ) // skip whitespace + ++line; + + char delimiter = *line; + char* next_delim; + + if ( *line ) + { + good = 1; + ++line; // skip delimiter + + net_proto = strtol(line, &next_delim, 10); + if ( *next_delim != delimiter ) + good = 0; + + line = next_delim; + if ( *line ) + ++line; + + if ( *line && *line != delimiter ) + { + const char* nptr = strchr(line, delimiter); + if ( nptr == NULL ) + { + nptr = line + strlen(line); + good = 0; + } + + string s(line, nptr-line); // extract IP address + IPAddr tmp(s); + // on error, "tmp" will have all 128 bits zero + if ( tmp == addr ) + good = 0; + + addr = tmp; + } + + line = strchr(line, delimiter); + + if ( line != NULL ) + { + ++line; // now the port + port = strtol(line, &next_delim, 10); + if ( *next_delim != delimiter ) + good = 0; + } + + } + + } + + r->Assign(0, new AddrVal(addr)); + r->Assign(1, new PortVal(port, TRANSPORT_TCP)); + r->Assign(2, new Val(good, TYPE_BOOL)); + + return r; + } +%%} + +## Converts a string representation of the FTP PORT command to an ``ftp_port``. +## +## s: The string of the FTP PORT command, e.g., ``"10,0,0,1,4,31"``. +## +## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` +## +## .. bro:see:: parse_eftp_port parse_ftp_pasv parse_ftp_epsv fmt_ftp_port +function parse_ftp_port%(s: string%): ftp_port + %{ + return parse_port(s->CheckString()); + %} + +## Converts a string representation of the FTP EPRT command to an ``ftp_port``. +## See `RFC 2428 `_. +## The format is ``EPRT``, +## where ```` is a delimiter in the ASCII range 33-126 (usually ``|``). +## +## s: The string of the FTP EPRT command, e.g., ``"|1|10.0.0.1|1055|"``. +## +## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` +## +## .. bro:see:: parse_ftp_port parse_ftp_pasv parse_ftp_epsv fmt_ftp_port +function parse_eftp_port%(s: string%): ftp_port + %{ + return parse_eftp(s->CheckString()); + %} + +## Converts the result of the FTP PASV command to an ``ftp_port``. +## +## str: The string containing the result of the FTP PASV command. +## +## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` +## +## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_epsv fmt_ftp_port +function parse_ftp_pasv%(str: string%): ftp_port + %{ + const char* s = str->CheckString(); + const char* line = strchr(s, '('); + if ( line ) + ++line; // move past '(' + else if ( (line = strstr(s, "PORT")) ) + line += 5; // Skip over + else if ( (line = strchr(s, ',')) ) + { // Look for comma-separated list. + while ( --line >= s && isdigit(*line) ) + ; // Back up over preceding digits. + ++line; // now points to first digit, or beginning of s + } + + return parse_port(line); + %} + +## Converts the result of the FTP EPSV command to an ``ftp_port``. +## See `RFC 2428 `_. +## The format is `` ()``, where ```` is a +## delimiter in the ASCII range 33-126 (usually ``|``). +## +## str: The string containing the result of the FTP EPSV command. +## +## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` +## +## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_pasv fmt_ftp_port +function parse_ftp_epsv%(str: string%): ftp_port + %{ + const char* s = str->CheckString(); + const char* line = strchr(s, '('); + if ( line ) + ++line; // move past '(' + return parse_eftp(line); + %} + +## Formats an IP address and TCP port as an FTP PORT command. For example, +## ``10.0.0.1`` and ``1055/tcp`` yields ``"10,0,0,1,4,31"``. +## +## a: The IP address. +## +## p: The TCP port. +## +## Returns: The FTP PORT string. +## +## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_pasv parse_ftp_epsv +function fmt_ftp_port%(a: addr, p: port%): string + %{ + const uint32* addr; + int len = a->AsAddr().GetBytes(&addr); + if ( len == 1 ) + { + uint32 a = ntohl(addr[0]); + uint32 pn = p->Port(); + return new StringVal(fmt("%d,%d,%d,%d,%d,%d", + a >> 24, (a >> 16) & 0xff, + (a >> 8) & 0xff, a & 0xff, + pn >> 8, pn & 0xff)); + } + else + { + builtin_error("conversion of non-IPv4 address in fmt_ftp_port", + @ARG@[0]); + return new StringVal(""); + } + %} + diff --git a/src/analyzer/protocol/gnutella/CMakeLists.txt b/src/analyzer/protocol/gnutella/CMakeLists.txt new file mode 100644 index 0000000000..ee5415b924 --- /dev/null +++ b/src/analyzer/protocol/gnutella/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Gnutella) +bro_plugin_cc(Gnutella.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/Gnutella.cc b/src/analyzer/protocol/gnutella/Gnutella.cc similarity index 92% rename from src/Gnutella.cc rename to src/analyzer/protocol/gnutella/Gnutella.cc index 6b5e901bc5..c0bab92007 100644 --- a/src/Gnutella.cc +++ b/src/analyzer/protocol/gnutella/Gnutella.cc @@ -7,10 +7,14 @@ #include #include "NetVar.h" -#include "HTTP.h" #include "Gnutella.h" #include "Event.h" -#include "PIA.h" +#include "analyzer/protocol/pia/PIA.h" +#include "analyzer/Manager.h" + +#include "events.bif.h" + +using namespace analyzer::gnutella; GnutellaMsgState::GnutellaMsgState() { @@ -30,7 +34,7 @@ GnutellaMsgState::GnutellaMsgState() Gnutella_Analyzer::Gnutella_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::Gnutella, conn) +: tcp::TCP_ApplicationAnalyzer("GNUTELLA", conn) { state = 0; new_state = 0; @@ -50,7 +54,7 @@ Gnutella_Analyzer::~Gnutella_Analyzer() void Gnutella_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( ! sent_establish && (gnutella_establish || gnutella_not_establish) ) { @@ -129,17 +133,18 @@ int Gnutella_Analyzer::IsHTTP(string header) ConnectionEvent(gnutella_http_notify, vl); } - if ( HTTP_Analyzer::Available() ) + analyzer::Analyzer* a = analyzer_mgr->InstantiateAnalyzer("HTTP", Conn()); + + if ( a ) { - Analyzer* a = new HTTP_Analyzer(Conn()); Parent()->AddChildAnalyzer(a); - if ( Parent()->GetTag() == AnalyzerTag::TCP ) + if ( Parent()->IsAnalyzer("TCP") ) { // Replay buffered data. - PIA* pia = static_cast(Parent())->GetPIA(); + pia::PIA* pia = static_cast(Parent())->GetPIA(); if ( pia ) - static_cast(pia)->ReplayStreamBuffer(a); + static_cast(pia)->ReplayStreamBuffer(a); } Parent()->RemoveChildAnalyzer(this); @@ -327,7 +332,7 @@ void Gnutella_Analyzer::DeliverMessages(int len, const u_char* data, bool orig) void Gnutella_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); ms = orig ? orig_msg_state : resp_msg_state; ms->current_offset = 0; diff --git a/src/Gnutella.h b/src/analyzer/protocol/gnutella/Gnutella.h similarity index 78% rename from src/Gnutella.h rename to src/analyzer/protocol/gnutella/Gnutella.h index 455876462d..11d51cf276 100644 --- a/src/Gnutella.h +++ b/src/analyzer/protocol/gnutella/Gnutella.h @@ -1,9 +1,9 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef gnutella_h -#define gnutella_h +#ifndef ANALYZER_PROTOCOL_GNUTELLA_GNUTELLA_H +#define ANALYZER_PROTOCOL_GNUTELLA_GNUTELLA_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #define ORIG_OK 0x1 #define RESP_OK 0x2 @@ -11,6 +11,8 @@ #define GNUTELLA_MSG_SIZE 23 #define GNUTELLA_MAX_PAYLOAD 1024 +namespace analyzer { namespace gnutella { + class GnutellaMsgState { public: GnutellaMsgState (); @@ -32,7 +34,7 @@ public: }; -class Gnutella_Analyzer : public TCP_ApplicationAnalyzer { +class Gnutella_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: Gnutella_Analyzer(Connection* conn); ~Gnutella_Analyzer(); @@ -40,16 +42,9 @@ public: virtual void Done (); virtual void DeliverStream(int len, const u_char* data, bool orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Gnutella_Analyzer(conn); } - static bool Available() - { - return gnutella_text_msg || gnutella_binary_msg || - gnutella_partial_binary_msg || gnutella_establish || - gnutella_not_establish || gnutella_http_notify; - } - private: int NextLine(const u_char* data, int len); @@ -74,4 +69,6 @@ private: GnutellaMsgState* ms; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/gnutella/Plugin.cc b/src/analyzer/protocol/gnutella/Plugin.cc new file mode 100644 index 0000000000..73b91af002 --- /dev/null +++ b/src/analyzer/protocol/gnutella/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Gnutella.h" + +BRO_PLUGIN_BEGIN(Bro, Gnutella) + BRO_PLUGIN_DESCRIPTION("Gnutella analyzer"); + BRO_PLUGIN_ANALYZER("Gnutella", gnutella::Gnutella_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/gnutella/events.bif b/src/analyzer/protocol/gnutella/events.bif new file mode 100644 index 0000000000..9384f34e88 --- /dev/null +++ b/src/analyzer/protocol/gnutella/events.bif @@ -0,0 +1,88 @@ +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify +## gnutella_not_establish gnutella_partial_binary_msg gnutella_signature_found +## +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_text_msg%(c: connection, orig: bool, headers: string%); + +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_establish gnutella_http_notify gnutella_not_establish +## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_binary_msg%(c: connection, orig: bool, msg_type: count, + ttl: count, hops: count, msg_len: count, + payload: string, payload_len: count, + trunc: bool, complete: bool%); + +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify +## gnutella_not_establish gnutella_signature_found gnutella_text_msg +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_partial_binary_msg%(c: connection, orig: bool, + msg: string, len: count%); + +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_binary_msg gnutella_http_notify gnutella_not_establish +## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_establish%(c: connection%); + +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify +## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_not_establish%(c: connection%); + +## TODO. +## +## See `Wikipedia `__ for more +## information about the Gnutella protocol. +## +## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_not_establish +## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event gnutella_http_notify%(c: connection%); diff --git a/src/analyzer/protocol/gtpv1/CMakeLists.txt b/src/analyzer/protocol/gtpv1/CMakeLists.txt new file mode 100644 index 0000000000..b45f32e883 --- /dev/null +++ b/src/analyzer/protocol/gtpv1/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro GTPv1) +bro_plugin_cc(GTPv1.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(gtpv1.pac gtpv1-protocol.pac gtpv1-analyzer.pac) +bro_plugin_end() diff --git a/src/GTPv1.cc b/src/analyzer/protocol/gtpv1/GTPv1.cc similarity index 78% rename from src/GTPv1.cc rename to src/analyzer/protocol/gtpv1/GTPv1.cc index 68b6f30a0c..0a94a28554 100644 --- a/src/GTPv1.cc +++ b/src/analyzer/protocol/gtpv1/GTPv1.cc @@ -1,7 +1,13 @@ +// See the file "COPYING" in the main distribution directory for copyright. + #include "GTPv1.h" +#include "events.bif.h" + +using namespace analyzer::gtpv1; + GTPv1_Analyzer::GTPv1_Analyzer(Connection* conn) -: Analyzer(AnalyzerTag::GTPv1, conn) +: Analyzer("GTPV1", conn) { interp = new binpac::GTPv1::GTPv1_Conn(this); } diff --git a/src/GTPv1.h b/src/analyzer/protocol/gtpv1/GTPv1.h similarity index 56% rename from src/GTPv1.h rename to src/analyzer/protocol/gtpv1/GTPv1.h index e111158833..b58405ea7f 100644 --- a/src/GTPv1.h +++ b/src/analyzer/protocol/gtpv1/GTPv1.h @@ -1,9 +1,11 @@ -#ifndef GTPv1_h -#define GTPv1_h +#ifndef ANALYZER_PROTOCOL_GTPV1_GTPV1_H +#define ANALYZER_PROTOCOL_GTPV1_GTPV1_H #include "gtpv1_pac.h" -class GTPv1_Analyzer : public Analyzer { +namespace analyzer { namespace gtpv1 { + +class GTPv1_Analyzer : public analyzer::Analyzer { public: GTPv1_Analyzer(Connection* conn); virtual ~GTPv1_Analyzer(); @@ -12,18 +14,15 @@ public: virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new GTPv1_Analyzer(conn); } - static bool Available() - { return BifConst::Tunnel::enable_gtpv1 && - BifConst::Tunnel::max_depth > 0; } - protected: - friend class AnalyzerTimer; void ExpireTimer(double t); binpac::GTPv1::GTPv1_Conn* interp; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/gtpv1/Plugin.cc b/src/analyzer/protocol/gtpv1/Plugin.cc new file mode 100644 index 0000000000..83d1557e4d --- /dev/null +++ b/src/analyzer/protocol/gtpv1/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "GTPv1.h" + +BRO_PLUGIN_BEGIN(Bro, GTPv1) + BRO_PLUGIN_DESCRIPTION("GTPv1 analyzer"); + BRO_PLUGIN_ANALYZER("GTPv1", gtpv1::GTPv1_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/gtpv1/events.bif b/src/analyzer/protocol/gtpv1/events.bif new file mode 100644 index 0000000000..b3bac93a2e --- /dev/null +++ b/src/analyzer/protocol/gtpv1/events.bif @@ -0,0 +1,74 @@ +## Generated for any GTP message with a GTPv1 header. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +event gtpv1_message%(c: connection, hdr: gtpv1_hdr%); + +## Generated for GTPv1 G-PDU packets. That is, packets with a UDP payload +## that includes a GTP header followed by an IPv4 or IPv6 packet. +## +## outer: The GTP outer tunnel connection. +## +## inner_gtp: The GTP header. +## +## inner_ip: The inner IP and transport layer packet headers. +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event gtpv1_g_pdu_packet%(outer: connection, inner_gtp: gtpv1_hdr, inner_ip: pkt_hdr%); + +## Generated for GTPv1-C Create PDP Context Request messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_create_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_create_pdp_ctx_request_elements%); + +## Generated for GTPv1-C Create PDP Context Response messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_create_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_create_pdp_ctx_response_elements%); + +## Generated for GTPv1-C Update PDP Context Request messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_update_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_update_pdp_ctx_request_elements%); + +## Generated for GTPv1-C Update PDP Context Response messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_update_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_update_pdp_ctx_response_elements%); + +## Generated for GTPv1-C Delete PDP Context Request messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_delete_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_delete_pdp_ctx_request_elements%); + +## Generated for GTPv1-C Delete PDP Context Response messages. +## +## c: The connection over which the message is sent. +## +## hdr: The GTPv1 header. +## +## elements: The set of Information Elements comprising the message. +event gtpv1_delete_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_delete_pdp_ctx_response_elements%); + diff --git a/src/gtpv1-analyzer.pac b/src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac similarity index 100% rename from src/gtpv1-analyzer.pac rename to src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac diff --git a/src/gtpv1-protocol.pac b/src/analyzer/protocol/gtpv1/gtpv1-protocol.pac similarity index 100% rename from src/gtpv1-protocol.pac rename to src/analyzer/protocol/gtpv1/gtpv1-protocol.pac diff --git a/src/gtpv1.pac b/src/analyzer/protocol/gtpv1/gtpv1.pac similarity index 82% rename from src/gtpv1.pac rename to src/analyzer/protocol/gtpv1/gtpv1.pac index d155ecfd67..0305951cc5 100644 --- a/src/gtpv1.pac +++ b/src/analyzer/protocol/gtpv1/gtpv1.pac @@ -1,6 +1,10 @@ %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer GTPv1 withcontext { connection: GTPv1_Conn; flow: GTPv1_Flow; diff --git a/src/analyzer/protocol/http/CMakeLists.txt b/src/analyzer/protocol/http/CMakeLists.txt new file mode 100644 index 0000000000..d1fbed07f0 --- /dev/null +++ b/src/analyzer/protocol/http/CMakeLists.txt @@ -0,0 +1,11 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro HTTP) +bro_plugin_cc(HTTP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() + diff --git a/src/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc similarity index 90% rename from src/HTTP.cc rename to src/analyzer/protocol/http/HTTP.cc index 07868555e1..71c0052b4b 100644 --- a/src/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -11,9 +11,13 @@ #include "NetVar.h" #include "HTTP.h" #include "Event.h" -#include "MIME.h" +#include "analyzer/protocol/mime/MIME.h" #include "file_analysis/Manager.h" +#include "events.bif.h" + +using namespace analyzer::http; + const bool DEBUG_http = false; // The EXPECT_*_NOTHING states are used to prevent further parsing. Used if a @@ -82,7 +86,7 @@ void HTTP_Entity::Deliver(int len, const char* data, int trailing_CRLF) if ( end_of_data ) { // Multipart entities may have trailers - if ( content_type != CONTENT_TYPE_MULTIPART ) + if ( content_type != mime::CONTENT_TYPE_MULTIPART ) IllegalFormat("data trailing the end of entity"); return; } @@ -98,8 +102,8 @@ void HTTP_Entity::Deliver(int len, const char* data, int trailing_CRLF) } // Entity body. - if ( content_type == CONTENT_TYPE_MULTIPART || - content_type == CONTENT_TYPE_MESSAGE ) + if ( content_type == mime::CONTENT_TYPE_MULTIPART || + content_type == mime::CONTENT_TYPE_MESSAGE ) DeliverBody(len, data, trailing_CRLF); else if ( chunked_transfer_state != NON_CHUNKED_TRANSFER ) @@ -166,7 +170,7 @@ void HTTP_Entity::Deliver(int len, const char* data, int trailing_CRLF) DeliverBody(len, data, trailing_CRLF); } -class HTTP_Entity::UncompressedOutput : public Analyzer::OutputHandler { +class HTTP_Entity::UncompressedOutput : public analyzer::OutputHandler { public: UncompressedOutput(HTTP_Entity* e) { entity = e; } virtual ~UncompressedOutput() { } @@ -182,14 +186,14 @@ void HTTP_Entity::DeliverBody(int len, const char* data, int trailing_CRLF) { if ( encoding == GZIP || encoding == DEFLATE ) { - ZIP_Analyzer::Method method = + zip::ZIP_Analyzer::Method method = encoding == GZIP ? - ZIP_Analyzer::GZIP : ZIP_Analyzer::DEFLATE; + zip::ZIP_Analyzer::GZIP : zip::ZIP_Analyzer::DEFLATE; if ( ! zip ) { // We don't care about the direction here. - zip = new ZIP_Analyzer( + zip = new zip::ZIP_Analyzer( http_message->MyHTTP_Analyzer()->Conn(), false, method); zip->SetOutputHandler(new UncompressedOutput(this)); @@ -239,7 +243,7 @@ int HTTP_Entity::Undelivered(int64_t len) return 0; file_mgr->Gap(body_length, len, - http_message->MyHTTP_Analyzer()->GetTag(), + http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), http_message->IsOrig()); @@ -296,12 +300,12 @@ void HTTP_Entity::SubmitData(int len, const char* buf) { if ( send_size && instance_length > 0 ) file_mgr->SetSize(instance_length, - http_message->MyHTTP_Analyzer()->GetTag(), + http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), http_message->IsOrig()); file_mgr->DataIn(reinterpret_cast(buf), len, offset, - http_message->MyHTTP_Analyzer()->GetTag(), + http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), http_message->IsOrig()); @@ -311,12 +315,12 @@ void HTTP_Entity::SubmitData(int len, const char* buf) { if ( send_size && content_length > 0 ) file_mgr->SetSize(content_length, - http_message->MyHTTP_Analyzer()->GetTag(), + http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), http_message->IsOrig()); file_mgr->DataIn(reinterpret_cast(buf), len, - http_message->MyHTTP_Analyzer()->GetTag(), + http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), http_message->IsOrig()); } @@ -336,12 +340,12 @@ void HTTP_Entity::SetPlainDelivery(int64_t length) // expect_data_length. } -void HTTP_Entity::SubmitHeader(MIME_Header* h) +void HTTP_Entity::SubmitHeader(mime::MIME_Header* h) { - if ( strcasecmp_n(h->get_name(), "content-length") == 0 ) + if ( mime::strcasecmp_n(h->get_name(), "content-length") == 0 ) { data_chunk_t vt = h->get_value_token(); - if ( ! is_null_data_chunk(vt) ) + if ( ! mime::is_null_data_chunk(vt) ) { int64_t n; if ( atoi_n(vt.length, vt.data, 0, 10, n) ) @@ -352,7 +356,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h) } // Figure out content-length for HTTP 206 Partial Content response - else if ( strcasecmp_n(h->get_name(), "content-range") == 0 && + else if ( mime::strcasecmp_n(h->get_name(), "content-range") == 0 && http_message->MyHTTP_Analyzer()->HTTP_ReplyCode() == 206 ) { data_chunk_t vt = h->get_value_token(); @@ -422,19 +426,19 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h) } } - else if ( strcasecmp_n(h->get_name(), "transfer-encoding") == 0 ) + else if ( mime::strcasecmp_n(h->get_name(), "transfer-encoding") == 0 ) { data_chunk_t vt = h->get_value_token(); - if ( strcasecmp_n(vt, "chunked") == 0 ) + if ( mime::strcasecmp_n(vt, "chunked") == 0 ) chunked_transfer_state = BEFORE_CHUNK; } - else if ( strcasecmp_n(h->get_name(), "content-encoding") == 0 ) + else if ( mime::strcasecmp_n(h->get_name(), "content-encoding") == 0 ) { data_chunk_t vt = h->get_value_token(); - if ( strcasecmp_n(vt, "gzip") == 0 ) + if ( mime::strcasecmp_n(vt, "gzip") == 0 ) encoding = GZIP; - if ( strcasecmp_n(vt, "deflate") == 0 ) + if ( mime::strcasecmp_n(vt, "deflate") == 0 ) encoding = DEFLATE; } @@ -468,8 +472,8 @@ void HTTP_Entity::SubmitAllHeaders() return; } - if ( content_type == CONTENT_TYPE_MULTIPART || - content_type == CONTENT_TYPE_MESSAGE ) + if ( content_type == mime::CONTENT_TYPE_MULTIPART || + content_type == mime::CONTENT_TYPE_MESSAGE ) { // Do nothing. // Make sure that we check for multiple/message contents first, @@ -518,7 +522,7 @@ void HTTP_Entity::SubmitAllHeaders() } HTTP_Message::HTTP_Message(HTTP_Analyzer* arg_analyzer, - ContentLine_Analyzer* arg_cl, bool arg_is_orig, + tcp::ContentLine_Analyzer* arg_cl, bool arg_is_orig, int expect_body, int64_t init_header_length) : MIME_Message (arg_analyzer) { @@ -569,7 +573,7 @@ void HTTP_Message::Done(const int interrupted, const char* detail) if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) // multipart/byteranges may span multiple connections - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetTag(), + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), MyHTTP_Analyzer()->Conn(), is_orig); if ( http_message_done ) @@ -606,7 +610,7 @@ int HTTP_Message::Undelivered(int64_t len) return 0; } -void HTTP_Message::BeginEntity(MIME_Entity* entity) +void HTTP_Message::BeginEntity(mime::MIME_Entity* entity) { if ( DEBUG_http ) DEBUG_MSG("%.6f: begin entity (%d)\n", network_time, is_orig); @@ -622,7 +626,7 @@ void HTTP_Message::BeginEntity(MIME_Entity* entity) } } -void HTTP_Message::EndEntity(MIME_Entity* entity) +void HTTP_Message::EndEntity(mime::MIME_Entity* entity) { if ( DEBUG_http ) DEBUG_MSG("%.6f: end entity (%d)\n", network_time, is_orig); @@ -648,16 +652,16 @@ void HTTP_Message::EndEntity(MIME_Entity* entity) Done(); else if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetTag(), + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), MyHTTP_Analyzer()->Conn(), is_orig); } -void HTTP_Message::SubmitHeader(MIME_Header* h) +void HTTP_Message::SubmitHeader(mime::MIME_Header* h) { MyHTTP_Analyzer()->HTTP_Header(is_orig, h); } -void HTTP_Message::SubmitAllHeaders(MIME_HeaderList& hlist) +void HTTP_Message::SubmitAllHeaders(mime::MIME_HeaderList& hlist) { if ( http_all_headers ) { @@ -684,7 +688,7 @@ void HTTP_Message::SubmitAllHeaders(MIME_HeaderList& hlist) } } -void HTTP_Message::SubmitTrailingHeaders(MIME_HeaderList& /* hlist */) +void HTTP_Message::SubmitTrailingHeaders(mime::MIME_HeaderList& /* hlist */) { // Do nothing for now. } @@ -725,15 +729,15 @@ void HTTP_Message::SubmitEvent(int event_type, const char* detail) const char* category = ""; switch ( event_type ) { - case MIME_EVENT_ILLEGAL_FORMAT: + case mime::MIME_EVENT_ILLEGAL_FORMAT: category = "illegal format"; break; - case MIME_EVENT_ILLEGAL_ENCODING: + case mime::MIME_EVENT_ILLEGAL_ENCODING: category = "illegal encoding"; break; - case MIME_EVENT_CONTENT_GAP: + case mime::MIME_EVENT_CONTENT_GAP: category = "content gap"; break; @@ -848,7 +852,7 @@ void HTTP_Message::Weird(const char* msg) } HTTP_Analyzer::HTTP_Analyzer(Connection* conn) - : TCP_ApplicationAnalyzer(AnalyzerTag::HTTP, conn) +: tcp::TCP_ApplicationAnalyzer("HTTP", conn) { num_requests = num_replies = 0; num_request_lines = num_reply_lines = 0; @@ -868,10 +872,10 @@ HTTP_Analyzer::HTTP_Analyzer(Connection* conn) reply_code = 0; reply_reason_phrase = 0; - content_line_orig = new ContentLine_Analyzer(conn, true); + content_line_orig = new tcp::ContentLine_Analyzer(conn, true); AddSupportAnalyzer(content_line_orig); - content_line_resp = new ContentLine_Analyzer(conn, false); + content_line_resp = new tcp::ContentLine_Analyzer(conn, false); content_line_resp->SetSkipPartial(true); AddSupportAnalyzer(content_line_resp); } @@ -889,7 +893,7 @@ void HTTP_Analyzer::Done() if ( IsFinished() ) return; - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); RequestMade(1, "message interrupted when connection done"); ReplyMade(1, "message interrupted when connection done"); @@ -908,18 +912,18 @@ void HTTP_Analyzer::Done() unanswered_requests.pop(); } - file_mgr->EndOfFile(GetTag(), Conn(), true); + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), true); /* TODO: this might be nice to have, but reply code is cleared by now. if ( HTTP_ReplyCode() != 206 ) // multipart/byteranges may span multiple connections - file_mgr->EndOfFile(GetTag(), Conn(), false); + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), false); */ } void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); if ( TCP() && TCP()->IsPartial() ) return; @@ -927,7 +931,7 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) const char* line = reinterpret_cast(data); const char* end_of_line = line + len; - ContentLine_Analyzer* content_line = + tcp::ContentLine_Analyzer* content_line = is_orig ? content_line_orig : content_line_resp; if ( content_line->IsPlainDelivery() ) @@ -976,7 +980,7 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) { if ( ! RequestExpected() ) HTTP_Event("crud_trailing_HTTP_request", - new_string_val(line, end_of_line)); + mime::new_string_val(line, end_of_line)); else { // We do see HTTP requests with a @@ -1055,20 +1059,20 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); // DEBUG_MSG("Undelivered from %d: %d bytes\n", seq, length); HTTP_Message* msg = is_orig ? request_message : reply_message; - ContentLine_Analyzer* content_line = + tcp::ContentLine_Analyzer* content_line = is_orig ? content_line_orig : content_line_resp; if ( ! content_line->IsSkippedContents(seq, len) ) { if ( msg ) - msg->SubmitEvent(MIME_EVENT_CONTENT_GAP, + msg->SubmitEvent(mime::MIME_EVENT_CONTENT_GAP, fmt("seq=%d, len=%d", seq, len)); } @@ -1099,7 +1103,7 @@ void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) void HTTP_Analyzer::EndpointEOF(bool is_orig) { - TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); // DEBUG_MSG("%.6f eof\n", network_time); @@ -1111,7 +1115,7 @@ void HTTP_Analyzer::EndpointEOF(bool is_orig) void HTTP_Analyzer::ConnectionFinished(int half_finished) { - TCP_ApplicationAnalyzer::ConnectionFinished(half_finished); + tcp::TCP_ApplicationAnalyzer::ConnectionFinished(half_finished); // DEBUG_MSG("%.6f connection finished\n", network_time); RequestMade(1, "message ends as connection is finished"); @@ -1120,7 +1124,7 @@ void HTTP_Analyzer::ConnectionFinished(int half_finished) void HTTP_Analyzer::ConnectionReset() { - TCP_ApplicationAnalyzer::ConnectionReset(); + tcp::TCP_ApplicationAnalyzer::ConnectionReset(); RequestMade(1, "message interrupted by RST"); ReplyMade(1, "message interrupted by RST"); @@ -1128,7 +1132,7 @@ void HTTP_Analyzer::ConnectionReset() void HTTP_Analyzer::PacketWithRST() { - TCP_ApplicationAnalyzer::PacketWithRST(); + tcp::TCP_ApplicationAnalyzer::PacketWithRST(); RequestMade(1, "message interrupted by RST"); ReplyMade(1, "message interrupted by RST"); @@ -1272,10 +1276,10 @@ int HTTP_Analyzer::ParseRequest(const char* line, const char* end_of_line) version_end = version_start + 3; if ( skip_whitespace(version_end, end_of_line) != end_of_line ) HTTP_Event("crud after HTTP version is ignored", - new_string_val(line, end_of_line)); + mime::new_string_val(line, end_of_line)); } else - HTTP_Event("bad_HTTP_version", new_string_val(line, end_of_line)); + HTTP_Event("bad_HTTP_version", mime::new_string_val(line, end_of_line)); } // NormalizeURI(line, end_of_uri); @@ -1299,7 +1303,7 @@ double HTTP_Analyzer::HTTP_Version(int len, const char* data) } else { - HTTP_Event("bad_HTTP_version", new_string_val(len, data)); + HTTP_Event("bad_HTTP_version", mime::new_string_val(len, data)); return 0; } } @@ -1478,20 +1482,20 @@ int HTTP_Analyzer::HTTP_ReplyLine(const char* line, const char* end_of_line) // ##TODO: some server replies with an HTML document // without a status line and a MIME header, when the // request is malformed. - HTTP_Event("bad_HTTP_reply", new_string_val(line, end_of_line)); + HTTP_Event("bad_HTTP_reply", mime::new_string_val(line, end_of_line)); return 0; } SetVersion(reply_version, HTTP_Version(end_of_line - rest, rest)); for ( ; rest < end_of_line; ++rest ) - if ( is_lws(*rest) ) + if ( mime::is_lws(*rest) ) break; if ( rest >= end_of_line ) { HTTP_Event("HTTP_reply_code_missing", - new_string_val(line, end_of_line)); + mime::new_string_val(line, end_of_line)); return 0; } @@ -1500,20 +1504,20 @@ int HTTP_Analyzer::HTTP_ReplyLine(const char* line, const char* end_of_line) if ( rest + 3 > end_of_line ) { HTTP_Event("HTTP_reply_code_missing", - new_string_val(line, end_of_line)); + mime::new_string_val(line, end_of_line)); return 0; } reply_code = HTTP_ReplyCode(rest); for ( rest += 3; rest < end_of_line; ++rest ) - if ( is_lws(*rest) ) + if ( mime::is_lws(*rest) ) break; if ( rest >= end_of_line ) { HTTP_Event("HTTP_reply_reason_phrase_missing", - new_string_val(line, end_of_line)); + mime::new_string_val(line, end_of_line)); // Tolerate missing reason phrase? return 1; } @@ -1560,7 +1564,7 @@ int HTTP_Analyzer::ExpectReplyMessageBody() return HTTP_BODY_EXPECTED; } -void HTTP_Analyzer::HTTP_Header(int is_orig, MIME_Header* h) +void HTTP_Analyzer::HTTP_Header(int is_orig, mime::MIME_Header* h) { #if 0 // ### Only call ParseVersion if we're tracking versions: @@ -1577,16 +1581,16 @@ void HTTP_Analyzer::HTTP_Header(int is_orig, MIME_Header* h) // side, and if seen assume the connection to be persistent. // This seems fairly safe - at worst, the client does indeed // send additional requests, and the server ignores them. - if ( is_orig && strcasecmp_n(h->get_name(), "connection") == 0 ) + if ( is_orig && mime::strcasecmp_n(h->get_name(), "connection") == 0 ) { - if ( strcasecmp_n(h->get_value_token(), "keep-alive") == 0 ) + if ( mime::strcasecmp_n(h->get_value_token(), "keep-alive") == 0 ) keep_alive = 1; } if ( ! is_orig && - strcasecmp_n(h->get_name(), "connection") == 0 ) + mime::strcasecmp_n(h->get_name(), "connection") == 0 ) { - if ( strcasecmp_n(h->get_value_token(), "close") == 0 ) + if ( mime::strcasecmp_n(h->get_value_token(), "close") == 0 ) connection_close = 1; } @@ -1609,8 +1613,8 @@ void HTTP_Analyzer::HTTP_Header(int is_orig, MIME_Header* h) val_list* vl = new val_list(); vl->append(BuildConnVal()); vl->append(new Val(is_orig, TYPE_BOOL)); - vl->append(new_string_val(h->get_name())->ToUpper()); - vl->append(new_string_val(h->get_value())); + vl->append(mime::new_string_val(h->get_name())->ToUpper()); + vl->append(mime::new_string_val(h->get_value())); if ( DEBUG_http ) DEBUG_MSG("%.6f http_header\n", network_time); ConnectionEvent(http_header, vl); @@ -1639,7 +1643,7 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, while ( len > 0 ) { // Skip white space. - while ( len && is_lws(*data) ) + while ( len && mime::is_lws(*data) ) { ++data; --len; @@ -1652,7 +1656,7 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, // Find end of comment. const char* data_start = data; const char* eoc = - data + MIME_skip_lws_comments(len, data); + data + mime::MIME_skip_lws_comments(len, data); // Split into parts. // (This may get confused by nested comments, @@ -1662,7 +1666,7 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, while ( 1 ) { // Eat spaces. - while ( data < eoc && is_lws(*data) ) + while ( data < eoc && mime::is_lws(*data) ) ++data; // Find end of token. @@ -1675,7 +1679,7 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, break; // Delete spaces at end of token. - for ( ; eot > data && is_lws(*(eot-1)); --eot ) + for ( ; eot > data && mime::is_lws(*(eot-1)); --eot ) ; if ( data != eot && software_version_found ) @@ -1688,7 +1692,7 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, continue; } - offset = MIME_get_slash_token_pair(len, data, + offset = mime::MIME_get_slash_token_pair(len, data, &product, &product_version); if ( offset < 0 ) { @@ -1696,10 +1700,10 @@ void HTTP_Analyzer::ParseVersion(data_chunk_t ver, const IPAddr& host, // so we do not complain in the final version if ( num_version == 0 ) HTTP_Event("bad_HTTP_version", - new_string_val(len, data)); + mime::new_string_val(len, data)); // Try to simply skip next token. - offset = MIME_get_token(len, data, &product); + offset = mime::MIME_get_token(len, data, &product); if ( offset < 0 ) break; @@ -1763,7 +1767,7 @@ void HTTP_Analyzer::HTTP_MessageDone(int is_orig, HTTP_Message* /* message */) ReplyMade(0, "message ends normally"); } -void HTTP_Analyzer::InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, +void HTTP_Analyzer::InitHTTPMessage(tcp::ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig, int expect_body, int64_t init_header_length) { if ( message ) @@ -1787,25 +1791,25 @@ void HTTP_Analyzer::SkipEntityData(int is_orig) msg->SkipEntityData(); } -int is_reserved_URI_char(unsigned char ch) +int analyzer::http::is_reserved_URI_char(unsigned char ch) { // see RFC 2396 (definition of URI) return strchr(";/?:@&=+$,", ch) != 0; } -int is_unreserved_URI_char(unsigned char ch) +int analyzer::http::is_unreserved_URI_char(unsigned char ch) { // see RFC 2396 (definition of URI) return isalnum(ch) || strchr("-_.!~*\'()", ch) != 0; } -void escape_URI_char(unsigned char ch, unsigned char*& p) +void analyzer::http::escape_URI_char(unsigned char ch, unsigned char*& p) { *p++ = '%'; *p++ = encode_hex((ch >> 4) & 0xf); *p++ = encode_hex(ch & 0xf); } -BroString* unescape_URI(const u_char* line, const u_char* line_end, - Analyzer* analyzer) +BroString* analyzer::http::unescape_URI(const u_char* line, const u_char* line_end, + analyzer::Analyzer* analyzer) { byte_vec decoded_URI = new u_char[line_end - line + 1]; byte_vec URI_p = decoded_URI; diff --git a/src/HTTP.h b/src/analyzer/protocol/http/HTTP.h similarity index 81% rename from src/HTTP.h rename to src/analyzer/protocol/http/HTTP.h index 81c7385825..8339e48e3b 100644 --- a/src/HTTP.h +++ b/src/analyzer/protocol/http/HTTP.h @@ -1,14 +1,19 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef http_h -#define http_h +#ifndef ANALYZER_PROTOCOL_HTTP_HTTP_H +#define ANALYZER_PROTOCOL_HTTP_HTTP_H -#include "TCP.h" -#include "ContentLine.h" -#include "MIME.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" +#include "analyzer/protocol/zip/ZIP.h" +#include "analyzer/protocol/mime/MIME.h" #include "binpac_bro.h" -#include "ZIP.h" #include "IPAddr.h" +#include "events.bif.h" + +#include "HTTP.h" + +namespace analyzer { namespace http { enum CHUNKED_TRANSFER_STATE { NON_CHUNKED_TRANSFER, @@ -24,7 +29,7 @@ class HTTP_Entity; class HTTP_Message; class HTTP_Analyzer; -class HTTP_Entity : public MIME_Entity { +class HTTP_Entity : public mime::MIME_Entity { public: HTTP_Entity(HTTP_Message* msg, MIME_Entity* parent_entity, int expect_body); @@ -54,7 +59,7 @@ protected: int64_t header_length; int deliver_body; enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding; - ZIP_Analyzer* zip; + zip::ZIP_Analyzer* zip; bool is_partial_content; uint64_t offset; int64_t instance_length; // total length indicated by content-range @@ -69,7 +74,7 @@ protected: void SetPlainDelivery(int64_t length); - void SubmitHeader(MIME_Header* h); + void SubmitHeader(mime::MIME_Header* h); void SubmitAllHeaders(); }; @@ -90,9 +95,9 @@ enum { // HTTP_Message::EndEntity -> Message::Done // HTTP_MessageDone -> {Request,Reply}Made -class HTTP_Message : public MIME_Message { +class HTTP_Message : public mime::MIME_Message { public: - HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl, + HTTP_Message(HTTP_Analyzer* analyzer, tcp::ContentLine_Analyzer* cl, bool is_orig, int expect_body, int64_t init_header_length); ~HTTP_Message(); void Done(const int interrupted, const char* msg); @@ -100,16 +105,16 @@ public: int Undelivered(int64_t len); - void BeginEntity(MIME_Entity* /* entity */); - void EndEntity(MIME_Entity* entity); - void SubmitHeader(MIME_Header* h); - void SubmitAllHeaders(MIME_HeaderList& /* hlist */); + void BeginEntity(mime::MIME_Entity* /* entity */); + void EndEntity(mime::MIME_Entity* entity); + void SubmitHeader(mime::MIME_Header* h); + void SubmitAllHeaders(mime::MIME_HeaderList& /* hlist */); void SubmitData(int len, const char* buf); int RequestBuffer(int* plen, char** pbuf); void SubmitAllData(); void SubmitEvent(int event_type, const char* detail); - void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */); + void SubmitTrailingHeaders(mime::MIME_HeaderList& /* hlist */); void SetPlainDelivery(int64_t length); void SkipEntityData(); @@ -121,7 +126,7 @@ public: protected: HTTP_Analyzer* analyzer; - ContentLine_Analyzer* content_line; + tcp::ContentLine_Analyzer* content_line; bool is_orig; vector buffers; @@ -149,14 +154,14 @@ protected: Val* BuildMessageStat(const int interrupted, const char* msg); }; -class HTTP_Analyzer : public TCP_ApplicationAnalyzer { +class HTTP_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: HTTP_Analyzer(Connection* conn); ~HTTP_Analyzer(); - void Undelivered(TCP_Endpoint* sender, int seq, int len); + void Undelivered(tcp::TCP_Endpoint* sender, int seq, int len); - void HTTP_Header(int is_orig, MIME_Header* h); + void HTTP_Header(int is_orig, mime::MIME_Header* h); void HTTP_EntityData(int is_orig, const BroString* entity_data); void HTTP_MessageDone(int is_orig, HTTP_Message* message); void HTTP_Event(const char* category, const char* detail); @@ -172,20 +177,20 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void Undelivered(int seq, int len, bool orig); - // Overriden from TCP_ApplicationAnalyzer + // Overriden from tcp::TCP_ApplicationAnalyzer virtual void EndpointEOF(bool is_orig); virtual void ConnectionFinished(int half_finished); virtual void ConnectionReset(); virtual void PacketWithRST(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new HTTP_Analyzer(conn); } static bool Available() { return (http_request || http_reply || http_header || http_all_headers || http_begin_entity || http_end_entity || http_content_type || http_entity_data || http_message_done || - http_event || http_stats) && !FLAGS_use_binpac; } + http_event || http_stats); } protected: void GenStats(); @@ -193,7 +198,7 @@ protected: int HTTP_RequestLine(const char* line, const char* end_of_line); int HTTP_ReplyLine(const char* line, const char* end_of_line); - void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig, + void InitHTTPMessage(tcp::ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig, int expect_body, int64_t init_header_length); const char* PrefixMatch(const char* line, const char* end_of_line, @@ -245,8 +250,8 @@ protected: int reply_code; Val* reply_reason_phrase; - ContentLine_Analyzer* content_line_orig; - ContentLine_Analyzer* content_line_resp; + tcp::ContentLine_Analyzer* content_line_orig; + tcp::ContentLine_Analyzer* content_line_resp; HTTP_Message* request_message; HTTP_Message* reply_message; @@ -256,6 +261,8 @@ extern int is_reserved_URI_char(unsigned char ch); extern int is_unreserved_URI_char(unsigned char ch); extern void escape_URI_char(unsigned char ch, unsigned char*& p); extern BroString* unescape_URI(const u_char* line, const u_char* line_end, - Analyzer* analyzer); + analyzer::Analyzer* analyzer); + +} } // namespace analyzer::* #endif diff --git a/src/analyzer/protocol/http/Plugin.cc b/src/analyzer/protocol/http/Plugin.cc new file mode 100644 index 0000000000..1a2a05cbed --- /dev/null +++ b/src/analyzer/protocol/http/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "HTTP.h" + +BRO_PLUGIN_BEGIN(Bro, HTTP) + BRO_PLUGIN_DESCRIPTION("HTTP analyzer"); + BRO_PLUGIN_ANALYZER("HTTP", http::HTTP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/http/events.bif b/src/analyzer/protocol/http/events.bif new file mode 100644 index 0000000000..7a509c6d54 --- /dev/null +++ b/src/analyzer/protocol/http/events.bif @@ -0,0 +1,232 @@ + +## Generated for HTTP requests. Bro supports persistent and pipelined HTTP +## sessions and raises corresponding events as it parses client/server +## dialogues. This event is generated as soon as a request's initial line has +## been parsed, and before any :bro:id:`http_header` events are raised. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## method: The HTTP method extracted from the request (e.g., ``GET``, ``POST``). +## +## original_URI: The unprocessed URI as specified in the request. +## +## unescaped_URI: The URI with all percent-encodings decoded. +## +## version: The version number specified in the request (e.g., ``1.1``). +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_event http_header http_message_done http_reply http_stats +## truncate_http_URI +event http_request%(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string%); + +## Generated for HTTP replies. Bro supports persistent and pipelined HTTP +## sessions and raises corresponding events as it parses client/server +## dialogues. This event is generated as soon as a reply's initial line has +## been parsed, and before any :bro:id:`http_header` events are raised. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## version: The version number specified in the reply (e.g., ``1.1``). +## +## code: The numerical response code returned by the server. +## +## reason: The textual description returned by the server along with *code*. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_event http_header http_message_done http_request +## http_stats +event http_reply%(c: connection, version: string, code: count, reason: string%); + +## Generated for HTTP headers. Bro supports persistent and pipelined HTTP +## sessions and raises corresponding events as it parses client/server +## dialogues. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the header was sent by the originator of the TCP connection. +## +## name: The name of the header. +## +## value: The value of the header. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_event http_message_done http_reply http_request +## http_stats +## +## .. note:: This event is also raised for headers found in nested body +## entities. +event http_header%(c: connection, is_orig: bool, name: string, value: string%); + +## Generated for HTTP headers, passing on all headers of an HTTP message at +## once. Bro supports persistent and pipelined HTTP sessions and raises +## corresponding events as it parses client/server dialogues. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the header was sent by the originator of the TCP connection. +## +## hlist: A *table* containing all headers extracted from the current entity. +## The table is indexed by the position of the header (1 for the first, +## 2 for the second, etc.). +## +## .. bro:see:: http_begin_entity http_content_type http_end_entity http_entity_data +## http_event http_header http_message_done http_reply http_request http_stats +## +## .. note:: This event is also raised for headers found in nested body +## entities. +event http_all_headers%(c: connection, is_orig: bool, hlist: mime_header_list%); + +## Generated when starting to parse an HTTP body entity. This event is generated +## at least once for each non-empty (client or server) HTTP body; and +## potentially more than once if the body contains further nested MIME +## entities. Bro raises this event just before it starts parsing each entity's +## content. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the entity was sent by the originator of the TCP +## connection. +## +## .. bro:see:: http_all_headers http_content_type http_end_entity http_entity_data +## http_event http_header http_message_done http_reply http_request http_stats +## mime_begin_entity +event http_begin_entity%(c: connection, is_orig: bool%); + +## Generated when finishing parsing an HTTP body entity. This event is generated +## at least once for each non-empty (client or server) HTTP body; and +## potentially more than once if the body contains further nested MIME +## entities. Bro raises this event at the point when it has finished parsing an +## entity's content. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the entity was sent by the originator of the TCP +## connection. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_entity_data +## http_event http_header http_message_done http_reply http_request +## http_stats mime_end_entity +event http_end_entity%(c: connection, is_orig: bool%); + +## Generated when parsing an HTTP body entity, passing on the data. This event +## can potentially be raised many times for each entity, each time passing a +## chunk of the data of not further defined size. +## +## A common idiom for using this event is to first *reassemble* the data +## at the scripting layer by concatenating it to a successively growing +## string; and only perform further content analysis once the corresponding +## :bro:id:`http_end_entity` event has been raised. Note, however, that doing so +## can be quite expensive for HTTP tranders. At the very least, one should +## impose an upper size limit on how much data is being buffered. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the entity was sent by the originator of the TCP +## connection. +## +## length: The length of *data*. +## +## data: One chunk of raw entity data. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_event http_header http_message_done http_reply http_request http_stats +## mime_entity_data http_entity_data_delivery_size skip_http_data +event http_entity_data%(c: connection, is_orig: bool, length: count, data: string%); + +## Generated for reporting an HTTP body's content type. This event is +## generated at the end of parsing an HTTP header, passing on the MIME +## type as specified by the ``Content-Type`` header. If that header is +## missing, this event is still raised with a default value of ``text/plain``. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the entity was sent by the originator of the TCP +## connection. +## +## ty: The main type. +## +## subty: The subtype. +## +## .. bro:see:: http_all_headers http_begin_entity http_end_entity http_entity_data +## http_event http_header http_message_done http_reply http_request http_stats +## +## .. note:: This event is also raised for headers found in nested body +## entities. +event http_content_type%(c: connection, is_orig: bool, ty: string, subty: string%); + +## Generated once at the end of parsing an HTTP message. Bro supports persistent +## and pipelined HTTP sessions and raises corresponding events as it parses +## client/server dialogues. A "message" is one top-level HTTP entity, such as a +## complete request or reply. Each message can have further nested sub-entities +## inside. This event is raised once all sub-entities belonging to a top-level +## message have been processed (and their corresponding ``http_entity_*`` events +## generated). +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## is_orig: True if the entity was sent by the originator of the TCP +## connection. +## +## stat: Further meta information about the message. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_event http_header http_reply http_request http_stats +event http_message_done%(c: connection, is_orig: bool, stat: http_message_stat%); + +## Generated for errors found when decoding HTTP requests or replies. +## +## See `Wikipedia `__ +## for more information about the HTTP protocol. +## +## c: The connection. +## +## event_type: A string describing the general category of the problem found +## (e.g., ``illegal format``). +## +## detail: Further more detailed description of the error. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_header http_message_done http_reply http_request +## http_stats mime_event +event http_event%(c: connection, event_type: string, detail: string%); + +## Generated at the end of an HTTP session to report statistics about it. This +## event is raised after all of an HTTP session's requests and replies have been +## fully processed. +## +## c: The connection. +## +## stats: Statistics summarizing HTTP-level properties of the finished +## connection. +## +## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity +## http_entity_data http_event http_header http_message_done http_reply +## http_request +event http_stats%(c: connection, stats: http_stats_rec%); diff --git a/src/analyzer/protocol/http/functions.bif b/src/analyzer/protocol/http/functions.bif new file mode 100644 index 0000000000..c4e5df80d5 --- /dev/null +++ b/src/analyzer/protocol/http/functions.bif @@ -0,0 +1,56 @@ + +%%{ +#include "protocol/http/HTTP.h" +%%} + +## Skips the data of the HTTP entity. +## +## c: The HTTP connection. +## +## is_orig: If true, the client data is skipped, and the server data otherwise. +## +## .. bro:see:: skip_smtp_data +function skip_http_entity_data%(c: connection, is_orig: bool%): any + %{ + analyzer::ID id = mgr.CurrentAnalyzer(); + if ( id ) + { + analyzer::Analyzer* ha = c->FindAnalyzer(id); + + if ( ha ) + { + if ( ha->IsAnalyzer("HTTP") ) + static_cast(ha)->SkipEntityData(is_orig); + else + reporter->Error("non-HTTP analyzer associated with connection record"); + } + else + reporter->Error("could not find analyzer for skip_http_entity_data"); + + } + else + reporter->Error("no analyzer associated with connection record"); + + return 0; + %} + +## Unescapes all characters in a URI (decode every ``%xx`` group). +## +## URI: The URI to unescape. +## +## Returns: The unescaped URI with all ``%xx`` groups decoded. +## +## .. note:: +## +## Unescaping reserved characters may cause loss of information. RFC 2396: +## A URI is always in an "escaped" form, since escaping or unescaping a +## completed URI might change its semantics. Normally, the only time +## escape encodings can safely be made is when the URI is being created +## from its component parts. +function unescape_URI%(URI: string%): string + %{ + const u_char* line = URI->Bytes(); + const u_char* const line_end = line + URI->Len(); + + return new StringVal(analyzer::http::unescape_URI(line, line_end, 0)); + %} diff --git a/src/analyzer/protocol/icmp/CMakeLists.txt b/src/analyzer/protocol/icmp/CMakeLists.txt new file mode 100644 index 0000000000..7b8bd9c7fe --- /dev/null +++ b/src/analyzer/protocol/icmp/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro ICMP) +bro_plugin_cc(ICMP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc similarity index 98% rename from src/ICMP.cc rename to src/analyzer/protocol/icmp/ICMP.cc index 5634e3885f..732727d709 100644 --- a/src/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -8,19 +8,16 @@ #include "NetVar.h" #include "Event.h" #include "ICMP.h" +#include "Conn.h" + +#include "events.bif.h" #include -ICMP_Analyzer::ICMP_Analyzer(Connection* c) -: TransportLayerAnalyzer(AnalyzerTag::ICMP, c) - { - icmp_conn_val = 0; - c->SetInactivityTimeout(icmp_inactivity_timeout); - request_len = reply_len = -1; - } +using namespace analyzer::icmp; -ICMP_Analyzer::ICMP_Analyzer(AnalyzerTag::Tag tag, Connection* c) -: TransportLayerAnalyzer(tag, c) +ICMP_Analyzer::ICMP_Analyzer(Connection* c) +: TransportLayerAnalyzer("ICMP", c) { icmp_conn_val = 0; c->SetInactivityTimeout(icmp_inactivity_timeout); @@ -835,7 +832,7 @@ VectorVal* ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data) return vv; } -int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) +int analyzer::icmp::ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) { is_one_way = false; @@ -862,7 +859,7 @@ int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) } } -int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way) +int analyzer::icmp::ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way) { is_one_way = false; diff --git a/src/ICMP.h b/src/analyzer/protocol/icmp/ICMP.h similarity index 88% rename from src/ICMP.h rename to src/analyzer/protocol/icmp/ICMP.h index 1e30b7ff54..e371f53889 100644 --- a/src/ICMP.h +++ b/src/analyzer/protocol/icmp/ICMP.h @@ -1,9 +1,12 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef icmp_h -#define icmp_h +#ifndef ANALYZER_PROTOCOL_ICMP_ICMP_H +#define ANALYZER_PROTOCOL_ICMP_ICMP_H -#include "Analyzer.h" +#include "RuleMatcher.h" +#include "analyzer/Analyzer.h" + +namespace analyzer { namespace icmp { typedef enum { ICMP_INACTIVE, // no packet seen @@ -12,20 +15,17 @@ typedef enum { // We do not have an PIA for ICMP (yet) and therefore derive from // RuleMatcherState to perform our own matching. -class ICMP_Analyzer : public TransportLayerAnalyzer { +class ICMP_Analyzer : public analyzer::TransportLayerAnalyzer { public: ICMP_Analyzer(Connection* conn); virtual void UpdateConnVal(RecordVal *conn_val); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new ICMP_Analyzer(conn); } - static bool Available() { return true; } - protected: - ICMP_Analyzer() { } - ICMP_Analyzer(AnalyzerTag::Tag tag, Connection* conn); + ICMP_Analyzer(analyzer::Tag tag, Connection* conn); virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, @@ -94,4 +94,6 @@ private: extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way); extern int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way); +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/icmp/Plugin.cc b/src/analyzer/protocol/icmp/Plugin.cc new file mode 100644 index 0000000000..f313842c2a --- /dev/null +++ b/src/analyzer/protocol/icmp/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "ICMP.h" + +BRO_PLUGIN_BEGIN(Bro, ICMP) + BRO_PLUGIN_DESCRIPTION("ICMP analyzer"); + BRO_PLUGIN_ANALYZER("ICMP", icmp::ICMP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/icmp/events.bif b/src/analyzer/protocol/icmp/events.bif new file mode 100644 index 0000000000..c471ca0ee6 --- /dev/null +++ b/src/analyzer/protocol/icmp/events.bif @@ -0,0 +1,300 @@ +## Generated for all ICMP messages that are not handled separately with +## dedicated ICMP events. Bro's ICMP analyzer handles a number of ICMP messages +## directly with dedicated events. This event acts as a fallback for those it +## doesn't. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard +## connection record *c*. +## +## .. bro:see:: icmp_error_message +event icmp_sent%(c: connection, icmp: icmp_conn%); + +## Generated for ICMP *echo request* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard +## connection record *c*. +## +## id: The *echo request* identifier. +## +## seq: The *echo request* sequence number. +## +## payload: The message-specific data of the packet payload, i.e., everything +## after the first 8 bytes of the ICMP header. +## +## .. bro:see:: icmp_echo_reply +event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); + +## Generated for ICMP *echo reply* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## id: The *echo reply* identifier. +## +## seq: The *echo reply* sequence number. +## +## payload: The message-specific data of the packet payload, i.e., everything +## after the first 8 bytes of the ICMP header. +## +## .. bro:see:: icmp_echo_request +event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); + +## Generated for all ICMPv6 error messages that are not handled +## separately with dedicated events. Bro's ICMP analyzer handles a number +## of ICMP error messages directly with dedicated events. This event acts +## as a fallback for those it doesn't. +## +## See `Wikipedia +## `__ for more +## information about the ICMPv6 protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard +## connection record *c*. +## +## code: The ICMP code of the error message. +## +## context: A record with specifics of the original packet that the message +## refers to. +## +## .. bro:see:: icmp_unreachable icmp_packet_too_big +## icmp_time_exceeded icmp_parameter_problem +event icmp_error_message%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); + +## Generated for ICMP *destination unreachable* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## code: The ICMP code of the *unreachable* message. +## +## context: A record with specifics of the original packet that the message +## refers to. *Unreachable* messages should include the original IP +## header from the packet that triggered them, and Bro parses that +## into the *context* structure. Note that if the *unreachable* +## includes only a partial IP header for some reason, no +## fields of *context* will be filled out. +## +## .. bro:see:: icmp_error_message icmp_packet_too_big +## icmp_time_exceeded icmp_parameter_problem +event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); + +## Generated for ICMPv6 *packet too big* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMPv6 protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## code: The ICMP code of the *too big* message. +## +## context: A record with specifics of the original packet that the message +## refers to. *Too big* messages should include the original IP header +## from the packet that triggered them, and Bro parses that into +## the *context* structure. Note that if the *too big* includes only +## a partial IP header for some reason, no fields of *context* will +## be filled out. +## +## .. bro:see:: icmp_error_message icmp_unreachable +## icmp_time_exceeded icmp_parameter_problem +event icmp_packet_too_big%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); + +## Generated for ICMP *time exceeded* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## code: The ICMP code of the *exceeded* message. +## +## context: A record with specifics of the original packet that the message +## refers to. *Unreachable* messages should include the original IP +## header from the packet that triggered them, and Bro parses that +## into the *context* structure. Note that if the *exceeded* includes +## only a partial IP header for some reason, no fields of *context* +## will be filled out. +## +## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big +## icmp_parameter_problem +event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); + +## Generated for ICMPv6 *parameter problem* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMPv6 protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## code: The ICMP code of the *parameter problem* message. +## +## context: A record with specifics of the original packet that the message +## refers to. *Parameter problem* messages should include the original +## IP header from the packet that triggered them, and Bro parses that +## into the *context* structure. Note that if the *parameter problem* +## includes only a partial IP header for some reason, no fields +## of *context* will be filled out. +## +## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big +## icmp_time_exceeded +event icmp_parameter_problem%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); + +## Generated for ICMP *router solicitation* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## options: Any Neighbor Discovery options included with message (:rfc:`4861`). +## +## .. bro:see:: icmp_router_advertisement +## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect +event icmp_router_solicitation%(c: connection, icmp: icmp_conn, options: icmp6_nd_options%); + +## Generated for ICMP *router advertisement* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## cur_hop_limit: The default value that should be placed in Hop Count field +## for outgoing IP packets. +## +## managed: Managed address configuration flag, :rfc:`4861`. +## +## other: Other stateful configuration flag, :rfc:`4861`. +## +## home_agent: Mobile IPv6 home agent flag, :rfc:`3775`. +## +## pref: Router selection preferences, :rfc:`4191`. +## +## proxy: Neighbor discovery proxy flag, :rfc:`4389`. +## +## rsv: Remaining two reserved bits of router advertisement flags. +## +## router_lifetime: How long this router should be used as a default router. +## +## reachable_time: How long a neighbor should be considered reachable. +## +## retrans_timer: How long a host should wait before retransmitting. +## +## options: Any Neighbor Discovery options included with message (:rfc:`4861`). +## +## .. bro:see:: icmp_router_solicitation +## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect +event icmp_router_advertisement%(c: connection, icmp: icmp_conn, cur_hop_limit: count, managed: bool, other: bool, home_agent: bool, pref: count, proxy: bool, rsv: count, router_lifetime: interval, reachable_time: interval, retrans_timer: interval, options: icmp6_nd_options%); + +## Generated for ICMP *neighbor solicitation* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## tgt: The IP address of the target of the solicitation. +## +## options: Any Neighbor Discovery options included with message (:rfc:`4861`). +## +## .. bro:see:: icmp_router_solicitation icmp_router_advertisement +## icmp_neighbor_advertisement icmp_redirect +event icmp_neighbor_solicitation%(c: connection, icmp: icmp_conn, tgt: addr, options: icmp6_nd_options%); + +## Generated for ICMP *neighbor advertisement* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## router: Flag indicating the sender is a router. +## +## solicited: Flag indicating advertisement is in response to a solicitation. +## +## override: Flag indicating advertisement should override existing caches. +## +## tgt: the Target Address in the soliciting message or the address whose +## link-layer address has changed for unsolicited adverts. +## +## options: Any Neighbor Discovery options included with message (:rfc:`4861`). +## +## .. bro:see:: icmp_router_solicitation icmp_router_advertisement +## icmp_neighbor_solicitation icmp_redirect +event icmp_neighbor_advertisement%(c: connection, icmp: icmp_conn, router: bool, solicited: bool, override: bool, tgt: addr, options: icmp6_nd_options%); + +## Generated for ICMP *redirect* messages. +## +## See `Wikipedia +## `__ for more +## information about the ICMP protocol. +## +## c: The connection record for the corresponding ICMP flow. +## +## icmp: Additional ICMP-specific information augmenting the standard connection +## record *c*. +## +## tgt: The address that is supposed to be a better first hop to use for +## ICMP Destination Address. +## +## dest: The address of the destination which is redirected to the target. +## +## options: Any Neighbor Discovery options included with message (:rfc:`4861`). +## +## .. bro:see:: icmp_router_solicitation icmp_router_advertisement +## icmp_neighbor_solicitation icmp_neighbor_advertisement +event icmp_redirect%(c: connection, icmp: icmp_conn, tgt: addr, dest: addr, options: icmp6_nd_options%); + diff --git a/src/analyzer/protocol/ident/CMakeLists.txt b/src/analyzer/protocol/ident/CMakeLists.txt new file mode 100644 index 0000000000..658dff141e --- /dev/null +++ b/src/analyzer/protocol/ident/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Ident) +bro_plugin_cc(Ident.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/Ident.cc b/src/analyzer/protocol/ident/Ident.cc similarity index 81% rename from src/Ident.cc rename to src/analyzer/protocol/ident/Ident.cc index b2e82e5f12..8e25775af8 100644 --- a/src/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -8,13 +8,17 @@ #include "Ident.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::ident; + Ident_Analyzer::Ident_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::Ident, conn) +: tcp::TCP_ApplicationAnalyzer("IDENT", conn) { did_bad_reply = did_deliver = 0; - orig_ident = new ContentLine_Analyzer(conn, true); - resp_ident = new ContentLine_Analyzer(conn, false); + orig_ident = new tcp::ContentLine_Analyzer(conn, true); + resp_ident = new tcp::ContentLine_Analyzer(conn, false); orig_ident->SetIsNULSensitive(true); resp_ident->SetIsNULSensitive(true); @@ -25,29 +29,29 @@ Ident_Analyzer::Ident_Analyzer(Connection* conn) void Ident_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( TCP() ) if ( (! did_deliver || orig_ident->HasPartialLine()) && - (TCP()->OrigState() == TCP_ENDPOINT_CLOSED || - TCP()->OrigPrevState() == TCP_ENDPOINT_CLOSED) && - TCP()->OrigPrevState() != TCP_ENDPOINT_PARTIAL && - TCP()->RespPrevState() != TCP_ENDPOINT_PARTIAL && - TCP()->OrigPrevState() != TCP_ENDPOINT_INACTIVE && - TCP()->RespPrevState() != TCP_ENDPOINT_INACTIVE ) + (TCP()->OrigState() == tcp::TCP_ENDPOINT_CLOSED || + TCP()->OrigPrevState() == tcp::TCP_ENDPOINT_CLOSED) && + TCP()->OrigPrevState() != tcp::TCP_ENDPOINT_PARTIAL && + TCP()->RespPrevState() != tcp::TCP_ENDPOINT_PARTIAL && + TCP()->OrigPrevState() != tcp::TCP_ENDPOINT_INACTIVE && + TCP()->RespPrevState() != tcp::TCP_ENDPOINT_INACTIVE ) Weird("partial_ident_request"); } void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig); int remote_port, local_port; const char* line = (const char*) data; const char* orig_line = line; const char* end_of_line = line + length; - TCP_Endpoint* s = 0; + tcp::TCP_Endpoint* s = 0; if ( TCP() ) s = is_orig ? TCP()->Orig() : TCP()->Resp(); @@ -60,9 +64,9 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) line = ParsePair(line, end_of_line, remote_port, local_port); if ( ! line ) { - if ( s && s->state == TCP_ENDPOINT_CLOSED && - (s->prev_state == TCP_ENDPOINT_INACTIVE || - s->prev_state == TCP_ENDPOINT_PARTIAL) ) + if ( s && s->state == tcp::TCP_ENDPOINT_CLOSED && + (s->prev_state == tcp::TCP_ENDPOINT_INACTIVE || + s->prev_state == tcp::TCP_ENDPOINT_PARTIAL) ) // not surprising the request is mangled. return; @@ -95,9 +99,9 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) if ( ! line || line == end_of_line || line[0] != ':' ) { - if ( s && s->state == TCP_ENDPOINT_CLOSED && - (s->prev_state == TCP_ENDPOINT_INACTIVE || - s->prev_state == TCP_ENDPOINT_PARTIAL) ) + if ( s && s->state == tcp::TCP_ENDPOINT_CLOSED && + (s->prev_state == tcp::TCP_ENDPOINT_INACTIVE || + s->prev_state == tcp::TCP_ENDPOINT_PARTIAL) ) // not surprising the request is mangled. return; diff --git a/src/Ident.h b/src/analyzer/protocol/ident/Ident.h similarity index 57% rename from src/Ident.h rename to src/analyzer/protocol/ident/Ident.h index a848d233e1..31df1dcdc6 100644 --- a/src/Ident.h +++ b/src/analyzer/protocol/ident/Ident.h @@ -1,24 +1,23 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef ident_h -#define ident_h +#ifndef ANALYZER_PROTOCOL_IDENT_IDENT_H +#define ANALYZER_PROTOCOL_IDENT_IDENT_H -#include "TCP.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" -class Ident_Analyzer : public TCP_ApplicationAnalyzer { +namespace analyzer { namespace ident { + +class Ident_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: Ident_Analyzer(Connection* conn); virtual void Done(); virtual void DeliverStream(int length, const u_char* data, bool is_orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Ident_Analyzer(conn); } - static bool Available() - { return ident_request || ident_reply || ident_error; } - protected: const char* ParsePair(const char* line, const char* end_of_line, int& p1, int &p2); @@ -28,11 +27,13 @@ protected: void BadRequest(int length, const char* line); void BadReply(int length, const char* line); - ContentLine_Analyzer* orig_ident; - ContentLine_Analyzer* resp_ident; + tcp::ContentLine_Analyzer* orig_ident; + tcp::ContentLine_Analyzer* resp_ident; unsigned int did_deliver:1; unsigned int did_bad_reply:1; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/ident/Plugin.cc b/src/analyzer/protocol/ident/Plugin.cc new file mode 100644 index 0000000000..c053689b8f --- /dev/null +++ b/src/analyzer/protocol/ident/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Ident.h" + +BRO_PLUGIN_BEGIN(Bro, Ident) + BRO_PLUGIN_DESCRIPTION("Ident analyzer"); + BRO_PLUGIN_ANALYZER("Ident", ident::Ident_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/ident/events.bif b/src/analyzer/protocol/ident/events.bif new file mode 100644 index 0000000000..96a7f37a31 --- /dev/null +++ b/src/analyzer/protocol/ident/events.bif @@ -0,0 +1,63 @@ +## Generated for Ident requests. +## +## See `Wikipedia `__ for more +## information about the Ident protocol. +## +## c: The connection. +## +## lport: The request's local port. +## +## rport: The request's remote port. +## +## .. bro:see:: ident_error ident_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ident_request%(c: connection, lport: port, rport: port%); + +## Generated for Ident replies. +## +## See `Wikipedia `__ for more +## information about the Ident protocol. +## +## c: The connection. +## +## lport: The corresponding request's local port. +## +## rport: The corresponding request's remote port. +## +## user_id: The user id returned by the reply. +## +## system: The operating system returned by the reply. +## +## .. bro:see:: ident_error ident_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ident_reply%(c: connection, lport: port, rport: port, user_id: string, system: string%); + +## Generated for Ident error replies. +## +## See `Wikipedia `__ for more +## information about the Ident protocol. +## +## c: The connection. +## +## lport: The corresponding request's local port. +## +## rport: The corresponding request's remote port. +## +## line: The error description returned by the reply. +## +## .. bro:see:: ident_reply ident_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ident_error%(c: connection, lport: port, rport: port, line: string%); + diff --git a/src/analyzer/protocol/interconn/CMakeLists.txt b/src/analyzer/protocol/interconn/CMakeLists.txt new file mode 100644 index 0000000000..ef5ca13a9a --- /dev/null +++ b/src/analyzer/protocol/interconn/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro InterConn) +bro_plugin_cc(InterConn.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/InterConn.cc b/src/analyzer/protocol/interconn/InterConn.cc similarity index 92% rename from src/InterConn.cc rename to src/analyzer/protocol/interconn/InterConn.cc index 403081181a..4b298eaa52 100644 --- a/src/InterConn.cc +++ b/src/analyzer/protocol/interconn/InterConn.cc @@ -5,9 +5,13 @@ #include "InterConn.h" #include "Event.h" #include "Net.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" -InterConnEndpoint::InterConnEndpoint(TCP_Endpoint* e) +#include "events.bif.h" + +using namespace analyzer::interconn; + +InterConnEndpoint::InterConnEndpoint(tcp::TCP_Endpoint* e) { endp = e; max_top_seq = 0; @@ -30,7 +34,7 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, if ( len <= 0 ) return 0; - if ( endp->state == TCP_ENDPOINT_PARTIAL ) + if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; int ack = endp->AckSeq() - endp->StartSeq(); @@ -153,7 +157,7 @@ int InterConnEndpoint::IsNormalKeystrokeInterarrival(double t) const } InterConn_Analyzer::InterConn_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::InterConn, c) +: tcp::TCP_ApplicationAnalyzer("INTERCONN", c) { orig_endp = resp_endp = 0; orig_stream_pos = resp_stream_pos = 1; @@ -172,7 +176,7 @@ InterConn_Analyzer::~InterConn_Analyzer() void InterConn_Analyzer::Init() { - TCP_ApplicationAnalyzer::Init(); + tcp::TCP_ApplicationAnalyzer::Init(); assert(TCP()); orig_endp = new InterConnEndpoint(TCP()->Orig()); @@ -182,7 +186,7 @@ void InterConn_Analyzer::Init() void InterConn_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) { - TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, + tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); if ( is_orig ) @@ -193,7 +197,7 @@ void InterConn_Analyzer::DeliverPacket(int len, const u_char* data, void InterConn_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); if ( is_orig ) { @@ -218,7 +222,7 @@ void InterConn_Analyzer::Done() RemoveEvent(); } - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); } void InterConn_Analyzer::StatTimer(double t, int is_expire) diff --git a/src/InterConn.h b/src/analyzer/protocol/interconn/InterConn.h similarity index 80% rename from src/InterConn.h rename to src/analyzer/protocol/interconn/InterConn.h index d9cd10de27..b13abecab1 100644 --- a/src/InterConn.h +++ b/src/analyzer/protocol/interconn/InterConn.h @@ -1,15 +1,17 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef interconn_h -#define interconn_h +#ifndef ANALYZER_PROTOCOL_INTERCONN_INTERCONN_H +#define ANALYZER_PROTOCOL_INTERCONN_INTERCONN_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "Timer.h" #include "NetVar.h" +namespace analyzer { namespace interconn { + class InterConnEndpoint : public BroObj { public: - InterConnEndpoint(TCP_Endpoint* e); + InterConnEndpoint(tcp::TCP_Endpoint* e); int DataSent(double t, int seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); @@ -21,7 +23,7 @@ protected: int IsPotentialKeystrokePacket(int len) const; int IsNormalKeystrokeInterarrival(double t) const; - TCP_Endpoint* endp; + tcp::TCP_Endpoint* endp; double last_keystroke_time; int max_top_seq; uint32 num_pkts; @@ -38,7 +40,7 @@ protected: }; -class InterConn_Analyzer : public TCP_ApplicationAnalyzer { +class InterConn_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: InterConn_Analyzer(Connection* c); ~InterConn_Analyzer(); @@ -47,11 +49,9 @@ public: virtual void Done(); void StatTimer(double t, int is_expire); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new InterConn_Analyzer(conn); } - static bool Available() { return interconn_stats; } - protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassembling. @@ -83,4 +83,6 @@ protected: InterConn_Analyzer* analyzer; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/interconn/Plugin.cc b/src/analyzer/protocol/interconn/Plugin.cc new file mode 100644 index 0000000000..c135d0fb07 --- /dev/null +++ b/src/analyzer/protocol/interconn/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "InterConn.h" + +BRO_PLUGIN_BEGIN(Bro, InterConn) + BRO_PLUGIN_DESCRIPTION("InterConn analyzer (deprecated)"); + BRO_PLUGIN_ANALYZER("InterConn", interconn::InterConn_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/interconn/events.bif b/src/analyzer/protocol/interconn/events.bif new file mode 100644 index 0000000000..6e859da668 --- /dev/null +++ b/src/analyzer/protocol/interconn/events.bif @@ -0,0 +1,8 @@ +# ##### Deprecated events. Proposed for removal. + +## Deprecated. Will be removed. +event interconn_stats%(c: connection, os: interconn_endp_stats, rs: interconn_endp_stats%); + +## Deprecated. Will be removed. +event interconn_remove_conn%(c: connection%); + diff --git a/src/analyzer/protocol/irc/CMakeLists.txt b/src/analyzer/protocol/irc/CMakeLists.txt new file mode 100644 index 0000000000..5f97482365 --- /dev/null +++ b/src/analyzer/protocol/irc/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro IRC) +bro_plugin_cc(IRC.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/IRC.cc b/src/analyzer/protocol/irc/IRC.cc similarity index 95% rename from src/IRC.cc rename to src/analyzer/protocol/irc/IRC.cc index 1918300ba2..71f591635f 100644 --- a/src/IRC.cc +++ b/src/analyzer/protocol/irc/IRC.cc @@ -2,15 +2,18 @@ #include #include "IRC.h" -#include "DPM.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/ContentLine.h" #include "NetVar.h" #include "Event.h" -#include "ZIP.h" +#include "analyzer/protocol/zip/ZIP.h" +#include "analyzer/Manager.h" +#include "events.bif.h" + +using namespace analyzer::irc; IRC_Analyzer::IRC_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::IRC, conn) +: tcp::TCP_ApplicationAnalyzer("IRC", conn) { invalid_msg_count = 0; invalid_msg_max_count = 20; @@ -18,50 +21,18 @@ IRC_Analyzer::IRC_Analyzer(Connection* conn) resp_status = WAIT_FOR_REGISTRATION; orig_zip_status = NO_ZIP; resp_zip_status = NO_ZIP; - AddSupportAnalyzer(new ContentLine_Analyzer(conn, true)); - AddSupportAnalyzer(new ContentLine_Analyzer(conn, false)); - } - -bool IRC_Analyzer::Available() - { - static bool did_avail = false; - static bool avail = false; - - if ( ! did_avail ) - { - // It's a lot of events, but for consistency with other - // analyzers we need to check for all of them. - avail = irc_request || irc_reply || - irc_message || irc_quit_message || - irc_privmsg_message || irc_notice_message || - irc_squery_message || irc_join_message || - irc_part_message || irc_nick_message || - irc_invalid_nick || irc_network_info || - irc_server_info || irc_channel_info || irc_who_line || - irc_who_message || irc_whois_message || - irc_whois_user_line || irc_whois_operator_line || - irc_whois_channel_line || irc_oper_message || - irc_oper_response || irc_kick_message || - irc_error_message || irc_invite_message || - irc_mode_message || irc_squit_message || - irc_names_info || irc_dcc_message || - irc_global_users || irc_user_message || - irc_channel_topic || irc_password_message; - - did_avail = true; - } - - return avail; + AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, true)); + AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, false)); } void IRC_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); } void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); // check line size if ( length > 512 ) @@ -1190,8 +1161,8 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { orig_zip_status = ZIP_LOADED; resp_zip_status = ZIP_LOADED; - AddSupportAnalyzer(new ZIP_Analyzer(Conn(), true)); - AddSupportAnalyzer(new ZIP_Analyzer(Conn(), false)); + AddSupportAnalyzer(new zip::ZIP_Analyzer(Conn(), true)); + AddSupportAnalyzer(new zip::ZIP_Analyzer(Conn(), false)); } return; diff --git a/src/IRC.h b/src/analyzer/protocol/irc/IRC.h similarity index 80% rename from src/IRC.h rename to src/analyzer/protocol/irc/IRC.h index 0fe36957de..a4112ccb12 100644 --- a/src/IRC.h +++ b/src/analyzer/protocol/irc/IRC.h @@ -1,13 +1,15 @@ // An IRC analyzer contributed by Roland Gruber. -#ifndef irc_h -#define irc_h -#include "TCP.h" +#ifndef ANALYZER_PROTOCOL_IRC_IRC_H +#define ANALYZER_PROTOCOL_IRC_IRC_H +#include "analyzer/protocol/tcp/TCP.h" + +namespace analyzer { namespace irc { /** * \brief Main class for analyzing IRC traffic. */ -class IRC_Analyzer : public TCP_ApplicationAnalyzer { +class IRC_Analyzer : public tcp::TCP_ApplicationAnalyzer { enum { WAIT_FOR_REGISTRATION, REGISTERED, }; enum { NO_ZIP, ACCEPT_ZIP, ZIP_LOADED, }; public: @@ -30,13 +32,11 @@ public: */ virtual void DeliverStream(int len, const u_char* data, bool orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new IRC_Analyzer(conn); } - static bool Available(); - protected: int orig_status; int orig_zip_status; @@ -62,4 +62,6 @@ private: }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/irc/Plugin.cc b/src/analyzer/protocol/irc/Plugin.cc new file mode 100644 index 0000000000..fc7de1bd6d --- /dev/null +++ b/src/analyzer/protocol/irc/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "IRC.h" + +BRO_PLUGIN_BEGIN(Bro, IRC) + BRO_PLUGIN_DESCRIPTION("IRC analyzer"); + BRO_PLUGIN_ANALYZER("IRC", irc::IRC_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/irc/events.bif b/src/analyzer/protocol/irc/events.bif new file mode 100644 index 0000000000..4e69b9ad33 --- /dev/null +++ b/src/analyzer/protocol/irc/events.bif @@ -0,0 +1,799 @@ + +## Generated for all client-side IRC commands. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: Always true. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## command: The command. +## +## arguments: The arguments for the command. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +## +## .. note:: This event is generated only for messages that originate +## at the client-side. Commands coming in from remote trigger +## the :bro:id:`irc_message` event instead. +event irc_request%(c: connection, is_orig: bool, prefix: string, + command: string, arguments: string%); + +## Generated for all IRC replies. IRC replies are sent in response to a +## request and come with a reply code. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the reply. IRC uses the prefix to +## indicate the true origin of a message. +## +## code: The reply code, as specified by the protocol. +## +## params: The reply's parameters. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_reply%(c: connection, is_orig: bool, prefix: string, + code: count, params: string%); + +## Generated for IRC commands forwarded from the server to the client. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: Always false. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## command: The command. +## +## message: TODO. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +## +## .. note:: +## +## This event is generated only for messages that are forwarded by the server +## to the client. Commands coming from client trigger the +## :bro:id:`irc_request` event instead. +event irc_message%(c: connection, is_orig: bool, prefix: string, + command: string, message: string%); + +## Generated for IRC messages of type *quit*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## nick: The nickname coming with the message. +## +## message: The text included with the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_quit_message%(c: connection, is_orig: bool, nick: string, message: string%); + +## Generated for IRC messages of type *privmsg*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## source: The source of the private communication. +## +## target: The target of the private communication. +## +## message: The text of communication. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_privmsg_message%(c: connection, is_orig: bool, source: string, + target: string, message: string%); + +## Generated for IRC messages of type *notice*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## source: The source of the private communication. +## +## target: The target of the private communication. +## +## message: The text of communication. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_notice_message%(c: connection, is_orig: bool, source: string, + target: string, message: string%); + +## Generated for IRC messages of type *squery*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## source: The source of the private communication. +## +## target: The target of the private communication. +## +## message: The text of communication. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_squery_message%(c: connection, is_orig: bool, source: string, + target: string, message: string%); + +## Generated for IRC messages of type *join*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## info_list: The user information coming with the command. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_join_message%(c: connection, is_orig: bool, info_list: irc_join_list%); + +## Generated for IRC messages of type *part*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## nick: The nickname coming with the message. +## +## chans: The set of channels affected. +## +## message: The text coming with the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_password_message +event irc_part_message%(c: connection, is_orig: bool, nick: string, + chans: string_set, message: string%); + +## Generated for IRC messages of type *nick*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## who: The user changing its nickname. +## +## newnick: The new nickname. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_nick_message%(c: connection, is_orig: bool, who: string, newnick: string%); + +## Generated when a server rejects an IRC nickname. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_invalid_nick%(c: connection, is_orig: bool%); + +## Generated for an IRC reply of type *luserclient*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## users: The number of users as returned in the reply. +## +## services: The number of services as returned in the reply. +## +## servers: The number of servers as returned in the reply. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_network_info%(c: connection, is_orig: bool, users: count, + services: count, servers: count%); + +## Generated for an IRC reply of type *luserme*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## users: The number of users as returned in the reply. +## +## services: The number of services as returned in the reply. +## +## servers: The number of servers as returned in the reply. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_server_info%(c: connection, is_orig: bool, users: count, + services: count, servers: count%); + +## Generated for an IRC reply of type *luserchannels*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## chans: The number of channels as returned in the reply. +## +## .. bro:see:: irc_channel_topic irc_dcc_message irc_error_message irc_global_users +## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_channel_info%(c: connection, is_orig: bool, chans: count%); + +## Generated for an IRC reply of type *whoreply*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## target_nick: The target nickname. +## +## channel: The channel. +## +## user: The user. +## +## host: The host. +## +## server: The server. +## +## nick: The nickname. +## +## params: The parameters. +## +## hops: The hop count. +## +## real_name: The real name. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_who_line%(c: connection, is_orig: bool, target_nick: string, + channel: string, user: string, host: string, + server: string, nick: string, params: string, + hops: count, real_name: string%); + + +## Generated for an IRC reply of type *namereply*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## c_type: The channel type. +## +## channel: The channel. +## +## users: The set of users. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_names_info%(c: connection, is_orig: bool, c_type: string, + channel: string, users: string_set%); + +## Generated for an IRC reply of type *whoisoperator*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## nick: The nickname specified in the reply. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_whois_operator_line%(c: connection, is_orig: bool, nick: string%); + +## Generated for an IRC reply of type *whoischannels*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## nick: The nickname specified in the reply. +## +## chans: The set of channels returned. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_whois_channel_line%(c: connection, is_orig: bool, nick: string, + chans: string_set%); + +## Generated for an IRC reply of type *whoisuser*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## nick: The nickname specified in the reply. +## +## user: The user name specified in the reply. +## +## host: The host name specified in the reply. +## +## real_name: The real name specified in the reply. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_whois_user_line%(c: connection, is_orig: bool, nick: string, + user: string, host: string, real_name: string%); + +## Generated for IRC replies of type *youreoper* and *nooperhost*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## got_oper: True if the *oper* command was executed successfully +## (*youreport*) and false otherwise (*nooperhost*). +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_part_message +## irc_password_message +event irc_oper_response%(c: connection, is_orig: bool, got_oper: bool%); + +## Generated for an IRC reply of type *globalusers*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## msg: The message coming with the reply. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_global_users%(c: connection, is_orig: bool, prefix: string, msg: string%); + +## Generated for an IRC reply of type *topic*. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## channel: The channel name specified in the reply. +## +## topic: The topic specified in the reply. +## +## .. bro:see:: irc_channel_info irc_dcc_message irc_error_message irc_global_users +## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_channel_topic%(c: connection, is_orig: bool, channel: string, topic: string%); + +## Generated for IRC messages of type *who*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## mask: The mask specified in the message. +## +## oper: True if the operator flag was set. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_who_message%(c: connection, is_orig: bool, mask: string, oper: bool%); + +## Generated for IRC messages of type *whois*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## server: TODO. +## +## users: TODO. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_whois_message%(c: connection, is_orig: bool, server: string, users: string%); + +## Generated for IRC messages of type *oper*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## user: The user specified in the message. +## +## password: The password specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_response irc_part_message +## irc_password_message +event irc_oper_message%(c: connection, is_orig: bool, user: string, password: string%); + +## Generated for IRC messages of type *kick*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## chans: The channels specified in the message. +## +## users: The users specified in the message. +## +## comment: The comment specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_kick_message%(c: connection, is_orig: bool, prefix: string, + chans: string, users: string, comment: string%); + +## Generated for IRC messages of type *error*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## message: The textual description specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_global_users +## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_error_message%(c: connection, is_orig: bool, prefix: string, message: string%); + +## Generated for IRC messages of type *invite*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## nickname: The nickname specified in the message. +## +## channel: The channel specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_invite_message%(c: connection, is_orig: bool, prefix: string, + nickname: string, channel: string%); + +## Generated for IRC messages of type *mode*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## params: The parameters coming with the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_mode_message%(c: connection, is_orig: bool, prefix: string, params: string%); + +## Generated for IRC messages of type *squit*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## server: The server specified in the message. +## +## message: The textual description specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_squit_message%(c: connection, is_orig: bool, prefix: string, + server: string, message: string%); + +## Generated for IRC messages of type *dcc*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## prefix: The optional prefix coming with the command. IRC uses the prefix to +## indicate the true origin of a message. +## +## target: The target specified in the message. +## +## dcc_type: The DCC type specified in the message. +## +## argument: The argument specified in the message. +## +## address: The address specified in the message. +## +## dest_port: The destination port specified in the message. +## +## size: The size specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_error_message irc_global_users +## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message +## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message +## irc_notice_message irc_oper_message irc_oper_response irc_part_message +## irc_password_message +event irc_dcc_message%(c: connection, is_orig: bool, + prefix: string, target: string, + dcc_type: string, argument: string, + address: addr, dest_port: count, size: count%); + +## Generated for IRC messages of type *user*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## user: The user specified in the message. +## +## host: The host name specified in the message. +## +## server: The server name specified in the message. +## +## real_name: The real name specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message irc_password_message +event irc_user_message%(c: connection, is_orig: bool, user: string, host: string, server: string, real_name: string%); + +## Generated for IRC messages of type *password*. This event is generated for +## messages coming from both the client and the server. +## +## See `Wikipedia `__ for more +## information about the IRC protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## password: The password specified in the message. +## +## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message +## irc_global_users irc_invalid_nick irc_invite_message irc_join_message +## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info +## irc_nick_message irc_notice_message irc_oper_message irc_oper_response +## irc_part_message +event irc_password_message%(c: connection, is_orig: bool, password: string%); diff --git a/src/analyzer/protocol/login/CMakeLists.txt b/src/analyzer/protocol/login/CMakeLists.txt new file mode 100644 index 0000000000..66f8eb1568 --- /dev/null +++ b/src/analyzer/protocol/login/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Login) +bro_plugin_cc(Login.cc RSH.cc Telnet.cc Rlogin.cc NVT.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() diff --git a/src/Login.cc b/src/analyzer/protocol/login/Login.cc similarity index 97% rename from src/Login.cc rename to src/analyzer/protocol/login/Login.cc index e626fb3a0a..335b855f1d 100644 --- a/src/Login.cc +++ b/src/analyzer/protocol/login/Login.cc @@ -10,6 +10,10 @@ #include "RE.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::login; + static RE_Matcher* re_skip_authentication = 0; static RE_Matcher* re_direct_login_prompts; static RE_Matcher* re_login_prompts; @@ -20,8 +24,8 @@ static RE_Matcher* re_login_timeouts; static RE_Matcher* init_RE(ListVal* l); -Login_Analyzer::Login_Analyzer(AnalyzerTag::Tag tag, Connection* conn) -: TCP_ApplicationAnalyzer(tag, conn) +Login_Analyzer::Login_Analyzer(const char* name, Connection* conn) +: tcp::TCP_ApplicationAnalyzer(name, conn) { state = LOGIN_STATE_AUTHENTICATE; num_user_lines_seen = lines_scanned = 0; @@ -65,7 +69,7 @@ Login_Analyzer::~Login_Analyzer() void Login_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); char* str = new char[length+1]; @@ -102,8 +106,8 @@ void Login_Analyzer::NewLine(bool orig, char* line) if ( state == LOGIN_STATE_AUTHENTICATE ) { - if ( TCP()->OrigState() == TCP_ENDPOINT_PARTIAL || - TCP()->RespState() == TCP_ENDPOINT_PARTIAL ) + if ( TCP()->OrigState() == tcp::TCP_ENDPOINT_PARTIAL || + TCP()->RespState() == tcp::TCP_ENDPOINT_PARTIAL ) state = LOGIN_STATE_CONFUSED; // unknown login state else { @@ -361,7 +365,7 @@ void Login_Analyzer::SetEnv(bool orig, char* name, char* val) void Login_Analyzer::EndpointEOF(bool orig) { - TCP_ApplicationAnalyzer::EndpointEOF(orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(orig); if ( state == LOGIN_STATE_AUTHENTICATE && HaveTypeahead() ) { diff --git a/src/Login.h b/src/analyzer/protocol/login/Login.h similarity index 88% rename from src/Login.h rename to src/analyzer/protocol/login/Login.h index b186cc52d2..2178bdff1a 100644 --- a/src/Login.h +++ b/src/analyzer/protocol/login/Login.h @@ -1,9 +1,11 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef login_h -#define login_h +#ifndef ANALYZER_PROTOCOL_LOGIN_LOGIN_H +#define ANALYZER_PROTOCOL_LOGIN_LOGIN_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" + +namespace analyzer { namespace login { typedef enum { LOGIN_STATE_AUTHENTICATE, // trying to authenticate @@ -19,9 +21,9 @@ typedef enum { // Maximum # lines look after login for failure. #define MAX_LOGIN_LOOKAHEAD 10 -class Login_Analyzer : public TCP_ApplicationAnalyzer { +class Login_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: - Login_Analyzer(AnalyzerTag::Tag tag, Connection* conn); + Login_Analyzer(const char* name, Connection* conn); ~Login_Analyzer(); virtual void DeliverStream(int len, const u_char* data, bool orig); @@ -82,4 +84,6 @@ protected: int saw_ploy; }; +} } // namespace analyzer::* + #endif diff --git a/src/NVT.cc b/src/analyzer/protocol/login/NVT.cc similarity index 98% rename from src/NVT.cc rename to src/analyzer/protocol/login/NVT.cc index 5ba12ac32a..62e4d0c050 100644 --- a/src/NVT.cc +++ b/src/analyzer/protocol/login/NVT.cc @@ -7,7 +7,9 @@ #include "NVT.h" #include "NetVar.h" #include "Event.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" + +#include "events.bif.h" #define IS_3_BYTE_OPTION(c) (c >= 251 && c <= 254) @@ -24,6 +26,8 @@ #define TELNET_IAC 255 +using namespace analyzer::login; + TelnetOption::TelnetOption(NVT_Analyzer* arg_endp, unsigned int arg_code) { endp = arg_endp; @@ -287,7 +291,7 @@ void TelnetEnvironmentOption::RecvSubOption(u_char* data, int len) break; } - static_cast + static_cast (endp->Parent())->SetEnv(endp->IsOrig(), var_name, var_val); } @@ -360,7 +364,7 @@ void TelnetBinaryOption::InconsistentOption(unsigned int /* type */) NVT_Analyzer::NVT_Analyzer(Connection* conn, bool orig) -: ContentLine_Analyzer(AnalyzerTag::NVT, conn, orig) +: tcp::ContentLine_Analyzer("NVT", conn, orig) { peer = 0; is_suboption = last_was_IAC = pending_IAC = 0; diff --git a/src/NVT.h b/src/analyzer/protocol/login/NVT.h similarity index 94% rename from src/NVT.h rename to src/analyzer/protocol/login/NVT.h index 61aa1ef740..3bcadcdc8e 100644 --- a/src/NVT.h +++ b/src/analyzer/protocol/login/NVT.h @@ -1,10 +1,9 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef nvt_h -#define nvt_h - -#include "ContentLine.h" +#ifndef ANALYZER_PROTOCOL_LOGIN_NVT_H +#define ANALYZER_PROTOCOL_LOGIN_NVT_H +#include "analyzer/protocol/tcp/ContentLine.h" #define TELNET_OPTION_BINARY 0 #define TELNET_OPTION_TERMINAL 24 @@ -13,8 +12,9 @@ #define TELNET_OPTION_ENVIRON 39 #define NUM_TELNET_OPTIONS 5 -class NVT_Analyzer; +namespace analyzer { namespace login { +class NVT_Analyzer; class TelnetOption { public: @@ -123,7 +123,7 @@ protected: void InconsistentOption(unsigned int type); }; -class NVT_Analyzer : public ContentLine_Analyzer { +class NVT_Analyzer : public tcp::ContentLine_Analyzer { public: NVT_Analyzer(Connection* conn, bool orig); ~NVT_Analyzer(); @@ -170,4 +170,6 @@ protected: int num_options; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/login/Plugin.cc b/src/analyzer/protocol/login/Plugin.cc new file mode 100644 index 0000000000..6b8d1a8fed --- /dev/null +++ b/src/analyzer/protocol/login/Plugin.cc @@ -0,0 +1,20 @@ + +#include "plugin/Plugin.h" + +#include "Login.h" +#include "Telnet.h" +#include "RSH.h" +#include "Rlogin.h" + +BRO_PLUGIN_BEGIN(Bro, Login) + BRO_PLUGIN_DESCRIPTION("Telnet/Rsh/Rlogin analyzers"); + BRO_PLUGIN_ANALYZER("Telnet", login::Telnet_Analyzer); + BRO_PLUGIN_ANALYZER("Rsh", login::Rsh_Analyzer); + BRO_PLUGIN_ANALYZER("Rlogin", login::Rlogin_Analyzer); + BRO_PLUGIN_ANALYZER_BARE("NVT"); + BRO_PLUGIN_ANALYZER_BARE("Login"); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_Rsh"); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_Rlogin"); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/RSH.cc b/src/analyzer/protocol/login/RSH.cc similarity index 92% rename from src/RSH.cc rename to src/analyzer/protocol/login/RSH.cc index ceef3ba7a4..1890fc3098 100644 --- a/src/RSH.cc +++ b/src/analyzer/protocol/login/RSH.cc @@ -6,12 +6,15 @@ #include "Event.h" #include "RSH.h" +#include "events.bif.h" + +using namespace analyzer::login; // FIXME: this code should probably be merged with Rlogin.cc. Contents_Rsh_Analyzer::Contents_Rsh_Analyzer(Connection* conn, bool orig, Rsh_Analyzer* arg_analyzer) -: ContentLine_Analyzer(AnalyzerTag::Contents_Rsh, conn, orig) +: tcp::ContentLine_Analyzer("CONTENTS_RSH", conn, orig) { num_bytes_to_scan = 0; analyzer = arg_analyzer; @@ -28,7 +31,7 @@ Contents_Rsh_Analyzer::~Contents_Rsh_Analyzer() void Contents_Rsh_Analyzer::DoDeliver(int len, const u_char* data) { - TCP_Analyzer* tcp = static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = static_cast(Parent())->TCP(); assert(tcp); int endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); @@ -42,10 +45,10 @@ void Contents_Rsh_Analyzer::DoDeliver(int len, const u_char* data) switch ( state ) { case RSH_FIRST_NULL: - if ( endp_state == TCP_ENDPOINT_PARTIAL || + if ( endp_state == tcp::TCP_ENDPOINT_PARTIAL || // We can be in closed if the data's due to // a dataful FIN being the first thing we see. - endp_state == TCP_ENDPOINT_CLOSED ) + endp_state == tcp::TCP_ENDPOINT_CLOSED ) { state = RSH_UNKNOWN; ++len, --data; // put back c and reprocess @@ -138,7 +141,7 @@ void Contents_Rsh_Analyzer::BadProlog() } Rsh_Analyzer::Rsh_Analyzer(Connection* conn) -: Login_Analyzer(AnalyzerTag::Rsh, conn) +: Login_Analyzer("RSH", conn) { contents_orig = new Contents_Rsh_Analyzer(conn, true, this); contents_resp = new Contents_Rsh_Analyzer(conn, false, this); diff --git a/src/RSH.h b/src/analyzer/protocol/login/RSH.h similarity index 79% rename from src/RSH.h rename to src/analyzer/protocol/login/RSH.h index 136d0b07f1..2036ea966a 100644 --- a/src/RSH.h +++ b/src/analyzer/protocol/login/RSH.h @@ -1,10 +1,12 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef rsh_h -#define rsh_h +#ifndef ANALYZER_PROTOCOL_LOGIN_RSH_H +#define ANALYZER_PROTOCOL_LOGIN_RSH_H #include "Login.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +namespace analyzer { namespace login { typedef enum { RSH_FIRST_NULL, // waiting to see first NUL @@ -21,7 +23,7 @@ typedef enum { class Rsh_Analyzer; -class Contents_Rsh_Analyzer : public ContentLine_Analyzer { +class Contents_Rsh_Analyzer : public tcp::ContentLine_Analyzer { public: Contents_Rsh_Analyzer(Connection* conn, bool orig, Rsh_Analyzer* analyzer); ~Contents_Rsh_Analyzer(); @@ -47,14 +49,13 @@ public: void ClientUserName(const char* s); void ServerUserName(const char* s); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Rsh_Analyzer(conn); } - static bool Available() - { return login_failure || login_success || login_input_line || login_output_line; } - Contents_Rsh_Analyzer* contents_orig; Contents_Rsh_Analyzer* contents_resp; }; +} } // namespace analyzer::* + #endif diff --git a/src/Rlogin.cc b/src/analyzer/protocol/login/Rlogin.cc similarity index 91% rename from src/Rlogin.cc rename to src/analyzer/protocol/login/Rlogin.cc index 1ad3f16d7e..9a31a47aa1 100644 --- a/src/Rlogin.cc +++ b/src/analyzer/protocol/login/Rlogin.cc @@ -6,9 +6,12 @@ #include "Event.h" #include "Rlogin.h" +#include "events.bif.h" + +using namespace analyzer::login; Contents_Rlogin_Analyzer::Contents_Rlogin_Analyzer(Connection* conn, bool orig, Rlogin_Analyzer* arg_analyzer) -: ContentLine_Analyzer(AnalyzerTag::Contents_Rlogin, conn, orig) +: tcp::ContentLine_Analyzer("CONTENTLINE", conn, orig) { num_bytes_to_scan = 0; analyzer = arg_analyzer; @@ -26,7 +29,7 @@ Contents_Rlogin_Analyzer::~Contents_Rlogin_Analyzer() void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data) { - TCP_Analyzer* tcp = static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = static_cast(Parent())->TCP(); assert(tcp); int endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); @@ -40,10 +43,10 @@ void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data) switch ( state ) { case RLOGIN_FIRST_NULL: - if ( endp_state == TCP_ENDPOINT_PARTIAL || + if ( endp_state == tcp::TCP_ENDPOINT_PARTIAL || // We can be in closed if the data's due to // a dataful FIN being the first thing we see. - endp_state == TCP_ENDPOINT_CLOSED ) + endp_state == tcp::TCP_ENDPOINT_CLOSED ) { state = RLOGIN_UNKNOWN; ++len, --data; // put back c and reprocess @@ -85,10 +88,10 @@ void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data) break; case RLOGIN_SERVER_ACK: - if ( endp_state == TCP_ENDPOINT_PARTIAL || + if ( endp_state == tcp::TCP_ENDPOINT_PARTIAL || // We can be in closed if the data's due to // a dataful FIN being the first thing we see. - endp_state == TCP_ENDPOINT_CLOSED ) + endp_state == tcp::TCP_ENDPOINT_CLOSED ) { state = RLOGIN_UNKNOWN; ++len, --data; // put back c and reprocess @@ -204,7 +207,7 @@ void Contents_Rlogin_Analyzer::BadProlog() Rlogin_Analyzer::Rlogin_Analyzer(Connection* conn) -: Login_Analyzer(AnalyzerTag::Rlogin, conn) +: Login_Analyzer("RLOGIN", conn) { Contents_Rlogin_Analyzer* orig = new Contents_Rlogin_Analyzer(conn, true, this); diff --git a/src/Rlogin.h b/src/analyzer/protocol/login/Rlogin.h similarity index 82% rename from src/Rlogin.h rename to src/analyzer/protocol/login/Rlogin.h index f8ad480630..79de3b8952 100644 --- a/src/Rlogin.h +++ b/src/analyzer/protocol/login/Rlogin.h @@ -1,10 +1,12 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef rlogin_h -#define rlogin_h +#ifndef ANALYZER_PROTOCOL_LOGIN_RLOGIN_H +#define ANALYZER_PROTOCOL_LOGIN_RLOGIN_H #include "Login.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +namespace analyzer { namespace login { typedef enum { RLOGIN_FIRST_NULL, // waiting to see first NUL @@ -29,7 +31,7 @@ typedef enum { class Rlogin_Analyzer; -class Contents_Rlogin_Analyzer : public ContentLine_Analyzer { +class Contents_Rlogin_Analyzer : public tcp::ContentLine_Analyzer { public: Contents_Rlogin_Analyzer(Connection* conn, bool orig, Rlogin_Analyzer* analyzer); @@ -60,14 +62,10 @@ public: void ServerUserName(const char* s); void TerminalType(const char* s); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Rlogin_Analyzer(conn); } - - static bool Available() - { - return login_failure || login_success || - login_input_line || login_output_line; - } }; +} } // namespace analyzer::* + #endif diff --git a/src/Telnet.cc b/src/analyzer/protocol/login/Telnet.cc similarity index 82% rename from src/Telnet.cc rename to src/analyzer/protocol/login/Telnet.cc index 62c7d7b500..c22b2afc5e 100644 --- a/src/Telnet.cc +++ b/src/analyzer/protocol/login/Telnet.cc @@ -5,8 +5,12 @@ #include "Telnet.h" #include "NVT.h" +#include "events.bif.h" + +using namespace analyzer::login; + Telnet_Analyzer::Telnet_Analyzer(Connection* conn) -: Login_Analyzer(AnalyzerTag::Telnet, conn) +: Login_Analyzer("TELNET", conn) { NVT_Analyzer* nvt_orig = new NVT_Analyzer(conn, true); NVT_Analyzer* nvt_resp = new NVT_Analyzer(conn, false); diff --git a/src/Telnet.h b/src/analyzer/protocol/login/Telnet.h similarity index 55% rename from src/Telnet.h rename to src/analyzer/protocol/login/Telnet.h index 5675775789..332281013c 100644 --- a/src/Telnet.h +++ b/src/analyzer/protocol/login/Telnet.h @@ -1,23 +1,21 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef telnet_h -#define telnet_h +#ifndef ANALYZER_PROTOCOL_LOGIN_TELNET_H +#define ANALYZER_PROTOCOL_LOGIN_TELNET_H #include "Login.h" +namespace analyzer { namespace login { + class Telnet_Analyzer : public Login_Analyzer { public: Telnet_Analyzer(Connection* conn); virtual ~Telnet_Analyzer() {} - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Telnet_Analyzer(conn); } - - static bool Available() - { - return login_failure || login_success || - login_input_line || login_output_line; - } }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/login/events.bif b/src/analyzer/protocol/login/events.bif new file mode 100644 index 0000000000..68f1c3cf11 --- /dev/null +++ b/src/analyzer/protocol/login/events.bif @@ -0,0 +1,409 @@ +## Generated for client side commands on an RSH connection. +## +## See `RFC 1258 `__ for more information +## about the Rlogin/Rsh protocol. +## +## c: The connection. +## +## client_user: The client-side user name as sent in the initial protocol +## handshake. +## +## server_user: The server-side user name as sent in the initial protocol +## handshake. +## +## line: The command line sent in the request. +## +## new_session: True if this is the first command of the Rsh session. +## +## .. bro:see:: rsh_reply login_confused login_confused_text login_display +## login_failure login_input_line login_output_line login_prompt login_success +## login_terminal +## +## .. note:: For historical reasons, these events are separate from the +## ``login_`` events. Ideally, they would all be handled uniquely. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event rsh_request%(c: connection, client_user: string, server_user: string, line: string, new_session: bool%); + +## Generated for client side commands on an RSH connection. +## +## See `RFC 1258 `__ for more information +## about the Rlogin/Rsh protocol. +## +## c: The connection. +## +## client_user: The client-side user name as sent in the initial protocol +## handshake. +## +## server_user: The server-side user name as sent in the initial protocol +## handshake. +## +## line: The command line sent in the request. +## +## .. bro:see:: rsh_request login_confused login_confused_text login_display +## login_failure login_input_line login_output_line login_prompt login_success +## login_terminal +## +## .. note:: For historical reasons, these events are separate from the +## ``login_`` events. Ideally, they would all be handled uniquely. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event rsh_reply%(c: connection, client_user: string, server_user: string, line: string%); + +## Generated for Telnet/Rlogin login failures. The *login* analyzer inspects +## Telnet/Rlogin sessions to heuristically extract username and password +## information as well as the text returned by the login server. This event is +## raised if a login attempt appears to have been unsuccessful. +## +## c: The connection. +## +## user: The user name tried. +## +## client_user: For Telnet connections, this is an empty string, but for Rlogin +## connections, it is the client name passed in the initial authentication +## information (to check against .rhosts). +## +## password: The password tried. +## +## line: The line of text that led the analyzer to conclude that the +## authentication had failed. +## +## .. bro:see:: login_confused login_confused_text login_display login_input_line +## login_output_line login_prompt login_success login_terminal direct_login_prompts +## get_login_state login_failure_msgs login_non_failure_msgs login_prompts login_success_msgs +## login_timeouts set_login_state +## +## .. note:: The login analyzer depends on a set of script-level variables that +## need to be configured with patterns identifying login attempts. This +## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and +## the analyzer is therefore not directly usable at the moment. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_failure%(c: connection, user: string, client_user: string, password: string, line: string%); + +## Generated for successful Telnet/Rlogin logins. The *login* analyzer inspects +## Telnet/Rlogin sessions to heuristically extract username and password +## information as well as the text returned by the login server. This event is +## raised if a login attempt appears to have been successful. +## +## c: The connection. +## +## user: The user name used. +## +## client_user: For Telnet connections, this is an empty string, but for Rlogin +## connections, it is the client name passed in the initial authentication +## information (to check against .rhosts). +## +## password: The password used. +## +## line: The line of text that led the analyzer to conclude that the +## authentication had succeeded. +## +## .. bro:see:: login_confused login_confused_text login_display login_failure +## login_input_line login_output_line login_prompt login_terminal +## direct_login_prompts get_login_state login_failure_msgs login_non_failure_msgs +## login_prompts login_success_msgs login_timeouts set_login_state +## +## .. note:: The login analyzer depends on a set of script-level variables that +## need to be configured with patterns identifying login attempts. This +## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and +## the analyzer is therefore not directly usable at the moment. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_success%(c: connection, user: string, client_user: string, password: string, line: string%); + +## Generated for lines of input on Telnet/Rlogin sessions. The line will have +## control characters (such as in-band Telnet options) removed. +## +## c: The connection. +## +## line: The input line. +## +## .. bro:see:: login_confused login_confused_text login_display login_failure +## login_output_line login_prompt login_success login_terminal rsh_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_input_line%(c: connection, line: string%); + +## Generated for lines of output on Telnet/Rlogin sessions. The line will have +## control characters (such as in-band Telnet options) removed. +## +## c: The connection. +## +## line: The ouput line. +## +## .. bro:see:: login_confused login_confused_text login_display login_failure +## login_input_line login_prompt login_success login_terminal rsh_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_output_line%(c: connection, line: string%); + +## Generated when tracking of Telnet/Rlogin authentication failed. As Bro's +## *login* analyzer uses a number of heuristics to extract authentication +## information, it may become confused. If it can no longer correctly track +## the authentication dialog, it raises this event. +## +## c: The connection. +## +## msg: Gives the particular problem the heuristics detected (for example, +## ``multiple_login_prompts`` means that the engine saw several login +## prompts in a row, without the type-ahead from the client side presumed +## necessary to cause them) +## +## line: The line of text that caused the heuristics to conclude they were +## confused. +## +## .. bro:see:: login_confused_text login_display login_failure login_input_line login_output_line +## login_prompt login_success login_terminal direct_login_prompts get_login_state +## login_failure_msgs login_non_failure_msgs login_prompts login_success_msgs +## login_timeouts set_login_state +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_confused%(c: connection, msg: string, line: string%); + +## Generated after getting confused while tracking a Telnet/Rlogin +## authentication dialog. The *login* analyzer generates this even for every +## line of user input after it has reported :bro:id:`login_confused` for a +## connection. +## +## c: The connection. +## +## line: The line the user typed. +## +## .. bro:see:: login_confused login_display login_failure login_input_line +## login_output_line login_prompt login_success login_terminal direct_login_prompts +## get_login_state login_failure_msgs login_non_failure_msgs login_prompts +## login_success_msgs login_timeouts set_login_state +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_confused_text%(c: connection, line: string%); + +## Generated for clients transmitting a terminal type in a Telnet session. This +## information is extracted out of environment variables sent as Telnet options. +## +## c: The connection. +## +## terminal: The TERM value transmitted. +## +## .. bro:see:: login_confused login_confused_text login_display login_failure +## login_input_line login_output_line login_prompt login_success +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_terminal%(c: connection, terminal: string%); + +## Generated for clients transmitting an X11 DISPLAY in a Telnet session. This +## information is extracted out of environment variables sent as Telnet options. +## +## c: The connection. +## +## display: The DISPLAY transmitted. +## +## .. bro:see:: login_confused login_confused_text login_failure login_input_line +## login_output_line login_prompt login_success login_terminal +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_display%(c: connection, display: string%); + +## Generated when a Telnet authentication has been successful. The Telnet +## protocol includes options for negotiating authentication. When such an +## option is sent from client to server and the server replies that it accepts +## the authentication, then the event engine generates this event. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## name: The authenticated name. +## +## c: The connection. +## +## .. bro:see:: authentication_rejected authentication_skipped login_success +## +## .. note:: This event inspects the corresponding Telnet option +## while :bro:id:`login_success` heuristically determines success by watching +## session data. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event authentication_accepted%(name: string, c: connection%); + +## Generated when a Telnet authentication has been unsuccessful. The Telnet +## protocol includes options for negotiating authentication. When such an option +## is sent from client to server and the server replies that it did not accept +## the authentication, then the event engine generates this event. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## name: The attempted authentication name. +## +## c: The connection. +## +## .. bro:see:: authentication_accepted authentication_skipped login_failure +## +## .. note:: This event inspects the corresponding Telnet option +## while :bro:id:`login_success` heuristically determines failure by watching +## session data. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event authentication_rejected%(name: string, c: connection%); + +## Generated for Telnet/Rlogin sessions when a pattern match indicates +## that no authentication is performed. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## .. bro:see:: authentication_accepted authentication_rejected direct_login_prompts +## get_login_state login_failure_msgs login_non_failure_msgs login_prompts +## login_success_msgs login_timeouts set_login_state +## +## .. note:: The login analyzer depends on a set of script-level variables that +## need to be configured with patterns identifying activity. This +## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and +## the analyzer is therefore not directly usable at the moment. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event authentication_skipped%(c: connection%); + +## Generated for clients transmitting a terminal prompt in a Telnet session. +## This information is extracted out of environment variables sent as Telnet +## options. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## prompt: The TTYPROMPT transmitted. +## +## .. bro:see:: login_confused login_confused_text login_display login_failure +## login_input_line login_output_line login_success login_terminal +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event login_prompt%(c: connection, prompt: string%); + +## Generated for Telnet sessions when encryption is activated. The Telnet +## protocol includes options for negotiating encryption. When such a series of +## options is successfully negotiated, the event engine generates this event. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## .. bro:see:: authentication_accepted authentication_rejected authentication_skipped +## login_confused login_confused_text login_display login_failure login_input_line +## login_output_line login_prompt login_success login_terminal +event activating_encryption%(c: connection%); + +## Generated for an inconsistent Telnet option. Telnet options are specified +## by the client and server stating which options they are willing to +## support vs. which they are not, and then instructing one another which in +## fact they should or should not use for the current connection. If the event +## engine sees a peer violate either what the other peer has instructed it to +## do, or what it itself offered in terms of options in the past, then the +## engine generates this event. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## .. bro:see:: bad_option bad_option_termination authentication_accepted +## authentication_rejected authentication_skipped login_confused +## login_confused_text login_display login_failure login_input_line +## login_output_line login_prompt login_success login_terminal +event inconsistent_option%(c: connection%); + +## Generated for an ill-formed or unrecognized Telnet option. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## .. bro:see:: inconsistent_option bad_option_termination authentication_accepted +## authentication_rejected authentication_skipped login_confused +## login_confused_text login_display login_failure login_input_line +## login_output_line login_prompt login_success login_terminal +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event bad_option%(c: connection%); + +## Generated for a Telnet option that's incorrectly terminated. +## +## See `Wikipedia `__ for more information +## about the Telnet protocol. +## +## c: The connection. +## +## .. bro:see:: inconsistent_option bad_option authentication_accepted +## authentication_rejected authentication_skipped login_confused +## login_confused_text login_display login_failure login_input_line +## login_output_line login_prompt login_success login_terminal +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event bad_option_termination%(c: connection%); diff --git a/src/analyzer/protocol/login/functions.bif b/src/analyzer/protocol/login/functions.bif new file mode 100644 index 0000000000..c3d7cbf82b --- /dev/null +++ b/src/analyzer/protocol/login/functions.bif @@ -0,0 +1,62 @@ + +%%{ +#include "Login.h" +%%} + +## Returns the state of the given login (Telnet or Rlogin) connection. +## +## cid: The connection ID. +## +## Returns: False if the connection is not active or is not tagged as a +## login analyzer. Otherwise the function returns the state, which can +## be one of: +## +## - ``LOGIN_STATE_AUTHENTICATE``: The connection is in its +## initial authentication dialog. +## - ``LOGIN_STATE_LOGGED_IN``: The analyzer believes the user has +## successfully authenticated. +## - ``LOGIN_STATE_SKIP``: The analyzer has skipped any further +## processing of the connection. +## - ``LOGIN_STATE_CONFUSED``: The analyzer has concluded that it +## does not correctly know the state of the connection, and/or +## the username associated with it. +## +## .. bro:see:: set_login_state +function get_login_state%(cid: conn_id%): count + %{ + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + return new Val(0, TYPE_BOOL); + + analyzer::Analyzer* la = c->FindAnalyzer("Login"); + if ( ! la ) + return new Val(0, TYPE_BOOL); + + return new Val(int(static_cast(la)->LoginState()), + TYPE_COUNT); + %} + +## Sets the login state of a connection with a login analyzer. +## +## cid: The connection ID. +## +## new_state: The new state of the login analyzer. See +## :bro:id:`get_login_state` for possible values. +## +## Returns: Returns false if *cid* is not an active connection +## or is not tagged as a login analyzer, and true otherwise. +## +## .. bro:see:: get_login_state +function set_login_state%(cid: conn_id, new_state: count%): bool + %{ + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + return new Val(0, TYPE_BOOL); + + analyzer::Analyzer* la = c->FindAnalyzer("Login"); + if ( ! la ) + return new Val(0, TYPE_BOOL); + + static_cast(la)->SetLoginState(analyzer::login::login_state(new_state)); + return new Val(1, TYPE_BOOL); + %} diff --git a/src/analyzer/protocol/mime/CMakeLists.txt b/src/analyzer/protocol/mime/CMakeLists.txt new file mode 100644 index 0000000000..0a038625f8 --- /dev/null +++ b/src/analyzer/protocol/mime/CMakeLists.txt @@ -0,0 +1,15 @@ + +# This is not an actual analyzer, but used by others. We still +# maintain it here along with the other analyzers because conceptually +# it's also parsing a protocol just like them. The current structure +# is merely a left-over from when this code was written. + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro MIME) +bro_plugin_cc(MIME.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() + diff --git a/src/MIME.cc b/src/analyzer/protocol/mime/MIME.cc similarity index 98% rename from src/MIME.cc rename to src/analyzer/protocol/mime/MIME.cc index 3104ed2e8e..039f26b905 100644 --- a/src/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -7,6 +7,8 @@ #include "digest.h" #include "file_analysis/Manager.h" +#include "events.bif.h" + // Here are a few things to do: // // 1. Add a Bro internal function 'stop_deliver_data_of_entity' so @@ -17,44 +19,10 @@ // headers of form: =; =; // =; ... (so that +namespace analyzer { namespace mime { + static const data_chunk_t null_data_chunk = { 0, 0 }; -int is_null_data_chunk(data_chunk_t b) - { - return b.data == 0; - } - -int fputs(data_chunk_t b, FILE* fp) - { - for ( int i = 0; i < b.length; ++i ) - if ( fputc(b.data[i], fp) == EOF ) - return EOF; - return 0; - } - -StringVal* new_string_val(int length, const char* data) - { - return new StringVal(length, data); - } - -StringVal* new_string_val(const char* data, const char* end_of_data) - { - return new StringVal(end_of_data - data, data); - } - -StringVal* new_string_val(const data_chunk_t buf) - { - return new_string_val(buf.length, buf.data); - } - -data_chunk_t get_data_chunk(BroString* s) - { - data_chunk_t b; - b.length = s->Len(); - b.data = (const char*) s->Bytes(); - return b; - } - int mime_header_only = 0; int mime_decode_data = 1; int mime_submit_data = 1; @@ -130,6 +98,326 @@ static const char* MIMEContentEncodingName[] = { 0, }; +int is_null_data_chunk(data_chunk_t b) + { + return b.data == 0; + } + +int is_lws(char ch) + { + return ch == 9 || ch == 32; + } + +StringVal* new_string_val(int length, const char* data) + { + return new StringVal(length, data); + } + +StringVal* new_string_val(const char* data, const char* end_of_data) + { + return new StringVal(end_of_data - data, data); + } + +StringVal* new_string_val(const data_chunk_t buf) + { + return new_string_val(buf.length, buf.data); + } + +static data_chunk_t get_data_chunk(BroString* s) + { + data_chunk_t b; + b.length = s->Len(); + b.data = (const char*) s->Bytes(); + return b; + } + +int fputs(data_chunk_t b, FILE* fp) + { + for ( int i = 0; i < b.length; ++i ) + if ( fputc(b.data[i], fp) == EOF ) + return EOF; + return 0; + } + +void MIME_Mail::Undelivered(int len) + { + // is_orig param not available, doesn't matter as long as it's consistent + file_mgr->Gap(cur_entity_len, len, analyzer->GetAnalyzerTag(), analyzer->Conn(), + false); + } + +int strcasecmp_n(data_chunk_t s, const char* t) + { + return ::strcasecmp_n(s.length, s.data, t); + } + +int MIME_count_leading_lws(int len, const char* data) + { + int i; + for ( i = 0; i < len; ++i ) + if ( ! is_lws(data[i]) ) + break; + return i; + } + +int MIME_count_trailing_lws(int len, const char* data) + { + int i; + for ( i = 0; i < len; ++i ) + if ( ! is_lws(data[len - 1 - i]) ) + break; + return i; + } + +// See RFC 2822, page 11 +int MIME_skip_comments(int len, const char* data) + { + if ( len == 0 || data[0] != '(' ) + return 0; + + int par = 0; + for ( int i = 0; i < len; ++i ) + { + switch ( data[i] ) { + case '(': + ++par; + break; + + case ')': + --par; + if ( par == 0 ) + return i + 1; + break; + + case '\\': + ++i; + break; + } + } + + return len; + } + +// Skip over lws and comments, but not tspecials. Do not use this +// function in quoted-string or comments. +int MIME_skip_lws_comments(int len, const char* data) + { + int i = 0; + while ( i < len ) + { + if ( is_lws(data[i]) ) + ++i; + else + { + if ( data[i] == '(' ) + i += MIME_skip_comments(len - i, data + i); + else + return i; + } + } + + return len; + } + +int MIME_get_field_name(int len, const char* data, data_chunk_t* name) + { + int i = MIME_skip_lws_comments(len, data); + while ( i < len ) + { + int j; + if ( MIME_is_field_name_char(data[i]) ) + { + name->data = data + i; + + for ( j = i; j < len; ++j ) + if ( ! MIME_is_field_name_char(data[j]) ) + break; + + name->length = j - i; + return j; + } + + j = MIME_skip_lws_comments(len - i, data + i); + i += (j > 0) ? j : 1; + } + + return -1; + } + +// See RFC 2045, page 12. +int MIME_is_tspecial (char ch) + { + return ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '@' || + ch == ',' || ch == ';' || ch == ':' || ch == '\\' || ch == '"' || + ch == '/' || ch == '[' || ch == ']' || ch == '?' || ch == '='; + } + +int MIME_is_field_name_char (char ch) + { + return ch >= 33 && ch <= 126 && ch != ':'; + } + +int MIME_is_token_char (char ch) + { + return ch >= 33 && ch <= 126 && ! MIME_is_tspecial(ch); + } + +// See RFC 2045, page 12. +// A token is composed of characters that are not SPACE, CTLs or tspecials +int MIME_get_token(int len, const char* data, data_chunk_t* token) + { + int i = MIME_skip_lws_comments(len, data); + while ( i < len ) + { + int j; + + if ( MIME_is_token_char(data[i]) ) + { + token->data = (data + i); + for ( j = i; j < len; ++j ) + { + if ( ! MIME_is_token_char(data[j]) ) + break; + } + + token->length = j - i; + return j; + } + + j = MIME_skip_lws_comments(len - i, data + i); + i += (j > 0) ? j : 1; + } + + return -1; + } + +int MIME_get_slash_token_pair(int len, const char* data, data_chunk_t* first, data_chunk_t* second) + { + int offset; + const char* data_start = data; + + offset = MIME_get_token(len, data, first); + if ( offset < 0 ) + { + // DEBUG_MSG("first token missing in slash token pair"); + return -1; + } + + data += offset; + len -= offset; + + offset = MIME_skip_lws_comments(len, data); + if ( offset < 0 || offset >= len || data[offset] != '/' ) + { + // DEBUG_MSG("/ not found in slash token pair"); + return -1; + } + + ++offset; + data += offset; + len -= offset; + + offset = MIME_get_token(len, data, second); + if ( offset < 0 ) + { + // DEBUG_MSG("second token missing in slash token pair"); + return -1; + } + + data += offset; + len -= offset; + + return data - data_start; + } + +// See RFC 2822, page 13. +int MIME_get_quoted_string(int len, const char* data, data_chunk_t* str) + { + int offset = MIME_skip_lws_comments(len, data); + + len -= offset; + data += offset; + + if ( len <= 0 || *data != '"' ) + return -1; + + for ( int i = 1; i < len; ++i ) + { + switch ( data[i] ) { + case '"': + str->data = data + 1; + str->length = i - 1; + return offset + i + 1; + + case '\\': + ++i; + break; + } + } + + return -1; + } + +int MIME_get_value(int len, const char* data, BroString*& buf) + { + int offset = MIME_skip_lws_comments(len, data); + + len -= offset; + data += offset; + + if ( len > 0 && *data == '"' ) + { + data_chunk_t str; + int end = MIME_get_quoted_string(len, data, &str); + if ( end < 0 ) + return -1; + + buf = MIME_decode_quoted_pairs(str); + return offset + end; + } + + else + { + data_chunk_t str; + int end = MIME_get_token(len, data, &str); + if ( end < 0 ) + return -1; + + buf = new BroString((const u_char*)str.data, str.length, 1); + return offset + end; + } + } + +// Decode each quoted-pair: a '\' followed by a character by the +// quoted character. The decoded string is returned. + +BroString* MIME_decode_quoted_pairs(data_chunk_t buf) + { + const char* data = buf.data; + char* dest = new char[buf.length+1]; + int j = 0; + for ( int i = 0; i < buf.length; ++i ) + if ( data[i] == '\\' ) + { + if ( ++i < buf.length ) + dest[j++] = data[i]; + else + { + // a trailing '\' -- don't know what + // to do with it -- ignore it. + } + } + else + dest[j++] = data[i]; + dest[j] = 0; + + return new BroString(1, (byte_vec) dest, j); + } + + +} } // namespace analyzer::* + +using namespace analyzer::mime; MIME_Multiline::MIME_Multiline() { @@ -967,7 +1255,7 @@ TableVal* MIME_Message::BuildHeaderTable(MIME_HeaderList& hlist) return t; } -MIME_Mail::MIME_Mail(Analyzer* mail_analyzer, int buf_size) +MIME_Mail::MIME_Mail(analyzer::Analyzer* mail_analyzer, int buf_size) : MIME_Message(mail_analyzer) { analyzer = mail_analyzer; @@ -1021,7 +1309,7 @@ void MIME_Mail::Done() MIME_Message::Done(); - file_mgr->EndOfFile(analyzer->GetTag(), analyzer->Conn()); + file_mgr->EndOfFile(analyzer->GetAnalyzerTag(), analyzer->Conn()); } MIME_Mail::~MIME_Mail() @@ -1072,7 +1360,7 @@ void MIME_Mail::EndEntity(MIME_Entity* /* entity */) analyzer->ConnectionEvent(mime_end_entity, vl); } - file_mgr->EndOfFile(analyzer->GetTag(), analyzer->Conn()); + file_mgr->EndOfFile(analyzer->GetAnalyzerTag(), analyzer->Conn()); } void MIME_Mail::SubmitHeader(MIME_Header* h) @@ -1132,7 +1420,7 @@ void MIME_Mail::SubmitData(int len, const char* buf) // is_orig param not available, doesn't matter as long as it's consistent file_mgr->DataIn(reinterpret_cast(buf), len, - analyzer->GetTag(), analyzer->Conn(), false); + analyzer->GetAnalyzerTag(), analyzer->Conn(), false); cur_entity_len += len; buffer_start = (buf + len) - (char*)data_buffer->Bytes(); @@ -1205,283 +1493,3 @@ void MIME_Mail::SubmitEvent(int event_type, const char* detail) analyzer->ConnectionEvent(mime_event, vl); } } - -void MIME_Mail::Undelivered(int len) - { - // is_orig param not available, doesn't matter as long as it's consistent - file_mgr->Gap(cur_entity_len, len, analyzer->GetTag(), analyzer->Conn(), - false); - } - -int strcasecmp_n(data_chunk_t s, const char* t) - { - return strcasecmp_n(s.length, s.data, t); - } - -int is_lws(char ch) - { - return ch == 9 || ch == 32; - } - -int MIME_count_leading_lws(int len, const char* data) - { - int i; - for ( i = 0; i < len; ++i ) - if ( ! is_lws(data[i]) ) - break; - return i; - } - -int MIME_count_trailing_lws(int len, const char* data) - { - int i; - for ( i = 0; i < len; ++i ) - if ( ! is_lws(data[len - 1 - i]) ) - break; - return i; - } - -// See RFC 2822, page 11 -int MIME_skip_comments(int len, const char* data) - { - if ( len == 0 || data[0] != '(' ) - return 0; - - int par = 0; - for ( int i = 0; i < len; ++i ) - { - switch ( data[i] ) { - case '(': - ++par; - break; - - case ')': - --par; - if ( par == 0 ) - return i + 1; - break; - - case '\\': - ++i; - break; - } - } - - return len; - } - -// Skip over lws and comments, but not tspecials. Do not use this -// function in quoted-string or comments. -int MIME_skip_lws_comments(int len, const char* data) - { - int i = 0; - while ( i < len ) - { - if ( is_lws(data[i]) ) - ++i; - else - { - if ( data[i] == '(' ) - i += MIME_skip_comments(len - i, data + i); - else - return i; - } - } - - return len; - } - -int MIME_get_field_name(int len, const char* data, data_chunk_t* name) - { - int i = MIME_skip_lws_comments(len, data); - while ( i < len ) - { - int j; - if ( MIME_is_field_name_char(data[i]) ) - { - name->data = data + i; - - for ( j = i; j < len; ++j ) - if ( ! MIME_is_field_name_char(data[j]) ) - break; - - name->length = j - i; - return j; - } - - j = MIME_skip_lws_comments(len - i, data + i); - i += (j > 0) ? j : 1; - } - - return -1; - } - -// See RFC 2045, page 12. -int MIME_is_tspecial (char ch) - { - return ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '@' || - ch == ',' || ch == ';' || ch == ':' || ch == '\\' || ch == '"' || - ch == '/' || ch == '[' || ch == ']' || ch == '?' || ch == '='; - } - -int MIME_is_field_name_char (char ch) - { - return ch >= 33 && ch <= 126 && ch != ':'; - } - -int MIME_is_token_char (char ch) - { - return ch >= 33 && ch <= 126 && ! MIME_is_tspecial(ch); - } - -// See RFC 2045, page 12. -// A token is composed of characters that are not SPACE, CTLs or tspecials -int MIME_get_token(int len, const char* data, data_chunk_t* token) - { - int i = MIME_skip_lws_comments(len, data); - while ( i < len ) - { - int j; - - if ( MIME_is_token_char(data[i]) ) - { - token->data = (data + i); - for ( j = i; j < len; ++j ) - { - if ( ! MIME_is_token_char(data[j]) ) - break; - } - - token->length = j - i; - return j; - } - - j = MIME_skip_lws_comments(len - i, data + i); - i += (j > 0) ? j : 1; - } - - return -1; - } - -int MIME_get_slash_token_pair(int len, const char* data, data_chunk_t* first, data_chunk_t* second) - { - int offset; - const char* data_start = data; - - offset = MIME_get_token(len, data, first); - if ( offset < 0 ) - { - // DEBUG_MSG("first token missing in slash token pair"); - return -1; - } - - data += offset; - len -= offset; - - offset = MIME_skip_lws_comments(len, data); - if ( offset < 0 || offset >= len || data[offset] != '/' ) - { - // DEBUG_MSG("/ not found in slash token pair"); - return -1; - } - - ++offset; - data += offset; - len -= offset; - - offset = MIME_get_token(len, data, second); - if ( offset < 0 ) - { - // DEBUG_MSG("second token missing in slash token pair"); - return -1; - } - - data += offset; - len -= offset; - - return data - data_start; - } - -// See RFC 2822, page 13. -int MIME_get_quoted_string(int len, const char* data, data_chunk_t* str) - { - int offset = MIME_skip_lws_comments(len, data); - - len -= offset; - data += offset; - - if ( len <= 0 || *data != '"' ) - return -1; - - for ( int i = 1; i < len; ++i ) - { - switch ( data[i] ) { - case '"': - str->data = data + 1; - str->length = i - 1; - return offset + i + 1; - - case '\\': - ++i; - break; - } - } - - return -1; - } - -int MIME_get_value(int len, const char* data, BroString*& buf) - { - int offset = MIME_skip_lws_comments(len, data); - - len -= offset; - data += offset; - - if ( len > 0 && *data == '"' ) - { - data_chunk_t str; - int end = MIME_get_quoted_string(len, data, &str); - if ( end < 0 ) - return -1; - - buf = MIME_decode_quoted_pairs(str); - return offset + end; - } - - else - { - data_chunk_t str; - int end = MIME_get_token(len, data, &str); - if ( end < 0 ) - return -1; - - buf = new BroString((const u_char*)str.data, str.length, 1); - return offset + end; - } - } - -// Decode each quoted-pair: a '\' followed by a character by the -// quoted character. The decoded string is returned. - -BroString* MIME_decode_quoted_pairs(data_chunk_t buf) - { - const char* data = buf.data; - char* dest = new char[buf.length+1]; - int j = 0; - for ( int i = 0; i < buf.length; ++i ) - if ( data[i] == '\\' ) - { - if ( ++i < buf.length ) - dest[j++] = data[i]; - else - { - // a trailing '\' -- don't know what - // to do with it -- ignore it. - } - } - else - dest[j++] = data[i]; - dest[j] = 0; - - return new BroString(1, (byte_vec) dest, j); - } diff --git a/src/MIME.h b/src/analyzer/protocol/mime/MIME.h similarity index 95% rename from src/MIME.h rename to src/analyzer/protocol/mime/MIME.h index eb30a43bd3..4d7a89f37a 100644 --- a/src/MIME.h +++ b/src/analyzer/protocol/mime/MIME.h @@ -1,5 +1,5 @@ -#ifndef mime_h -#define mime_h +#ifndef ANALYZER_PROTOCOL_MIME_MIME_H +#define ANALYZER_PROTOCOL_MIME_MIME_H #include #include @@ -10,7 +10,9 @@ using namespace std; #include "Base64.h" #include "BroString.h" -#include "Analyzer.h" +#include "analyzer/Analyzer.h" + +namespace analyzer { namespace mime { // MIME: Multipurpose Internet Mail Extensions // Follows RFC 822 & 2822 (Internet Mail), 2045-2049 (MIME) @@ -178,7 +180,7 @@ protected: class MIME_Message { public: - MIME_Message(Analyzer* arg_analyzer) + MIME_Message(analyzer::Analyzer* arg_analyzer) { // Cannot initialize top_level entity because we do // not know its type yet (MIME_Entity / MIME_Mail / @@ -203,7 +205,7 @@ public: top_level->Deliver(len, data, trailing_CRLF); } - Analyzer* GetAnalyzer() const { return analyzer; } + analyzer::Analyzer* GetAnalyzer() const { return analyzer; } // Events generated by MIME_Entity virtual void BeginEntity(MIME_Entity*) = 0; @@ -215,7 +217,7 @@ public: virtual void SubmitEvent(int event_type, const char* detail) = 0; protected: - Analyzer* analyzer; + analyzer::Analyzer* analyzer; MIME_Entity* top_level; int finished; @@ -226,7 +228,7 @@ protected: class MIME_Mail : public MIME_Message { public: - MIME_Mail(Analyzer* mail_conn, int buf_size = 0); + MIME_Mail(analyzer::Analyzer* mail_conn, int buf_size = 0); ~MIME_Mail(); void Done(); @@ -276,4 +278,6 @@ extern int MIME_get_value(int len, const char* data, BroString*& buf); extern int MIME_get_field_name(int len, const char* data, data_chunk_t* name); extern BroString* MIME_decode_quoted_pairs(data_chunk_t buf); +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/mime/Plugin.cc b/src/analyzer/protocol/mime/Plugin.cc new file mode 100644 index 0000000000..d519a8f84e --- /dev/null +++ b/src/analyzer/protocol/mime/Plugin.cc @@ -0,0 +1,7 @@ + +#include "plugin/Plugin.h" + +BRO_PLUGIN_BEGIN(Bro, MIME) + BRO_PLUGIN_DESCRIPTION("MIME parsing code"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/mime/events.bif b/src/analyzer/protocol/mime/events.bif new file mode 100644 index 0000000000..e9e5f66fda --- /dev/null +++ b/src/analyzer/protocol/mime/events.bif @@ -0,0 +1,196 @@ +## Generated when starting to parse an email MIME entity. MIME is a +## protocol-independent data format for encoding text and files, along with +## corresponding metadata, for transmission. Bro raises this event when it +## begins parsing a MIME entity extracted from an email protocol. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## .. bro:see:: mime_all_data mime_all_headers mime_content_hash mime_end_entity +## mime_entity_data mime_event mime_one_header mime_segment_data smtp_data +## http_begin_entity +## +## .. note:: Bro also extracts MIME entities from HTTP sessions. For those, +## however, it raises :bro:id:`http_begin_entity` instead. +event mime_begin_entity%(c: connection%); + +## Generated when finishing parsing an email MIME entity. MIME is a +## protocol-independent data format for encoding text and files, along with +## corresponding metadata, for transmission. Bro raises this event when it +## finished parsing a MIME entity extracted from an email protocol. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_entity_data mime_event mime_one_header mime_segment_data smtp_data +## http_end_entity +## +## .. note:: Bro also extracts MIME entities from HTTP sessions. For those, +## however, it raises :bro:id:`http_end_entity` instead. +event mime_end_entity%(c: connection%); + +## Generated for individual MIME headers extracted from email MIME +## entities. MIME is a protocol-independent data format for encoding text and +## files, along with corresponding metadata, for transmission. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## h: The parsed MIME header. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_event mime_segment_data +## http_header http_all_headers +## +## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, +## however, it raises :bro:id:`http_header` instead. +event mime_one_header%(c: connection, h: mime_header_rec%); + +## Generated for MIME headers extracted from email MIME entities, passing all +## headers at once. MIME is a protocol-independent data format for encoding +## text and files, along with corresponding metadata, for transmission. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## hlist: A *table* containing all headers extracted from the current entity. +## The table is indexed by the position of the header (1 for the first, +## 2 for the second, etc.). +## +## .. bro:see:: mime_all_data mime_begin_entity mime_content_hash mime_end_entity +## mime_entity_data mime_event mime_one_header mime_segment_data +## http_header http_all_headers +## +## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, +## however, it raises :bro:id:`http_header` instead. +event mime_all_headers%(c: connection, hlist: mime_header_list%); + +## Generated for chunks of decoded MIME data from email MIME entities. MIME +## is a protocol-independent data format for encoding text and files, along with +## corresponding metadata, for transmission. As Bro parses the data of an +## entity, it raises a sequence of these events, each coming as soon as a new +## chunk of data is available. In contrast, there is also +## :bro:id:`mime_entity_data`, which passes all of an entities data at once +## in a single block. While the latter is more convenient to handle, +## ``mime_segment_data`` is more efficient as Bro does not need to buffer +## the data. Thus, if possible, this event should be preferred. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## length: The length of *data*. +## +## data: The raw data of one segment of the current entity. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_event mime_one_header http_entity_data +## mime_segment_length mime_segment_overlap_length +## +## .. note:: Bro also extracts MIME data from HTTP sessions. For those, +## however, it raises :bro:id:`http_entity_data` (sic!) instead. +event mime_segment_data%(c: connection, length: count, data: string%); + +## Generated for data decoded from an email MIME entity. This event delivers +## the complete content of a single MIME entity. In contrast, there is also +## :bro:id:`mime_segment_data`, which passes on a sequence of data chunks as +## they come in. While ``mime_entity_data`` is more convenient to handle, +## ``mime_segment_data`` is more efficient as Bro does not need to buffer the +## data. Thus, if possible, the latter should be preferred. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## length: The length of *data*. +## +## data: The raw data of the complete entity. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_event mime_one_header mime_segment_data +## +## .. note:: While Bro also decodes MIME entities extracted from HTTP +## sessions, there's no corresponding event for that currently. +event mime_entity_data%(c: connection, length: count, data: string%); + +## Generated for passing on all data decoded from a single email MIME +## message. If an email message has more than one MIME entity, this event +## combines all their data into a single value for analysis. Note that because +## of the potentially significant buffering necessary, using this event can be +## expensive. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## length: The length of *data*. +## +## data: The raw data of all MIME entities concatenated. +## +## .. bro:see:: mime_all_headers mime_begin_entity mime_content_hash mime_end_entity +## mime_entity_data mime_event mime_one_header mime_segment_data +## +## .. note:: While Bro also decodes MIME entities extracted from HTTP +## sessions, there's no corresponding event for that currently. +event mime_all_data%(c: connection, length: count, data: string%); + +## Generated for errors found when decoding email MIME entities. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## event_type: A string describing the general category of the problem found +## (e.g., ``illegal format``). +## +## detail: Further more detailed description of the error. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_one_header mime_segment_data http_event +## +## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, +## however, it raises :bro:id:`http_event` instead. +event mime_event%(c: connection, event_type: string, detail: string%); + +## Generated for decoded MIME entities extracted from email messages, passing on +## their MD5 checksums. Bro computes the MD5 over the complete decoded data of +## each MIME entity. +## +## Bro's MIME analyzer for emails currently supports SMTP and POP3. See +## `Wikipedia `__ for more information +## about MIME. +## +## c: The connection. +## +## content_len: The length of the entity being hashed. +## +## hash_value: The MD5 hash. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_end_entity +## mime_entity_data mime_event mime_one_header mime_segment_data +## +## .. note:: While Bro also decodes MIME entities extracted from HTTP +## sessions, there's no corresponding event for that currently. +event mime_content_hash%(c: connection, content_len: count, hash_value: string%); + diff --git a/src/analyzer/protocol/modbus/CMakeLists.txt b/src/analyzer/protocol/modbus/CMakeLists.txt new file mode 100644 index 0000000000..e6705cdd22 --- /dev/null +++ b/src/analyzer/protocol/modbus/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Modbus) +bro_plugin_cc(Modbus.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(modbus.pac modbus-analyzer.pac modbus-protocol.pac) +bro_plugin_end() diff --git a/src/Modbus.cc b/src/analyzer/protocol/modbus/Modbus.cc similarity index 84% rename from src/Modbus.cc rename to src/analyzer/protocol/modbus/Modbus.cc index 278eb91e57..9d216d356b 100644 --- a/src/Modbus.cc +++ b/src/analyzer/protocol/modbus/Modbus.cc @@ -1,9 +1,13 @@ #include "Modbus.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" + +using namespace analyzer::modbus; ModbusTCP_Analyzer::ModbusTCP_Analyzer(Connection* c) - : TCP_ApplicationAnalyzer(AnalyzerTag::Modbus, c) + : TCP_ApplicationAnalyzer("MODBUS", c) { interp = new binpac::ModbusTCP::ModbusTCP_Conn(this); } diff --git a/src/analyzer/protocol/modbus/Modbus.h b/src/analyzer/protocol/modbus/Modbus.h new file mode 100644 index 0000000000..6f566be828 --- /dev/null +++ b/src/analyzer/protocol/modbus/Modbus.h @@ -0,0 +1,29 @@ +#ifndef ANALYZER_PROTOCOL_MODBUS_MODBUS_H +#define ANALYZER_PROTOCOL_MODBUS_MODBUS_H + +#include "analyzer/protocol/tcp/TCP.h" +#include "modbus_pac.h" + +namespace analyzer { namespace modbus { + +class ModbusTCP_Analyzer : public tcp::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::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new ModbusTCP_Analyzer(conn); } + +protected: + binpac::ModbusTCP::ModbusTCP_Conn* interp; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/modbus/Plugin.cc b/src/analyzer/protocol/modbus/Plugin.cc new file mode 100644 index 0000000000..c84992cbae --- /dev/null +++ b/src/analyzer/protocol/modbus/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Modbus.h" + +BRO_PLUGIN_BEGIN(Bro, Modbus) + BRO_PLUGIN_DESCRIPTION("Modbus analyzer"); + BRO_PLUGIN_ANALYZER("MODBUS", modbus::ModbusTCP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/modbus/events.bif b/src/analyzer/protocol/modbus/events.bif new file mode 100644 index 0000000000..1cd17381ee --- /dev/null +++ b/src/analyzer/protocol/modbus/events.bif @@ -0,0 +1,295 @@ +## Generated for any modbus message regardless if the particular function +## is further supported or not. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## is_orig: True if the event is raised for the originator side. +event modbus_message%(c: connection, headers: ModbusHeaders, is_orig: bool%); + +## Generated for any modbus exception message. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## code: The exception code. +event modbus_exception%(c: connection, headers: ModbusHeaders, code: count%); + +## Generated for a Modbus read coils request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address where of the first coil to be read. +## +## quantity: The number of coils to be read. +event modbus_read_coils_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus read coils response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## coils: The coil values returned from the device. +event modbus_read_coils_response%(c: connection, headers: ModbusHeaders, coils: ModbusCoils%); + +## Generated for a Modbus read discrete inputs request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first coil to be read. +## +## quantity: The number of coils to be read. +event modbus_read_discrete_inputs_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus read discrete inputs response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## coils: The coil values returned from the device. +event modbus_read_discrete_inputs_response%(c: connection, headers: ModbusHeaders, coils: ModbusCoils%); + +## Generated for a Modbus read holding registers request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first register to be read. +## +## quantity: The number of registers to be read. +event modbus_read_holding_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus read holding registers response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## registers: The register values returned from the device. +event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%); + +## Generated for a Modbus read input registers request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first register to be read. +## +## quantity: The number of registers to be read. +event modbus_read_input_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus read input registers response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## registers: The register values returned from the device. +event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%); + +## Generated for a Modbus write single coil request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the coil to be written. +## +## value: The value to be written to the coil. +event modbus_write_single_coil_request%(c: connection, headers: ModbusHeaders, address: count, value: bool%); + +## Generated for a Modbus write single coil response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the coil that was written. +## +## value: The value that was written to the coil. +event modbus_write_single_coil_response%(c: connection, headers: ModbusHeaders, address: count, value: bool%); + +## Generated for a Modbus write single register request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the register to be written. +## +## value: The value to be written to the register. +event modbus_write_single_register_request%(c: connection, headers: ModbusHeaders, address: count, value: count%); + +## Generated for a Modbus write single register response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the register that was written. +## +## value: The value that was written to the register. +event modbus_write_single_register_response%(c: connection, headers: ModbusHeaders, address: count, value: count%); + +## Generated for a Modbus write multiple coils request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first coil to be written. +## +## value: The values to be written to the coils. +event modbus_write_multiple_coils_request%(c: connection, headers: ModbusHeaders, start_address: count, coils: ModbusCoils%); + +## Generated for a Modbus write multiple coils response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first coil that was written. +## +## quantity: The quantity of coils that were written. +event modbus_write_multiple_coils_response%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus write multiple registers request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first register to be written. +## +## registers: The values to be written to the registers. +event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters%); + +## Generated for a Modbus write multiple registers response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The memory address of the first register that was written. +## +## quantity: The quantity of registers that were written. +event modbus_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); + +## Generated for a Modbus read file record request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## .. note: This event is incomplete. The information from the data structure is not +## yet passed through to the event. +event modbus_read_file_record_request%(c: connection, headers: ModbusHeaders%); + +## Generated for a Modbus read file record response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## .. note: This event is incomplete. The information from the data structure is not +## yet passed through to the event. +event modbus_read_file_record_response%(c: connection, headers: ModbusHeaders%); + +## Generated for a Modbus write file record request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## .. note: This event is incomplete. The information from the data structure is not +## yet passed through to the event. +event modbus_write_file_record_request%(c: connection, headers: ModbusHeaders%); + +## Generated for a Modbus write file record response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## .. note: This event is incomplete. The information from the data structure is not +## yet passed through to the event. +event modbus_write_file_record_response%(c: connection, headers: ModbusHeaders%); + +## Generated for a Modbus mask write register request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the register where the masks should be applied. +## +## and_mask: The value of the logical AND mask to apply to the register. +## +## or_mask: The value of the logical OR mask to apply to the register. +event modbus_mask_write_register_request%(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count%); + +## Generated for a Modbus mask write register request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## address: The memory address of the register where the masks were applied. +## +## and_mask: The value of the logical AND mask applied register. +## +## or_mask: The value of the logical OR mask applied to the register. +event modbus_mask_write_register_response%(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count%); + +## Generated for a Modbus read/write multiple registers request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## read_start_address: The memory address of the first register to be read. +## +## read_quantity: The number of registers to read. +## +## write_start_address: The memory address of the first register to be written. +## +## write_registers: The values to be written to the registers. +event modbus_read_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_registers: ModbusRegisters%); + +## Generated for a Modbus read/write multiple registers response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## written_registers: The register values read from the registers specified in the request. +event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters%); + +## Generated for a Modbus read FIFO queue request. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## start_address: The address of the FIFO queue to read. +event modbus_read_fifo_queue_request%(c: connection, headers: ModbusHeaders, start_address: count%); + +## Generated for a Modbus read FIFO queue response. +## +## c: The connection. +## +## headers: The headers for the modbus function. +## +## fifos: The register values read from the FIFO queue on the device. +event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters%); + diff --git a/src/modbus-analyzer.pac b/src/analyzer/protocol/modbus/modbus-analyzer.pac similarity index 100% rename from src/modbus-analyzer.pac rename to src/analyzer/protocol/modbus/modbus-analyzer.pac diff --git a/src/modbus-protocol.pac b/src/analyzer/protocol/modbus/modbus-protocol.pac similarity index 100% rename from src/modbus-protocol.pac rename to src/analyzer/protocol/modbus/modbus-protocol.pac diff --git a/src/modbus.pac b/src/analyzer/protocol/modbus/modbus.pac similarity index 95% rename from src/modbus.pac rename to src/analyzer/protocol/modbus/modbus.pac index 9148997295..28b657abc5 100644 --- a/src/modbus.pac +++ b/src/analyzer/protocol/modbus/modbus.pac @@ -9,6 +9,10 @@ %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer ModbusTCP withcontext { connection: ModbusTCP_Conn; flow: ModbusTCP_Flow; diff --git a/src/analyzer/protocol/ncp/CMakeLists.txt b/src/analyzer/protocol/ncp/CMakeLists.txt new file mode 100644 index 0000000000..bd06d4e426 --- /dev/null +++ b/src/analyzer/protocol/ncp/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro NCP) +bro_plugin_cc(NCP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(ncp.pac) +bro_plugin_end() diff --git a/src/NCP.cc b/src/analyzer/protocol/ncp/NCP.cc similarity index 89% rename from src/NCP.cc rename to src/analyzer/protocol/ncp/NCP.cc index edd882747c..75b6c9f4be 100644 --- a/src/NCP.cc +++ b/src/analyzer/protocol/ncp/NCP.cc @@ -6,7 +6,12 @@ #include #include +#include "NCP.h" + +#include "events.bif.h" + using namespace std; +using namespace analyzer::ncp; #include "NCP.h" #include "Sessions.h" @@ -17,7 +22,7 @@ using namespace std; uint16(xbyte(bytes, 0)) | ((uint16(xbyte(bytes, 1))) << 8) : \ uint16(xbyte(bytes, 1)) | ((uint16(xbyte(bytes, 0))) << 8)) -NCP_Session::NCP_Session(Analyzer* a) +NCP_Session::NCP_Session(analyzer::Analyzer* a) : analyzer(a) { req_frame_type = 0; @@ -150,15 +155,15 @@ void NCP_FrameBuffer::compute_msg_length() } Contents_NCP_Analyzer::Contents_NCP_Analyzer(Connection* conn, bool orig, NCP_Session* arg_session) -: TCP_SupportAnalyzer(AnalyzerTag::Contents_NCP, conn, orig) +: tcp::TCP_SupportAnalyzer("CONTENTS_NCP", conn, orig) { session = arg_session; resync = true; - TCP_Analyzer* tcp = static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = static_cast(Parent())->TCP(); if ( tcp ) resync = (orig ? tcp->OrigState() : tcp->RespState()) != - TCP_ENDPOINT_ESTABLISHED; + tcp::TCP_ENDPOINT_ESTABLISHED; } Contents_NCP_Analyzer::~Contents_NCP_Analyzer() @@ -167,9 +172,9 @@ Contents_NCP_Analyzer::~Contents_NCP_Analyzer() void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); - TCP_Analyzer* tcp = static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = static_cast(Parent())->TCP(); if ( tcp && tcp->HadGap(orig) ) return; @@ -208,14 +213,14 @@ void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig void Contents_NCP_Analyzer::Undelivered(int seq, int len, bool orig) { - TCP_SupportAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); buffer.Reset(); resync = true; } NCP_Analyzer::NCP_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::NCP, conn) +: tcp::TCP_ApplicationAnalyzer("NCP", conn) { session = new NCP_Session(this); o_ncp = new Contents_NCP_Analyzer(conn, true, session); diff --git a/src/NCP.h b/src/analyzer/protocol/ncp/NCP.h similarity index 84% rename from src/NCP.h rename to src/analyzer/protocol/ncp/NCP.h index 1e783ee3ab..34174df74e 100644 --- a/src/NCP.h +++ b/src/analyzer/protocol/ncp/NCP.h @@ -1,7 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef ncp_h -#define ncp_h +#ifndef ANALYZER_PROTOCOL_NCP_NCP_H +#define ANALYZER_PROTOCOL_NCP_NCP_H // A very crude analyzer for NCP (Netware Core Protocol) // @@ -19,17 +19,19 @@ // http://faydoc.tripod.com/structures/21/2149.htm #include "NetVar.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "ncp_pac.h" +namespace analyzer { namespace ncp { + // Create a general NCP_Session class so that it can be used in // case the RPC conversation is tunneled through other connections, // e.g., through an SMB session. class NCP_Session { public: - NCP_Session(Analyzer* analyzer); + NCP_Session(analyzer::Analyzer* analyzer); virtual ~NCP_Session() {} virtual void Deliver(int is_orig, int len, const u_char* data); @@ -42,7 +44,7 @@ public: protected: void DeliverFrame(const binpac::NCP::ncp_frame* frame); - Analyzer* analyzer; + analyzer::Analyzer* analyzer; int req_frame_type; int req_func; }; @@ -81,7 +83,7 @@ protected: void compute_msg_length(); }; -class Contents_NCP_Analyzer : public TCP_SupportAnalyzer { +class Contents_NCP_Analyzer : public tcp::TCP_SupportAnalyzer { public: Contents_NCP_Analyzer(Connection* conn, bool orig, NCP_Session* session); ~Contents_NCP_Analyzer(); @@ -97,16 +99,14 @@ protected: bool resync; }; -class NCP_Analyzer : public TCP_ApplicationAnalyzer { +class NCP_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: NCP_Analyzer(Connection* conn); virtual ~NCP_Analyzer(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NCP_Analyzer(conn); } - static bool Available() { return NCP_Session::any_ncp_event(); } - protected: NCP_Session* session; @@ -114,4 +114,6 @@ protected: Contents_NCP_Analyzer * r_ncp; }; +} } // namespace analyzer::* + #endif /* ncp_h */ diff --git a/src/NCP_func.def b/src/analyzer/protocol/ncp/NCP_func.def similarity index 100% rename from src/NCP_func.def rename to src/analyzer/protocol/ncp/NCP_func.def diff --git a/src/analyzer/protocol/ncp/Plugin.cc b/src/analyzer/protocol/ncp/Plugin.cc new file mode 100644 index 0000000000..85cd318fe0 --- /dev/null +++ b/src/analyzer/protocol/ncp/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "NCP.h" + +BRO_PLUGIN_BEGIN(Bro, NCP) + BRO_PLUGIN_DESCRIPTION("NCP analyzer"); + BRO_PLUGIN_ANALYZER("NCP", ncp::NCP_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_NCP"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/ncp/events.bif b/src/analyzer/protocol/ncp/events.bif new file mode 100644 index 0000000000..9b5b7d77a7 --- /dev/null +++ b/src/analyzer/protocol/ncp/events.bif @@ -0,0 +1,46 @@ +## Generated for NCP requests (Netware Core Protocol). +## +## See `Wikipedia `__ for +## more information about the NCP protocol. +## +## c: The connection. +## +## frame_type: The frame type, as specified by the protocol. +## +## length: The length of the request body, excluding the frame header. +## +## func: The requested function, as specified by the protocol. +## +## .. bro:see:: ncp_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ncp_request%(c: connection, frame_type: count, length: count, func: count%); + +## Generated for NCP replies (Netware Core Protocol). +## +## See `Wikipedia `__ for +## more information about the NCP protocol. +## +## c: The connection. +## +## frame_type: The frame type, as specified by the protocol. +## +## length: The length of the request body, excluding the frame header. +## +## req_frame: The frame type from the corresponding request. +## +## req_func: The function code from the corresponding request. +## +## completion_code: The reply's completion code, as specified by the protocol. +## +## .. bro:see:: ncp_request +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ncp_reply%(c: connection, frame_type: count, length: count, req_frame: count, req_func: count, completion_code: count%); + diff --git a/src/ncp.pac b/src/analyzer/protocol/ncp/ncp.pac similarity index 97% rename from src/ncp.pac rename to src/analyzer/protocol/ncp/ncp.pac index 86b8bca5da..d4d5734a54 100644 --- a/src/ncp.pac +++ b/src/analyzer/protocol/ncp/ncp.pac @@ -2,6 +2,10 @@ %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer NCP withcontext {}; type ncp_request(length: uint32) = record { diff --git a/src/analyzer/protocol/netbios/CMakeLists.txt b/src/analyzer/protocol/netbios/CMakeLists.txt new file mode 100644 index 0000000000..ad6009d171 --- /dev/null +++ b/src/analyzer/protocol/netbios/CMakeLists.txt @@ -0,0 +1,13 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/../dce-rpc) +include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/../smb) + +bro_plugin_begin(Bro NetBIOS) +bro_plugin_cc(NetbiosSSN.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() + diff --git a/src/NetbiosSSN.cc b/src/analyzer/protocol/netbios/NetbiosSSN.cc similarity index 93% rename from src/NetbiosSSN.cc rename to src/analyzer/protocol/netbios/NetbiosSSN.cc index 362d974956..01544c4b2c 100644 --- a/src/NetbiosSSN.cc +++ b/src/analyzer/protocol/netbios/NetbiosSSN.cc @@ -9,6 +9,10 @@ #include "Sessions.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::netbios_ssn; + double netbios_ssn_session_timeout = 15.0; #define MAKE_INT16(dest, src) dest = *src; dest <<=8; src++; dest |= *src; src++; @@ -43,8 +47,8 @@ NetbiosDGM_RawMsgHdr::NetbiosDGM_RawMsgHdr(const u_char*& data, int& len) } -NetbiosSSN_Interpreter::NetbiosSSN_Interpreter(Analyzer* arg_analyzer, - SMB_Session* arg_smb_session) +NetbiosSSN_Interpreter::NetbiosSSN_Interpreter(analyzer::Analyzer* arg_analyzer, + smb::SMB_Session* arg_smb_session) { analyzer = arg_analyzer; smb_session = arg_smb_session; @@ -340,7 +344,7 @@ void NetbiosSSN_Interpreter::Event(EventHandlerPtr event, const u_char* data, Contents_NetbiosSSN::Contents_NetbiosSSN(Connection* conn, bool orig, NetbiosSSN_Interpreter* arg_interp) -: TCP_SupportAnalyzer(AnalyzerTag::Contents_NetbiosSSN, conn, orig) +: tcp::TCP_SupportAnalyzer("CONTENTS_NETBIOSSSN", conn, orig) { interp = arg_interp; type = flags = msg_size = 0; @@ -365,7 +369,7 @@ void Contents_NetbiosSSN::Flush() void Contents_NetbiosSSN::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); if ( state == NETBIOS_SSN_TYPE ) { @@ -455,9 +459,9 @@ void Contents_NetbiosSSN::DeliverStream(int len, const u_char* data, bool orig) } NetbiosSSN_Analyzer::NetbiosSSN_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::NetbiosSSN, conn) +: tcp::TCP_ApplicationAnalyzer("NETBIOS", conn) { - smb_session = new SMB_Session(this); + smb_session = new smb::SMB_Session(this); interp = new NetbiosSSN_Interpreter(this, smb_session); orig_netbios = resp_netbios = 0; did_session_done = 0; @@ -485,7 +489,7 @@ NetbiosSSN_Analyzer::~NetbiosSSN_Analyzer() void NetbiosSSN_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); interp->Timeout(); if ( Conn()->ConnTransport() == TRANSPORT_UDP && ! did_session_done ) @@ -496,15 +500,15 @@ void NetbiosSSN_Analyzer::Done() void NetbiosSSN_Analyzer::EndpointEOF(bool orig) { - TCP_ApplicationAnalyzer::EndpointEOF(orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(orig); (orig ? orig_netbios : resp_netbios)->Flush(); } -void NetbiosSSN_Analyzer::ConnectionClosed(TCP_Endpoint* endpoint, - TCP_Endpoint* peer, int gen_event) +void NetbiosSSN_Analyzer::ConnectionClosed(tcp::TCP_Endpoint* endpoint, + tcp::TCP_Endpoint* peer, int gen_event) { - TCP_ApplicationAnalyzer::ConnectionClosed(endpoint, peer, gen_event); + tcp::TCP_ApplicationAnalyzer::ConnectionClosed(endpoint, peer, gen_event); // Question: Why do we flush *both* endpoints upon connection close? // orig_netbios->Flush(); @@ -514,7 +518,7 @@ void NetbiosSSN_Analyzer::ConnectionClosed(TCP_Endpoint* endpoint, void NetbiosSSN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { - TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); if ( orig ) interp->ParseMessageUDP(data, len, 1); diff --git a/src/NetbiosSSN.h b/src/analyzer/protocol/netbios/NetbiosSSN.h similarity index 83% rename from src/NetbiosSSN.h rename to src/analyzer/protocol/netbios/NetbiosSSN.h index 7c4dd91b90..7c2728ef9a 100644 --- a/src/NetbiosSSN.h +++ b/src/analyzer/protocol/netbios/NetbiosSSN.h @@ -1,11 +1,13 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef netbios_ssn_h -#define netbios_ssn_h +#ifndef ANALYZER_PROTOCOL_NETBIOS_SSN_NETBIOSSSN_H +#define ANALYZER_PROTOCOL_NETBIOS_SSN_NETBIOSSSN_H -#include "UDP.h" -#include "TCP.h" -#include "SMB.h" +#include "analyzer/protocol/udp/UDP.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/smb/SMB.h" + +namespace analyzer { namespace netbios_ssn { typedef enum { NETBIOS_SSN_MSG = 0x0, @@ -62,7 +64,7 @@ struct NetbiosDGM_RawMsgHdr { class NetbiosSSN_Interpreter { public: - NetbiosSSN_Interpreter(Analyzer* analyzer, SMB_Session* smb_session); + NetbiosSSN_Interpreter(analyzer::Analyzer* analyzer, smb::SMB_Session* smb_session); int ParseMessage(unsigned int type, unsigned int flags, const u_char* data, int len, int is_query); @@ -73,17 +75,6 @@ public: void Timeout() { } - static bool any_netbios_ssn_event() - { - return netbios_session_message || - netbios_session_request || - netbios_session_accepted || - netbios_session_rejected || - netbios_session_raw_message || - netbios_session_ret_arg_resp || - netbios_session_keepalive; - } - protected: int ParseSessionMsg(const u_char* data, int len, int is_query); int ParseSessionReq(const u_char* data, int len, int is_query); @@ -108,8 +99,8 @@ protected: u_char*& xname, int& xlen); protected: - Analyzer* analyzer; - SMB_Session* smb_session; + analyzer::Analyzer* analyzer; + smb::SMB_Session* smb_session; }; @@ -122,7 +113,7 @@ typedef enum { } NetbiosSSN_State; // ### This should be merged with TCP_Contents_RPC, TCP_Contents_DNS. -class Contents_NetbiosSSN : public TCP_SupportAnalyzer { +class Contents_NetbiosSSN : public tcp::TCP_SupportAnalyzer { public: Contents_NetbiosSSN(Connection* conn, bool orig, NetbiosSSN_Interpreter* interp); @@ -148,7 +139,7 @@ protected: NetbiosSSN_State state; }; -class NetbiosSSN_Analyzer : public TCP_ApplicationAnalyzer { +class NetbiosSSN_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: NetbiosSSN_Analyzer(Connection* conn); ~NetbiosSSN_Analyzer(); @@ -157,25 +148,18 @@ public: virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NetbiosSSN_Analyzer(conn); } - static bool Available() - { - return NetbiosSSN_Interpreter::any_netbios_ssn_event() || - SMB_Session::any_smb_event() || - DCE_RPC_Session::any_dce_rpc_event(); - } - protected: - virtual void ConnectionClosed(TCP_Endpoint* endpoint, - TCP_Endpoint* peer, int gen_event); + virtual void ConnectionClosed(tcp::TCP_Endpoint* endpoint, + tcp::TCP_Endpoint* peer, int gen_event); virtual void EndpointEOF(bool is_orig); void ExpireTimer(double t); NetbiosSSN_Interpreter* interp; - SMB_Session* smb_session; + smb::SMB_Session* smb_session; Contents_NetbiosSSN* orig_netbios; Contents_NetbiosSSN* resp_netbios; int did_session_done; @@ -184,4 +168,6 @@ protected: // FIXME: Doesn't really fit into new analyzer structure. What to do? int IsReuse(double t, const u_char* pkt); +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/netbios/Plugin.cc b/src/analyzer/protocol/netbios/Plugin.cc new file mode 100644 index 0000000000..15daeb1ab5 --- /dev/null +++ b/src/analyzer/protocol/netbios/Plugin.cc @@ -0,0 +1,12 @@ + +#include "plugin/Plugin.h" + +#include "NetbiosSSN.h" + +BRO_PLUGIN_BEGIN(Bro, NetBIOS) + BRO_PLUGIN_DESCRIPTION("NetBIOS analyzer (support only SSN currently)"); + BRO_PLUGIN_ANALYZER("NetbiosSSN", netbios_ssn::NetbiosSSN_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_NetbiosSSN"); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/netbios/events.bif b/src/analyzer/protocol/netbios/events.bif new file mode 100644 index 0000000000..bf382e1663 --- /dev/null +++ b/src/analyzer/protocol/netbios/events.bif @@ -0,0 +1,209 @@ +## Generated for all NetBIOS SSN and DGM messages. Bro's NetBIOS analyzer +## processes the NetBIOS session service running on TCP port 139, and (despite +## its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## msg_type: The general type of message, as defined in Section 4.3.1 of +## `RFC 1002 `__. +## +## data_len: The length of the message's payload. +## +## .. bro:see:: netbios_session_accepted netbios_session_keepalive +## netbios_session_raw_message netbios_session_rejected netbios_session_request +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_message%(c: connection, is_orig: bool, msg_type: count, data_len: count%); + +## Generated for NetBIOS messages of type *session request*. Bro's NetBIOS +## analyzer processes the NetBIOS session service running on TCP port 139, and +## (despite its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header. +## +## .. bro:see:: netbios_session_accepted netbios_session_keepalive +## netbios_session_message netbios_session_raw_message netbios_session_rejected +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_request%(c: connection, msg: string%); + +## Generated for NetBIOS messages of type *positive session response*. Bro's +## NetBIOS analyzer processes the NetBIOS session service running on TCP port +## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header. +## +## .. bro:see:: netbios_session_keepalive netbios_session_message +## netbios_session_raw_message netbios_session_rejected netbios_session_request +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_accepted%(c: connection, msg: string%); + +## Generated for NetBIOS messages of type *negative session response*. Bro's +## NetBIOS analyzer processes the NetBIOS session service running on TCP port +## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header. +## +## .. bro:see:: netbios_session_accepted netbios_session_keepalive +## netbios_session_message netbios_session_raw_message netbios_session_request +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_rejected%(c: connection, msg: string%); + +## Generated for NetBIOS messages of type *session message* that are not +## carrying an SMB payload. +## +## NetBIOS analyzer processes the NetBIOS session service running on TCP port +## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header (i.e., the ``user_data``). +## +## .. bro:see:: netbios_session_accepted netbios_session_keepalive +## netbios_session_message netbios_session_rejected netbios_session_request +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: This is an oddly named event. In fact, it's probably an odd event +## to have to begin with. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_raw_message%(c: connection, is_orig: bool, msg: string%); + +## Generated for NetBIOS messages of type *retarget response*. Bro's NetBIOS +## analyzer processes the NetBIOS session service running on TCP port 139, and +## (despite its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header. +## +## .. bro:see:: netbios_session_accepted netbios_session_keepalive +## netbios_session_message netbios_session_raw_message netbios_session_rejected +## netbios_session_request decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: This is an oddly named event. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_ret_arg_resp%(c: connection, msg: string%); + +## Generated for NetBIOS messages of type *keep-alive*. Bro's NetBIOS analyzer +## processes the NetBIOS session service running on TCP port 139, and (despite +## its name!) the NetBIOS datagram service on UDP port 138. +## +## See `Wikipedia `__ for more information +## about NetBIOS. `RFC 1002 `__ describes +## the packet format for NetBIOS over TCP/IP, which Bro parses. +## +## c: The connection, which may be TCP or UDP, depending on the type of the +## NetBIOS session. +## +## msg: The raw payload of the message sent, excluding the common NetBIOS +## header. +## +## .. bro:see:: netbios_session_accepted netbios_session_message +## netbios_session_raw_message netbios_session_rejected netbios_session_request +## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type +## +## .. note:: These days, NetBIOS is primarily used as a transport mechanism for +## `SMB/CIFS `__. Bro's +## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event netbios_session_keepalive%(c: connection, msg: string%); + diff --git a/src/analyzer/protocol/netbios/functions.bif b/src/analyzer/protocol/netbios/functions.bif new file mode 100644 index 0000000000..d4316d0c66 --- /dev/null +++ b/src/analyzer/protocol/netbios/functions.bif @@ -0,0 +1,50 @@ + +## Decode a NetBIOS name. See http://support.microsoft.com/kb/194203. +## +## name: The encoded NetBIOS name, e.g., ``"FEEIEFCAEOEFFEECEJEPFDCAEOEBENEF"``. +## +## Returns: The decoded NetBIOS name, e.g., ``"THE NETBIOS NAME"``. +## +## .. bro:see:: decode_netbios_name_type +function decode_netbios_name%(name: string%): string + %{ + char buf[16]; + char result[16]; + const u_char* s = name->Bytes(); + int i, j; + + for ( i = 0, j = 0; i < 16; ++i ) + { + char c0 = (j < name->Len()) ? toupper(s[j++]) : 'A'; + char c1 = (j < name->Len()) ? toupper(s[j++]) : 'A'; + buf[i] = ((c0 - 'A') << 4) + (c1 - 'A'); + } + + for ( i = 0; i < 15; ++i ) + { + if ( isalnum(buf[i]) || ispunct(buf[i]) || + // \x01\x02 is seen in at least one case as the first two bytes. + // I think that any \x01 and \x02 should always be passed through. + buf[i] < 3 ) + result[i] = buf[i]; + else + break; + } + + return new StringVal(i, result); + %} + +## Converts a NetBIOS name type to its corresponding numeric value. +## See http://support.microsoft.com/kb/163409. +## +## name: The NetBIOS name type. +## +## Returns: The numeric value of *name*. +## +## .. bro:see:: decode_netbios_name +function decode_netbios_name_type%(name: string%): count + %{ + const u_char* s = name->Bytes(); + char return_val = ((toupper(s[30]) - 'A') << 4) + (toupper(s[31]) - 'A'); + return new Val(return_val, TYPE_COUNT); + %} diff --git a/src/analyzer/protocol/netflow/CMakeLists.txt b/src/analyzer/protocol/netflow/CMakeLists.txt new file mode 100644 index 0000000000..3afc9fd66a --- /dev/null +++ b/src/analyzer/protocol/netflow/CMakeLists.txt @@ -0,0 +1,16 @@ + +# This is not an actual analyzer, but used by the core. We still +# maintain it here along with the other analyzers because conceptually +# it's also parsing a protocol just like them. The current structure +# is merely a left-over from when this code was written. + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro NetFlow) +bro_plugin_cc(Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(netflow.pac netflow-protocol.pac netflow-analyzer.pac) +bro_plugin_end() + diff --git a/src/analyzer/protocol/netflow/Plugin.cc b/src/analyzer/protocol/netflow/Plugin.cc new file mode 100644 index 0000000000..b994caa5d8 --- /dev/null +++ b/src/analyzer/protocol/netflow/Plugin.cc @@ -0,0 +1,7 @@ + +#include "plugin/Plugin.h" + +BRO_PLUGIN_BEGIN(Bro, NetFlow) + BRO_PLUGIN_DESCRIPTION("NetFlow parsing code"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/netflow/events.bif b/src/analyzer/protocol/netflow/events.bif new file mode 100644 index 0000000000..69c196de9e --- /dev/null +++ b/src/analyzer/protocol/netflow/events.bif @@ -0,0 +1,18 @@ +## Generated for a received NetFlow v5 header. Bro's NetFlow processor raises +## this event whenever it either receives a NetFlow header on the port it's +## listening on, or reads one from a trace file. +## +## h: The parsed NetFlow header. +## +## .. bro:see:: netflow_v5_record +event netflow_v5_header%(h: nf_v5_header%); + +## Generated for a received NetFlow v5 record. Bro's NetFlow processor raises +## this event whenever it either receives a NetFlow record on the port it's +## listening on, or reads one from a trace file. +## +## r: The parsed NetFlow record. +## +## .. bro:see:: netflow_v5_record +event netflow_v5_record%(r: nf_v5_record%); + diff --git a/src/netflow-analyzer.pac b/src/analyzer/protocol/netflow/netflow-analyzer.pac similarity index 100% rename from src/netflow-analyzer.pac rename to src/analyzer/protocol/netflow/netflow-analyzer.pac diff --git a/src/netflow-protocol.pac b/src/analyzer/protocol/netflow/netflow-protocol.pac similarity index 100% rename from src/netflow-protocol.pac rename to src/analyzer/protocol/netflow/netflow-protocol.pac diff --git a/src/netflow.pac b/src/analyzer/protocol/netflow/netflow.pac similarity index 88% rename from src/netflow.pac rename to src/analyzer/protocol/netflow/netflow.pac index 91040aadeb..57e1b71a76 100644 --- a/src/netflow.pac +++ b/src/analyzer/protocol/netflow/netflow.pac @@ -4,6 +4,8 @@ #include "net_util.h" #include "Event.h" extern RecordType* conn_id; + +#include "events.bif.h" %} %include bro.pac diff --git a/src/analyzer/protocol/ntp/CMakeLists.txt b/src/analyzer/protocol/ntp/CMakeLists.txt new file mode 100644 index 0000000000..a8b8bb1872 --- /dev/null +++ b/src/analyzer/protocol/ntp/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro NTP) +bro_plugin_cc(NTP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/NTP.cc b/src/analyzer/protocol/ntp/NTP.cc similarity index 97% rename from src/NTP.cc rename to src/analyzer/protocol/ntp/NTP.cc index 60b7e6202d..b4b63d5634 100644 --- a/src/NTP.cc +++ b/src/analyzer/protocol/ntp/NTP.cc @@ -7,9 +7,12 @@ #include "Sessions.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::ntp; NTP_Analyzer::NTP_Analyzer(Connection* conn) - : Analyzer(AnalyzerTag::NTP, conn) + : Analyzer("NTP", conn) { ADD_ANALYZER_TIMER(&NTP_Analyzer::ExpireTimer, network_time + ntp_session_timeout, 1, diff --git a/src/NTP.h b/src/analyzer/protocol/ntp/NTP.h similarity index 83% rename from src/NTP.h rename to src/analyzer/protocol/ntp/NTP.h index a22a7b231b..201c5a8774 100644 --- a/src/NTP.h +++ b/src/analyzer/protocol/ntp/NTP.h @@ -1,16 +1,17 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef ntp_h -#define ntp_h - -#include "UDP.h" +#ifndef ANALYZER_PROTOCOL_NTP_NTP_H +#define ANALYZER_PROTOCOL_NTP_NTP_H +#include "analyzer/protocol/udp/UDP.h" // The following are from the tcpdump distribution, credited there // to the U of MD implementation. #define JAN_1970 2208988800.0 /* 1970 - 1900 in seconds */ +namespace analyzer { namespace ntp { + struct l_fixedpt { unsigned int int_part; unsigned int fraction; @@ -35,15 +36,13 @@ struct ntpdata { struct l_fixedpt xmt; }; -class NTP_Analyzer : public Analyzer { +class NTP_Analyzer : public analyzer::Analyzer { public: NTP_Analyzer(Connection* conn); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NTP_Analyzer(conn); } - static bool Available() { return ntp_message; } - protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, @@ -65,4 +64,6 @@ protected: void ExpireTimer(double t); }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/ntp/Plugin.cc b/src/analyzer/protocol/ntp/Plugin.cc new file mode 100644 index 0000000000..ce4ce5680f --- /dev/null +++ b/src/analyzer/protocol/ntp/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "NTP.h" + +BRO_PLUGIN_BEGIN(Bro, NTP) + BRO_PLUGIN_DESCRIPTION("NTP analyzer"); + BRO_PLUGIN_ANALYZER("NTP", ntp::NTP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/ntp/events.bif b/src/analyzer/protocol/ntp/events.bif new file mode 100644 index 0000000000..bba2dfbbe5 --- /dev/null +++ b/src/analyzer/protocol/ntp/events.bif @@ -0,0 +1,21 @@ +## Generated for all NTP messages. Different from many other of Bro's events, +## this one is generated for both client-side and server-side messages. +## +## See `Wikipedia `__ for +## more information about the NTP protocol. +## +## u: The connection record describing the corresponding UDP flow. +## +## msg: The parsed NTP message. +## +## excess: The raw bytes of any optional parts of the NTP packet. Bro does not +## further parse any optional fields. +## +## .. bro:see:: ntp_session_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event ntp_message%(u: connection, msg: ntp_msg, excess: string%); + diff --git a/src/analyzer/protocol/pia/CMakeLists.txt b/src/analyzer/protocol/pia/CMakeLists.txt new file mode 100644 index 0000000000..ff55bcf0aa --- /dev/null +++ b/src/analyzer/protocol/pia/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro PIA) +bro_plugin_cc(PIA.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/PIA.cc b/src/analyzer/protocol/pia/PIA.cc similarity index 80% rename from src/PIA.cc rename to src/analyzer/protocol/pia/PIA.cc index 9adb4ccab3..cc1dd7ea0e 100644 --- a/src/PIA.cc +++ b/src/analyzer/protocol/pia/PIA.cc @@ -1,8 +1,12 @@ #include "PIA.h" #include "RuleMatcher.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" -PIA::PIA(Analyzer* arg_as_analyzer) +#include "events.bif.h" + +using namespace analyzer::pia; + +PIA::PIA(analyzer::Analyzer* arg_as_analyzer) { current_packet.data = 0; as_analyzer = arg_as_analyzer; @@ -61,9 +65,9 @@ void PIA::AddToBuffer(Buffer* buffer, int len, const u_char* data, bool is_orig) AddToBuffer(buffer, -1, len, data, is_orig); } -void PIA::ReplayPacketBuffer(Analyzer* analyzer) +void PIA::ReplayPacketBuffer(analyzer::Analyzer* analyzer) { - DBG_LOG(DBG_DPD, "PIA replaying %d total packet bytes", pkt_buffer.size); + DBG_LOG(DBG_ANALYZER, "PIA replaying %d total packet bytes", pkt_buffer.size); for ( DataBlock* b = pkt_buffer.head; b; b = b->next ) analyzer->DeliverPacket(b->len, b->data, b->is_orig, -1, 0, 0); @@ -129,11 +133,11 @@ void PIA::DoMatch(const u_char* data, int len, bool is_orig, bool bol, bool eol, bol, eol, clear_state); } -void PIA_UDP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) +void PIA_UDP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule) { if ( pkt_buffer.state == MATCHING_ONLY ) { - DBG_LOG(DBG_DPD, "analyzer found but buffer already exceeded"); + DBG_LOG(DBG_ANALYZER, "analyzer found but buffer already exceeded"); // FIXME: This is where to check whether an analyzer // supports partial connections once we get such. return; @@ -142,14 +146,14 @@ void PIA_UDP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) if ( Parent()->HasChildAnalyzer(tag) ) return; - Analyzer* a = Parent()->AddChildAnalyzer(tag); + analyzer::Analyzer* a = Parent()->AddChildAnalyzer(tag); a->SetSignature(rule); if ( a ) ReplayPacketBuffer(a); } -void PIA_UDP::DeactivateAnalyzer(AnalyzerTag::Tag tag) +void PIA_UDP::DeactivateAnalyzer(analyzer::Tag tag) { reporter->InternalError("PIA_UDP::Deact not implemented yet"); } @@ -163,11 +167,11 @@ PIA_TCP::~PIA_TCP() void PIA_TCP::Init() { - TCP_ApplicationAnalyzer::Init(); + tcp::TCP_ApplicationAnalyzer::Init(); - if ( Parent()->GetTag() == AnalyzerTag::TCP ) + if ( Parent()->IsAnalyzer("TCP") ) { - TCP_Analyzer* tcp = static_cast(Parent()); + tcp::TCP_Analyzer* tcp = static_cast(Parent()); SetTCP(tcp); tcp->SetPIA(this); } @@ -180,7 +184,7 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) static struct tcphdr* tcp4 = 0; static IP_Hdr* ip4_hdr = 0; - DBG_LOG(DBG_DPD, "PIA_TCP[%d] FirstPacket(%s)", GetID(), (is_orig ? "T" : "F")); + DBG_LOG(DBG_ANALYZER, "PIA_TCP[%d] FirstPacket(%s)", GetID(), (is_orig ? "T" : "F")); if ( ! ip ) { @@ -223,7 +227,7 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) void PIA_TCP::DeliverStream(int len, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); if ( stream_buffer.state == SKIPPING ) return; @@ -253,7 +257,7 @@ void PIA_TCP::DeliverStream(int len, const u_char* data, bool is_orig) void PIA_TCP::Undelivered(int seq, int len, bool is_orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); if ( stream_buffer.state == BUFFERING ) // We use data=nil to mark an undelivered. @@ -262,11 +266,11 @@ void PIA_TCP::Undelivered(int seq, int len, bool is_orig) // No check for buffer overrun here. I think that's ok. } -void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) +void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule) { if ( stream_buffer.state == MATCHING_ONLY ) { - DBG_LOG(DBG_DPD, "analyzer found but buffer already exceeded"); + DBG_LOG(DBG_ANALYZER, "analyzer found but buffer already exceeded"); // FIXME: This is where to check whether an analyzer supports // partial connections once we get such. return; @@ -275,7 +279,7 @@ void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) if ( Parent()->HasChildAnalyzer(tag) ) return; - Analyzer* a = Parent()->AddChildAnalyzer(tag); + analyzer::Analyzer* a = Parent()->AddChildAnalyzer(tag); a->SetSignature(rule); // We have two cases here: @@ -294,7 +298,7 @@ void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) // // Here's what we do: // - // (1) We create new TCP_Reassemblers and feed them the buffered + // (1) We create new tcp::TCP_Reassemblers and feed them the buffered // packets. // // (2) The reassembler will give us their results via the @@ -305,13 +309,13 @@ void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) // (4) We hand the two reassemblers to the TCP Analyzer (our parent), // turning reassembly now on for all subsequent data. - DBG_LOG(DBG_DPD, "DPM_TCP switching from packet-mode to stream-mode"); + DBG_LOG(DBG_ANALYZER, "PIA_TCP switching from packet-mode to stream-mode"); stream_mode = true; // FIXME: The reassembler will query the endpoint for state. Not sure // if this is works in all cases... - if ( Parent()->GetTag() != AnalyzerTag::TCP ) + if ( ! Parent()->IsAnalyzer("TCP") ) { // Our parent is not the TCP analyzer, which can only mean // we have been inserted somewhere further down in the @@ -322,14 +326,14 @@ void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) return; } - TCP_Analyzer* tcp = (TCP_Analyzer*) Parent(); + tcp::TCP_Analyzer* tcp = (tcp::TCP_Analyzer*) Parent(); - TCP_Reassembler* reass_orig = - new TCP_Reassembler(this, tcp, TCP_Reassembler::Direct, + tcp::TCP_Reassembler* reass_orig = + new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct, true, tcp->Orig()); - TCP_Reassembler* reass_resp = - new TCP_Reassembler(this, tcp, TCP_Reassembler::Direct, + tcp::TCP_Reassembler* reass_resp = + new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct, false, tcp->Resp()); int orig_seq = 0; @@ -365,20 +369,20 @@ void PIA_TCP::ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule) reass_orig->AckReceived(orig_seq); reass_resp->AckReceived(resp_seq); - reass_orig->SetType(TCP_Reassembler::Forward); - reass_resp->SetType(TCP_Reassembler::Forward); + reass_orig->SetType(tcp::TCP_Reassembler::Forward); + reass_resp->SetType(tcp::TCP_Reassembler::Forward); tcp->SetReassembler(reass_orig, reass_resp); } -void PIA_TCP::DeactivateAnalyzer(AnalyzerTag::Tag tag) +void PIA_TCP::DeactivateAnalyzer(analyzer::Tag tag) { reporter->InternalError("PIA_TCP::Deact not implemented yet"); } -void PIA_TCP::ReplayStreamBuffer(Analyzer* analyzer) +void PIA_TCP::ReplayStreamBuffer(analyzer::Analyzer* analyzer) { - DBG_LOG(DBG_DPD, "PIA_TCP replaying %d total stream bytes", stream_buffer.size); + DBG_LOG(DBG_ANALYZER, "PIA_TCP replaying %d total stream bytes", stream_buffer.size); for ( DataBlock* b = stream_buffer.head; b; b = b->next ) { diff --git a/src/PIA.h b/src/analyzer/protocol/pia/PIA.h similarity index 77% rename from src/PIA.h rename to src/analyzer/protocol/pia/PIA.h index 907350bbdf..d8c272d219 100644 --- a/src/PIA.h +++ b/src/analyzer/protocol/pia/PIA.h @@ -1,13 +1,15 @@ // An analyzer for application-layer protocol-detection. -#ifndef PIA_H -#define PIA_H +#ifndef ANALYZER_PROTOCOL_PIA_PIA_H +#define ANALYZER_PROTOCOL_PIA_PIA_H -#include "Analyzer.h" -#include "TCP.h" +#include "analyzer/Analyzer.h" +#include "analyzer/protocol/tcp/TCP.h" class RuleEndpointState; +namespace analyzer { namespace pia { + // Abstract PIA class providing common functionality for both TCP and UDP. // Accepts only packet input. // @@ -17,27 +19,25 @@ class RuleEndpointState; // PIAs and then each needs its own matching-state. class PIA : public RuleMatcherState { public: - PIA(Analyzer* as_analyzer); + PIA(analyzer::Analyzer* as_analyzer); virtual ~PIA(); // Called when PIA wants to put an Analyzer in charge. rule is the // signature that triggered the activitation, if any. - virtual void ActivateAnalyzer(AnalyzerTag::Tag tag, + virtual void ActivateAnalyzer(analyzer::Tag tag, const Rule* rule = 0) = 0; // Called when PIA wants to remove an Analyzer. - virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag) = 0; + virtual void DeactivateAnalyzer(analyzer::Tag tag) = 0; void Match(Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol, bool eol, bool clear_state); - void ReplayPacketBuffer(Analyzer* analyzer); + void ReplayPacketBuffer(analyzer::Analyzer* analyzer); // Children are also derived from Analyzer. Return this object // as pointer to an Analyzer. - Analyzer* AsAnalyzer() { return as_analyzer; } - - static bool Available() { return true; } + analyzer::Analyzer* AsAnalyzer() { return as_analyzer; } protected: void PIA_Done(); @@ -81,20 +81,20 @@ protected: Buffer pkt_buffer; private: - Analyzer* as_analyzer; + analyzer::Analyzer* as_analyzer; Connection* conn; DataBlock current_packet; }; // PIA for UDP. -class PIA_UDP : public PIA, public Analyzer { +class PIA_UDP : public PIA, public analyzer::Analyzer { public: PIA_UDP(Connection* conn) - : PIA(this), Analyzer(AnalyzerTag::PIA_UDP, conn) + : PIA(this), Analyzer("PIA_UDP", conn) { SetConn(conn); } virtual ~PIA_UDP() { } - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new PIA_UDP(conn); } protected: @@ -111,16 +111,16 @@ protected: PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); } - virtual void ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule); - virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag); + virtual void ActivateAnalyzer(analyzer::Tag tag, const Rule* rule); + virtual void DeactivateAnalyzer(analyzer::Tag tag); }; // PIA for TCP. Accepts both packet and stream input (and reassembles // packets before passing payload on to children). -class PIA_TCP : public PIA, public TCP_ApplicationAnalyzer { +class PIA_TCP : public PIA, public tcp::TCP_ApplicationAnalyzer { public: PIA_TCP(Connection* conn) - : PIA(this), TCP_ApplicationAnalyzer(AnalyzerTag::PIA_TCP, conn) + : PIA(this), tcp::TCP_ApplicationAnalyzer("PIA_TCP", conn) { stream_mode = false; SetConn(conn); } virtual ~PIA_TCP(); @@ -137,9 +137,9 @@ public: // to be unnecessary overhead.) void FirstPacket(bool is_orig, const IP_Hdr* ip); - void ReplayStreamBuffer(Analyzer* analyzer); + void ReplayStreamBuffer(analyzer::Analyzer* analyzer); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new PIA_TCP(conn); } protected: @@ -159,9 +159,9 @@ protected: virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void Undelivered(int seq, int len, bool is_orig); - virtual void ActivateAnalyzer(AnalyzerTag::Tag tag, + virtual void ActivateAnalyzer(analyzer::Tag tag, const Rule* rule = 0); - virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag); + virtual void DeactivateAnalyzer(analyzer::Tag tag); private: // FIXME: Not sure yet whether we need both pkt_buffer and stream_buffer. @@ -171,4 +171,6 @@ private: bool stream_mode; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/pia/Plugin.cc b/src/analyzer/protocol/pia/Plugin.cc new file mode 100644 index 0000000000..7d52801475 --- /dev/null +++ b/src/analyzer/protocol/pia/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "PIA.h" + +BRO_PLUGIN_BEGIN(Bro, PIA) + BRO_PLUGIN_DESCRIPTION("Analyzers implementing Dynamic Protocol Detection"); + BRO_PLUGIN_ANALYZER("PIA_TCP", pia::PIA_TCP); + BRO_PLUGIN_ANALYZER("PIA_UDP", pia::PIA_UDP); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/pia/events.bif b/src/analyzer/protocol/pia/events.bif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/analyzer/protocol/pop3/CMakeLists.txt b/src/analyzer/protocol/pop3/CMakeLists.txt new file mode 100644 index 0000000000..8071d6a74d --- /dev/null +++ b/src/analyzer/protocol/pop3/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro POP3) +bro_plugin_cc(POP3.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc similarity index 97% rename from src/POP3.cc rename to src/analyzer/protocol/pop3/POP3.cc index 3075e76507..652fd20e32 100644 --- a/src/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -12,8 +12,12 @@ #include "NetVar.h" #include "POP3.h" #include "Event.h" -#include "NVT.h" #include "Reporter.h" +#include "analyzer/protocol/login/NVT.h" + +#include "events.bif.h" + +using namespace analyzer::pop3; #undef POP3_CMD_DEF #define POP3_CMD_DEF(cmd) #cmd, @@ -26,7 +30,7 @@ static const char* pop3_cmd_word[] = { POP3_Analyzer::POP3_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::POP3, conn) +: tcp::TCP_ApplicationAnalyzer("POP3", conn) { masterState = POP3_START; subState = POP3_WOK; @@ -41,8 +45,8 @@ POP3_Analyzer::POP3_Analyzer(Connection* conn) mail = 0; - AddSupportAnalyzer(new ContentLine_Analyzer(conn, true)); - AddSupportAnalyzer(new ContentLine_Analyzer(conn, false)); + AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, true)); + AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, false)); } POP3_Analyzer::~POP3_Analyzer() @@ -51,7 +55,7 @@ POP3_Analyzer::~POP3_Analyzer() void POP3_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( mail ) EndData(); @@ -60,7 +64,7 @@ void POP3_Analyzer::Done() void POP3_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); if ( (TCP() && TCP()->IsPartial()) || backOff ) return; @@ -802,7 +806,7 @@ void POP3_Analyzer::AuthSuccessfull() void POP3_Analyzer::BeginData() { delete mail; - mail = new MIME_Mail(this); + mail = new mime::MIME_Mail(this); } void POP3_Analyzer::EndData() diff --git a/src/POP3.h b/src/analyzer/protocol/pop3/POP3.h similarity index 80% rename from src/POP3.h rename to src/analyzer/protocol/pop3/POP3.h index 8d09d5e686..ab535420e5 100644 --- a/src/POP3.h +++ b/src/analyzer/protocol/pop3/POP3.h @@ -2,21 +2,22 @@ // // An analyser for the POP3 protocol. -#ifndef pop3_h -#define pop3_h +#ifndef ANALYZER_PROTOCOL_POP3_POP3_H +#define ANALYZER_PROTOCOL_POP3_POP3_H #include #include #include -#include "NVT.h" -#include "TCP.h" -#include "MIME.h" - +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/login/NVT.h" +#include "analyzer/protocol/mime/MIME.h" #undef POP3_CMD_DEF #define POP3_CMD_DEF(cmd) POP3_CMD_##cmd, +namespace analyzer { namespace pop3 { + typedef enum { #include "POP3_cmd.def" } POP3_Cmd; @@ -60,7 +61,7 @@ typedef enum { POP3_WOK, } POP3_SubState; -class POP3_Analyzer : public TCP_ApplicationAnalyzer { +class POP3_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: POP3_Analyzer(Connection* conn); ~POP3_Analyzer(); @@ -68,16 +69,11 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new POP3_Analyzer(conn); } - static bool Available() - { - return pop3_request || pop3_reply || pop3_data || pop3_unexpected; - } - protected: int masterState; int subState; @@ -108,11 +104,13 @@ protected: void POP3Event(EventHandlerPtr event, bool is_orig, const char* arg1 = 0, const char* arg2 = 0); - MIME_Mail* mail; + mime::MIME_Mail* mail; list cmds; private: bool backOff; }; +} } // namespace analyzer::* + #endif diff --git a/src/POP3_cmd.def b/src/analyzer/protocol/pop3/POP3_cmd.def similarity index 100% rename from src/POP3_cmd.def rename to src/analyzer/protocol/pop3/POP3_cmd.def diff --git a/src/analyzer/protocol/pop3/Plugin.cc b/src/analyzer/protocol/pop3/Plugin.cc new file mode 100644 index 0000000000..edd99e2617 --- /dev/null +++ b/src/analyzer/protocol/pop3/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "POP3.h" + +BRO_PLUGIN_BEGIN(Bro, POP3) + BRO_PLUGIN_DESCRIPTION("POP3 analyzer"); + BRO_PLUGIN_ANALYZER("POP3", pop3::POP3_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/pop3/events.bif b/src/analyzer/protocol/pop3/events.bif new file mode 100644 index 0000000000..7692c61f6b --- /dev/null +++ b/src/analyzer/protocol/pop3/events.bif @@ -0,0 +1,172 @@ +## Generated for client-side commands on POP3 connections. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## command: The command sent. +## +## arg: The argument to the command. +## +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply +## pop3_terminate pop3_unexpected +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_request%(c: connection, is_orig: bool, + command: string, arg: string%); + +## Generated for server-side replies to commands on POP3 connections. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: True if the command was sent by the originator of the TCP +## connection. +## +## cmd: The success indicator sent by the server. This corresponds to the +## first token on the line sent, and should be either ``OK`` or ``ERR``. +## +## msg: The textual description the server sent along with *cmd*. +## +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_request +## pop3_terminate pop3_unexpected +## +## .. todo:: This event is receiving odd parameters, should unify. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_reply%(c: connection, is_orig: bool, cmd: string, msg: string%); + +## Generated for server-side multi-line responses on POP3 connections. POP3 +## connections use multi-line responses to send bulk data, such as the actual +## mails. This event is generated once for each line that's part of such a +## response. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: True if the data was sent by the originator of the TCP connection. +## +## data: The data sent. +## +## .. bro:see:: pop3_login_failure pop3_login_success pop3_reply pop3_request +## pop3_terminate pop3_unexpected +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_data%(c: connection, is_orig: bool, data: string%); + +## Generated for errors encountered on POP3 sessions. If the POP3 analyzer +## finds state transitions that do not conform to the protocol specification, +## or other situations it can't handle, it raises this event. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: True if the data was sent by the originator of the TCP connection. +## +## msg: A textual description of the situation. +## +## detail: The input that triggered the event. +## +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request +## pop3_terminate +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_unexpected%(c: connection, is_orig: bool, + msg: string, detail: string%); + +## Generated when a POP3 connection goes encrypted. While POP3 is by default a +## clear-text protocol, extensions exist to switch to encryption. This event is +## generated if that happens and the analyzer then stops processing the +## connection. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: Always false. +## +## msg: A descriptive message why processing was stopped. +## +## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request +## pop3_unexpected +## +## .. note:: Currently, only the ``STARTLS`` command is recognized and +## triggers this. +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_terminate%(c: connection, is_orig: bool, msg: string%); + +## Generated for successful authentications on POP3 connections. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: Always false. +## +## user: The user name used for authentication. The event is only generated if +## a non-empty user name was used. +## +## password: The password used for authentication. +## +## .. bro:see:: pop3_data pop3_login_failure pop3_reply pop3_request pop3_terminate +## pop3_unexpected +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_login_success%(c: connection, is_orig: bool, + user: string, password: string%); + +## Generated for unsuccessful authentications on POP3 connections. +## +## See `Wikipedia `__ for more information +## about the POP3 protocol. +## +## c: The connection. +## +## is_orig: Always false. +## +## user: The user name attempted for authentication. The event is only +## generated if a non-empty user name was used. +## +## password: The password attempted for authentication. +## +## .. bro:see:: pop3_data pop3_login_success pop3_reply pop3_request pop3_terminate +## pop3_unexpected +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pop3_login_failure%(c: connection, is_orig: bool, + user: string, password: string%); + diff --git a/src/analyzer/protocol/rpc/CMakeLists.txt b/src/analyzer/protocol/rpc/CMakeLists.txt new file mode 100644 index 0000000000..5696a74cd6 --- /dev/null +++ b/src/analyzer/protocol/rpc/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro RPC) +bro_plugin_cc(RPC.cc NFS.cc Portmap.cc XDR.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/NFS.cc b/src/analyzer/protocol/rpc/NFS.cc similarity index 99% rename from src/NFS.cc rename to src/analyzer/protocol/rpc/NFS.cc index d64f7755a3..51d1b90691 100644 --- a/src/NFS.cc +++ b/src/analyzer/protocol/rpc/NFS.cc @@ -9,6 +9,10 @@ #include "NFS.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::rpc; + int NFS_Interp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n) { if ( c->Program() != 100003 ) @@ -641,7 +645,7 @@ Val* NFS_Interp::ExtractBool(const u_char*& buf, int& n) NFS_Analyzer::NFS_Analyzer(Connection* conn) - : RPC_Analyzer(AnalyzerTag::NFS, conn, new NFS_Interp(this)) + : RPC_Analyzer("RPC", conn, new NFS_Interp(this)) { orig_rpc = resp_rpc = 0; } diff --git a/src/NFS.h b/src/analyzer/protocol/rpc/NFS.h similarity index 86% rename from src/NFS.h rename to src/analyzer/protocol/rpc/NFS.h index 6a65143808..7656450d94 100644 --- a/src/NFS.h +++ b/src/analyzer/protocol/rpc/NFS.h @@ -1,15 +1,17 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef nfs_h -#define nfs_h +#ifndef ANALYZER_PROTOCOL_RPC_NFS_H +#define ANALYZER_PROTOCOL_RPC_NFS_H #include "RPC.h" #include "XDR.h" #include "Event.h" +namespace analyzer { namespace rpc { + class NFS_Interp : public RPC_Interpreter { public: - NFS_Interp(Analyzer* arg_analyzer) : RPC_Interpreter(arg_analyzer) { } + NFS_Interp(analyzer::Analyzer* arg_analyzer) : RPC_Interpreter(arg_analyzer) { } protected: int RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n); @@ -75,19 +77,11 @@ public: NFS_Analyzer(Connection* conn); virtual void Init(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NFS_Analyzer(conn); } - - static bool Available() - { - return ( nfs_proc_null || nfs_proc_not_implemented || nfs_proc_getattr || - nfs_proc_lookup || nfs_proc_read || nfs_proc_readlink || - nfs_proc_write || nfs_proc_create || nfs_proc_mkdir || - nfs_proc_remove || nfs_proc_rmdir || nfs_proc_readdir || - nfs_reply_status || - rpc_dialogue || rpc_call || rpc_reply ); - } }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/rpc/Plugin.cc b/src/analyzer/protocol/rpc/Plugin.cc new file mode 100644 index 0000000000..9760df0623 --- /dev/null +++ b/src/analyzer/protocol/rpc/Plugin.cc @@ -0,0 +1,15 @@ + +#include "plugin/Plugin.h" + +#include "RPC.h" +#include "NFS.h" +#include "Portmap.h" + +BRO_PLUGIN_BEGIN(Bro, RPC) + BRO_PLUGIN_DESCRIPTION("Analyzers for RPC-based protocols"); + BRO_PLUGIN_ANALYZER("NFS", rpc::NFS_Analyzer); + BRO_PLUGIN_ANALYZER("Portmapper", rpc::Portmapper_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_RPC"); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_NFS"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/Portmap.cc b/src/analyzer/protocol/rpc/Portmap.cc similarity index 98% rename from src/Portmap.cc rename to src/analyzer/protocol/rpc/Portmap.cc index dd1049a361..f57d9a915c 100644 --- a/src/Portmap.cc +++ b/src/analyzer/protocol/rpc/Portmap.cc @@ -7,6 +7,10 @@ #include "Portmap.h" #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::rpc; + #define PMAPPROC_NULL 0 #define PMAPPROC_SET 1 #define PMAPPROC_UNSET 2 @@ -300,7 +304,7 @@ void PortmapperInterp::Event(EventHandlerPtr f, Val* request, BifEnum::rpc_statu } Portmapper_Analyzer::Portmapper_Analyzer(Connection* conn) -: RPC_Analyzer(AnalyzerTag::Portmapper, conn, new PortmapperInterp(this)) +: RPC_Analyzer("PORTMAPPER", conn, new PortmapperInterp(this)) { orig_rpc = resp_rpc = 0; } diff --git a/src/Portmap.h b/src/analyzer/protocol/rpc/Portmap.h similarity index 74% rename from src/Portmap.h rename to src/analyzer/protocol/rpc/Portmap.h index 62e954bc80..52d0c21a04 100644 --- a/src/Portmap.h +++ b/src/analyzer/protocol/rpc/Portmap.h @@ -1,13 +1,15 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef portmap_h -#define portmap_h +#ifndef ANALYZER_PROTOCOL_RPC_PORTMAP_H +#define ANALYZER_PROTOCOL_RPC_PORTMAP_H #include "RPC.h" +namespace analyzer { namespace rpc { + class PortmapperInterp : public RPC_Interpreter { public: - PortmapperInterp(Analyzer* arg_analyzer) : RPC_Interpreter(arg_analyzer) { } + PortmapperInterp(analyzer::Analyzer* arg_analyzer) : RPC_Interpreter(arg_analyzer) { } protected: int RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n); @@ -29,11 +31,10 @@ public: virtual ~Portmapper_Analyzer(); virtual void Init(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Portmapper_Analyzer(conn); } - - static bool Available() - { return pm_request || rpc_call; } }; +} } // namespace analyzer::* + #endif diff --git a/src/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc similarity index 95% rename from src/RPC.cc rename to src/analyzer/protocol/rpc/RPC.cc index 81fd6709b1..ea037c227f 100644 --- a/src/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -11,6 +11,10 @@ #include "RPC.h" #include "Sessions.h" +#include "events.bif.h" + +using namespace analyzer::rpc; + namespace { // local namespace const bool DEBUG_rpc_resync = false; } @@ -66,7 +70,7 @@ void rpc_callinfo_delete_func(void* v) delete (RPC_CallInfo*) v; } -RPC_Interpreter::RPC_Interpreter(Analyzer* arg_analyzer) +RPC_Interpreter::RPC_Interpreter(analyzer::Analyzer* arg_analyzer) { analyzer = arg_analyzer; calls.SetDeleteFunc(rpc_callinfo_delete_func); @@ -373,7 +377,7 @@ bool RPC_Reasm_Buffer::ConsumeChunk(const u_char*& data, int& len) Contents_RPC::Contents_RPC(Connection* conn, bool orig, RPC_Interpreter* arg_interp) - : TCP_SupportAnalyzer(AnalyzerTag::Contents_RPC, conn, orig) + : tcp::TCP_SupportAnalyzer("CONTENTS_RPC", conn, orig) { interp = arg_interp; state = WAIT_FOR_MESSAGE; @@ -385,7 +389,7 @@ Contents_RPC::Contents_RPC(Connection* conn, bool orig, void Contents_RPC::Init() { - TCP_SupportAnalyzer::Init(); + tcp::TCP_SupportAnalyzer::Init(); } Contents_RPC::~Contents_RPC() @@ -394,7 +398,7 @@ Contents_RPC::~Contents_RPC() void Contents_RPC::Undelivered(int seq, int len, bool orig) { - TCP_SupportAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); NeedResync(); } @@ -413,12 +417,12 @@ bool Contents_RPC::CheckResync(int& len, const u_char*& data, bool orig) // is fully established we are in sync (since it's the first chunk // of data after the SYN if its not established we need to // resync. - TCP_Analyzer* tcp = - static_cast(Parent())->TCP(); + tcp::TCP_Analyzer* tcp = + static_cast(Parent())->TCP(); assert(tcp); if ( (IsOrig() ? tcp->OrigState() : tcp->RespState()) != - TCP_ENDPOINT_ESTABLISHED ) + tcp::TCP_ENDPOINT_ESTABLISHED ) { NeedResync(); } @@ -578,7 +582,7 @@ bool Contents_RPC::CheckResync(int& len, const u_char*& data, bool orig) void Contents_RPC::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); uint32 marker; bool last_frag; @@ -673,9 +677,9 @@ void Contents_RPC::DeliverStream(int len, const u_char* data, bool orig) } // end while } -RPC_Analyzer::RPC_Analyzer(AnalyzerTag::Tag tag, Connection* conn, +RPC_Analyzer::RPC_Analyzer(const char* name, Connection* conn, RPC_Interpreter* arg_interp) -: TCP_ApplicationAnalyzer(tag, conn) +: tcp::TCP_ApplicationAnalyzer(name, conn) { interp = arg_interp; @@ -692,7 +696,7 @@ RPC_Analyzer::~RPC_Analyzer() void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { - TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); len = min(len, caplen); if ( orig ) @@ -709,7 +713,7 @@ void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void RPC_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); interp->Timeout(); } diff --git a/src/RPC.h b/src/analyzer/protocol/rpc/RPC.h similarity index 93% rename from src/RPC.h rename to src/analyzer/protocol/rpc/RPC.h index 0eee423460..a705d272f6 100644 --- a/src/RPC.h +++ b/src/analyzer/protocol/rpc/RPC.h @@ -1,10 +1,12 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef rpc_h -#define rpc_h +#ifndef ANALYZER_PROTOCOL_RPC_RPC_H +#define ANALYZER_PROTOCOL_RPC_RPC_H -#include "TCP.h" -#include "UDP.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/udp/UDP.h" + +namespace analyzer { namespace rpc { enum { RPC_CALL = 0, @@ -92,7 +94,7 @@ declare(PDict,RPC_CallInfo); class RPC_Interpreter { public: - RPC_Interpreter(Analyzer* analyzer); + RPC_Interpreter(analyzer::Analyzer* analyzer); virtual ~RPC_Interpreter(); // Delivers the given RPC. Returns true if "len" bytes were @@ -115,7 +117,7 @@ protected: void Weird(const char* name); PDict(RPC_CallInfo) calls; - Analyzer* analyzer; + analyzer::Analyzer* analyzer; }; @@ -176,7 +178,7 @@ protected: }; /* Support Analyzer for reassembling RPC-over-TCP messages */ -class Contents_RPC : public TCP_SupportAnalyzer { +class Contents_RPC : public tcp::TCP_SupportAnalyzer { public: Contents_RPC(Connection* conn, bool orig, RPC_Interpreter* interp); virtual ~Contents_RPC(); @@ -222,9 +224,9 @@ protected: int resync_toskip; }; -class RPC_Analyzer : public TCP_ApplicationAnalyzer { +class RPC_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: - RPC_Analyzer(AnalyzerTag::Tag tag, Connection* conn, + RPC_Analyzer(const char* name, Connection* conn, RPC_Interpreter* arg_interp); virtual ~RPC_Analyzer(); @@ -242,4 +244,6 @@ protected: Contents_RPC* resp_rpc; }; +} } // namespace analyzer::* + #endif diff --git a/src/XDR.cc b/src/analyzer/protocol/rpc/XDR.cc similarity index 73% rename from src/XDR.cc rename to src/analyzer/protocol/rpc/XDR.cc index 96d855ddbd..981a982716 100644 --- a/src/XDR.cc +++ b/src/analyzer/protocol/rpc/XDR.cc @@ -6,7 +6,11 @@ #include "XDR.h" -uint32 extract_XDR_uint32(const u_char*& buf, int& len) +#include "events.bif.h" + +using namespace analyzer::rpc; + +uint32 analyzer::rpc::extract_XDR_uint32(const u_char*& buf, int& len) { if ( ! buf ) return 0; @@ -26,7 +30,7 @@ uint32 extract_XDR_uint32(const u_char*& buf, int& len) return bits32; } -uint64 extract_XDR_uint64(const u_char*& buf, int& len) +uint64 analyzer::rpc::extract_XDR_uint64(const u_char*& buf, int& len) { if ( ! buf || len < 8 ) { @@ -40,7 +44,7 @@ uint64 extract_XDR_uint64(const u_char*& buf, int& len) return (uhi << 32) + ulo; } -double extract_XDR_time(const u_char*& buf, int& len) +double analyzer::rpc::extract_XDR_time(const u_char*& buf, int& len) { if ( ! buf || len < 8 ) { @@ -54,7 +58,7 @@ double extract_XDR_time(const u_char*& buf, int& len) return double(uhi) + double(ulo) / 1e9; } -const u_char* extract_XDR_opaque(const u_char*& buf, int& len, int& n, int max_len, bool short_buf_ok) +const u_char* analyzer::rpc::extract_XDR_opaque(const u_char*& buf, int& len, int& n, int max_len, bool short_buf_ok) { n = int(extract_XDR_uint32(buf, len)); if ( ! buf ) @@ -78,7 +82,7 @@ const u_char* extract_XDR_opaque(const u_char*& buf, int& len, int& n, int max_l return opaque; } -const u_char* extract_XDR_opaque_fixed(const u_char*& buf, int& len, int n) +const u_char* analyzer::rpc::extract_XDR_opaque_fixed(const u_char*& buf, int& len, int n) { if ( ! buf ) return 0; @@ -97,7 +101,7 @@ const u_char* extract_XDR_opaque_fixed(const u_char*& buf, int& len, int n) } -uint32 skip_XDR_opaque_auth(const u_char*& buf, int& len) +uint32 analyzer::rpc::skip_XDR_opaque_auth(const u_char*& buf, int& len) { uint32 auth_flavor = extract_XDR_uint32(buf, len); if ( ! buf ) diff --git a/src/XDR.h b/src/analyzer/protocol/rpc/XDR.h similarity index 81% rename from src/XDR.h rename to src/analyzer/protocol/rpc/XDR.h index 65192d6067..a1be0a1e05 100644 --- a/src/XDR.h +++ b/src/analyzer/protocol/rpc/XDR.h @@ -1,13 +1,15 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef xdr_h -#define xdr_h +#ifndef ANALYZER_PROTOCOL_RPC_XDR_H +#define ANALYZER_PROTOCOL_RPC_XDR_H #include #include #include "util.h" +namespace analyzer { namespace rpc { + extern uint32 extract_XDR_uint32(const u_char*& buf, int& len); extern uint64 extract_XDR_uint64(const u_char*& buf, int& len); extern double extract_XDR_time(const u_char*& buf, int& len); @@ -16,4 +18,6 @@ extern const u_char* extract_XDR_opaque(const u_char*& buf, int& len, extern const u_char* extract_XDR_opaque_fixed(const u_char*& buf, int& len, int n); extern uint32 skip_XDR_opaque_auth(const u_char*& buf, int& len); +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/rpc/events.bif b/src/analyzer/protocol/rpc/events.bif new file mode 100644 index 0000000000..72c57aff74 --- /dev/null +++ b/src/analyzer/protocol/rpc/events.bif @@ -0,0 +1,731 @@ +## Generated for NFSv3 request/reply dialogues of type *null*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_read nfs_proc_readdir nfs_proc_readlink +## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_null%(c: connection, info: NFS3::info_t%); + +## Generated for NFSv3 request/reply dialogues of type *getattr*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## fh: TODO. +## +## attrs: The attributes returned in the reply. The values may not be valid if +## the request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status +## rpc_call rpc_dialogue rpc_reply file_mode +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_getattr%(c: connection, info: NFS3::info_t, fh: string, attrs: NFS3::fattr_t%); + +## Generated for NFSv3 request/reply dialogues of type *lookup*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: The arguments passed in the request. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status +## rpc_call rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_lookup%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::lookup_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *read*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: The arguments passed in the request. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_remove nfs_proc_rmdir +## nfs_proc_write nfs_reply_status rpc_call rpc_dialogue rpc_reply +## NFS3::return_data NFS3::return_data_first_only NFS3::return_data_max +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_read%(c: connection, info: NFS3::info_t, req: NFS3::readargs_t, rep: NFS3::read_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *readlink*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## fh: The file handle passed in the request. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_readlink%(c: connection, info: NFS3::info_t, fh: string, rep: NFS3::readlink_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *write*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_reply_status rpc_call +## rpc_dialogue rpc_reply NFS3::return_data NFS3::return_data_first_only +## NFS3::return_data_max +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_write%(c: connection, info: NFS3::info_t, req: NFS3::writeargs_t, rep: NFS3::write_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *create*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status +## rpc_call rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_create%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::newobj_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *mkdir*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status +## rpc_call rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_mkdir%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::newobj_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *remove*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_remove%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::delobj_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *rmdir*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_write nfs_reply_status rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_rmdir%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::delobj_reply_t%); + +## Generated for NFSv3 request/reply dialogues of type *readdir*. The event is +## generated once we have either seen both the request and its corresponding +## reply, or an unanswered request has timed out. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## req: TODO. +## +## rep: The response returned in the reply. The values may not be valid if the +## request was unsuccessful. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readlink +## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_readdir%(c: connection, info: NFS3::info_t, req: NFS3::readdirargs_t, rep: NFS3::readdir_reply_t%); + +## Generated for NFSv3 request/reply dialogues of a type that Bro's NFSv3 +## analyzer does not implement. +## +## NFS is a service running on top of RPC. See `Wikipedia +## `__ for more +## information about the service. +## +## c: The RPC connection. +## +## info: Reports the status of the dialogue, along with some meta information. +## +## proc: The procedure called that Bro does not implement. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_null nfs_proc_read nfs_proc_readdir nfs_proc_readlink nfs_proc_remove +## nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_proc_not_implemented%(c: connection, info: NFS3::info_t, proc: NFS3::proc_t%); + +## Generated for each NFSv3 reply message received, reporting just the +## status included. +## +## n: The connection. +## +## info: Reports the status included in the reply. +## +## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir +## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir +## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event nfs_reply_status%(n: connection, info: NFS3::info_t%); + +## Generated for Portmapper requests of type *null*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit +## pm_request_dump pm_request_getport pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_null%(r: connection%); + +## Generated for Portmapper request/reply dialogues of type *set*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## m: The argument to the request. +## +## success: True if the request was successful, according to the corresponding +## reply. If no reply was seen, this will be false once the request +## times out. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit +## pm_request_dump pm_request_getport pm_request_null pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_set%(r: connection, m: pm_mapping, success: bool%); + +## Generated for Portmapper request/reply dialogues of type *unset*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## m: The argument to the request. +## +## success: True if the request was successful, according to the corresponding +## reply. If no reply was seen, this will be false once the request +## times out. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit +## pm_request_dump pm_request_getport pm_request_null pm_request_set rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_unset%(r: connection, m: pm_mapping, success: bool%); + +## Generated for Portmapper request/reply dialogues of type *getport*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## pr: The argument to the request. +## +## p: The port returned by the server. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit +## pm_request_dump pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_getport%(r: connection, pr: pm_port_request, p: port%); + +## Generated for Portmapper request/reply dialogues of type *dump*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## m: The mappings returned by the server. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_dump%(r: connection, m: pm_mappings%); + +## Generated for Portmapper request/reply dialogues of type *callit*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## call: The argument to the request. +## +## p: The port value returned by the call. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_request_callit%(r: connection, call: pm_callit_request, p: port%); + +## Generated for failed Portmapper requests of type *null*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_null%(r: connection, status: rpc_status%); + +## Generated for failed Portmapper requests of type *set*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## m: The argument to the original request. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_set%(r: connection, status: rpc_status, m: pm_mapping%); + +## Generated for failed Portmapper requests of type *unset*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## m: The argument to the original request. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_unset%(r: connection, status: rpc_status, m: pm_mapping%); + +## Generated for failed Portmapper requests of type *getport*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## pr: The argument to the original request. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_null +## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_getport%(r: connection, status: rpc_status, pr: pm_port_request%); + +## Generated for failed Portmapper requests of type *dump*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_getport pm_attempt_null +## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_dump%(r: connection, status: rpc_status%); + +## Generated for failed Portmapper requests of type *callit*. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## call: The argument to the original request. +## +## .. bro:see:: epm_map_response pm_attempt_dump pm_attempt_getport pm_attempt_null +## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump +## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call +## rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_attempt_callit%(r: connection, status: rpc_status, call: pm_callit_request%); + +## Generated for Portmapper requests or replies that include an invalid port +## number. Since ports are represented by unsigned 4-byte integers, they can +## stray outside the allowed range of 0--65535 by being >= 65536. If so, this +## event is generated. +## +## Portmapper is a service running on top of RPC. See `Wikipedia +## `__ for more information about the +## service. +## +## r: The RPC connection. +## +## bad_p: The invalid port value. +## +## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport +## pm_attempt_null pm_attempt_set pm_attempt_unset pm_request_callit +## pm_request_dump pm_request_getport pm_request_null pm_request_set +## pm_request_unset rpc_call rpc_dialogue rpc_reply +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event pm_bad_port%(r: connection, bad_p: count%); + +## Generated for RPC request/reply *pairs*. The RPC analyzer associates request +## and reply by their transaction identifiers and raises this event once both +## have been seen. If there's not a reply, this event will still be generated +## eventually on timeout. In that case, *status* will be set to +## :bro:enum:`RPC_TIMEOUT`. +## +## See `Wikipedia `__ for more information +## about the ONC RPC protocol. +## +## c: The connection. +## +## prog: The remote program to call. +## +## ver: The version of the remote program to call. +## +## proc: The procedure of the remote program to call. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## start_time: The time when the *call* was seen. +## +## call_len: The size of the *call_body* PDU. +## +## reply_len: The size of the *reply_body* PDU. +## +## .. bro:see:: rpc_call rpc_reply dce_rpc_bind dce_rpc_message dce_rpc_request +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event rpc_dialogue%(c: connection, prog: count, ver: count, proc: count, status: rpc_status, start_time: time, call_len: count, reply_len: count%); + +## Generated for RPC *call* messages. +## +## See `Wikipedia `__ for more information +## about the ONC RPC protocol. +## +## c: The connection. +## +## xid: The transaction identifier allowing to match requests with replies. +## +## prog: The remote program to call. +## +## ver: The version of the remote program to call. +## +## proc: The procedure of the remote program to call. +## +## call_len: The size of the *call_body* PDU. +## +## .. bro:see:: rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message dce_rpc_request +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event rpc_call%(c: connection, xid: count, prog: count, ver: count, proc: count, call_len: count%); + +## Generated for RPC *reply* messages. +## +## See `Wikipedia `__ for more information +## about the ONC RPC protocol. +## +## c: The connection. +## +## xid: The transaction identifier allowing to match requests with replies. +## +## status: The status of the reply, which should be one of the index values of +## :bro:id:`RPC_status`. +## +## reply_len: The size of the *reply_body* PDU. +## +## .. bro:see:: rpc_call rpc_dialogue dce_rpc_bind dce_rpc_message dce_rpc_request +## dce_rpc_response rpc_timeout +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to add a +## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload +## signature. +event rpc_reply%(c: connection, xid: count, status: rpc_status, reply_len: count%); diff --git a/src/analyzer/protocol/smb/CMakeLists.txt b/src/analyzer/protocol/smb/CMakeLists.txt new file mode 100644 index 0000000000..feec283197 --- /dev/null +++ b/src/analyzer/protocol/smb/CMakeLists.txt @@ -0,0 +1,11 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/../dce-rpc) + +bro_plugin_begin(Bro SMB) +bro_plugin_cc(SMB.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(smb.pac smb-protocol.pac smb-pipe.pac smb-mailslot.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/smb/Plugin.cc b/src/analyzer/protocol/smb/Plugin.cc new file mode 100644 index 0000000000..af564c067c --- /dev/null +++ b/src/analyzer/protocol/smb/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "SMB.h" + +BRO_PLUGIN_BEGIN(Bro, SMB) + BRO_PLUGIN_DESCRIPTION("SMB analyzer"); + BRO_PLUGIN_ANALYZER("SMB", smb::SMB_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents_SMB"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/SMB.cc b/src/analyzer/protocol/smb/SMB.cc similarity index 98% rename from src/SMB.cc rename to src/analyzer/protocol/smb/SMB.cc index a06707328a..798e2bfd1f 100644 --- a/src/SMB.cc +++ b/src/analyzer/protocol/smb/SMB.cc @@ -6,6 +6,10 @@ #include "Val.h" #include "Reporter.h" +#include "events.bif.h" + +using namespace analyzer::smb; + namespace { const bool DEBUG_smb_ipc = true; } @@ -93,7 +97,7 @@ static int lookup_IPC_name(BroString* name) return IPC_NONE; } -SMB_Session::SMB_Session(Analyzer* arg_analyzer) +SMB_Session::SMB_Session(analyzer::Analyzer* arg_analyzer) { analyzer = arg_analyzer; dce_rpc_session = 0; @@ -1093,7 +1097,7 @@ bool SMB_Session::CheckRPC(int is_orig, int data_count, const u_char *data) if ( LooksLikeRPC(data_count, data) ) { if ( ! dce_rpc_session ) - dce_rpc_session = new DCE_RPC_Session(analyzer); + dce_rpc_session = new dce_rpc::DCE_RPC_Session(analyzer); dce_rpc_session->DeliverPDU(is_orig, data_count, data); @@ -1104,7 +1108,7 @@ bool SMB_Session::CheckRPC(int is_orig, int data_count, const u_char *data) } Contents_SMB::Contents_SMB(Connection* conn, bool orig, SMB_Session* s) -: TCP_SupportAnalyzer(AnalyzerTag::Contents_SMB, conn, orig) +: tcp::TCP_SupportAnalyzer("CONTENTS_SMB", conn, orig) { smb_session = s; msg_buf = 0; @@ -1145,7 +1149,7 @@ void Contents_SMB::DeliverSMB(int len, const u_char* data) void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); while ( len > 0 ) { @@ -1221,7 +1225,7 @@ void Contents_SMB::DeliverStream(int len, const u_char* data, bool orig) } SMB_Analyzer::SMB_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::SMB, conn) +: tcp::TCP_ApplicationAnalyzer("SMB", conn) { smb_session = new SMB_Session(this); o_smb = new Contents_SMB(conn, true, smb_session); diff --git a/src/SMB.h b/src/analyzer/protocol/smb/SMB.h similarity index 88% rename from src/SMB.h rename to src/analyzer/protocol/smb/SMB.h index f7287efb79..b54852e5b7 100644 --- a/src/SMB.h +++ b/src/analyzer/protocol/smb/SMB.h @@ -1,15 +1,17 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef smb_h -#define smb_h +#ifndef ANALYZER_PROTOCOL_SMB_SMB_H +#define ANALYZER_PROTOCOL_SMB_SMB_H // SMB (CIFS) analyzer. // Reference: http://www.snia.org/tech_activities/CIFS/CIFS-TR-1p00_FINAL.pdf -#include "TCP.h" -#include "DCE_RPC.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/dce-rpc/DCE_RPC.h" #include "smb_pac.h" +namespace analyzer { namespace smb { + enum IPC_named_pipe { IPC_NONE, IPC_LOCATOR, @@ -39,20 +41,11 @@ protected: class SMB_Session { public: - SMB_Session(Analyzer* analyzer); + SMB_Session(analyzer::Analyzer* analyzer); ~SMB_Session(); void Deliver(int is_orig, int len, const u_char* msg); - static bool any_smb_event() - { - return smb_message || - smb_com_tree_connect_andx || - smb_com_nt_create_andx || smb_com_transaction || - smb_com_transaction2 || smb_com_read_andx || - smb_com_write_andx; - } - protected: void ParseMessage(int is_orig, int cmd, binpac::SMB::SMB_header const &hdr, @@ -158,8 +151,8 @@ protected: Val* BuildTransactionVal(binpac::SMB::SMB_transaction_response const &trans); Val* BuildTransactionDataVal(binpac::SMB::SMB_transaction_data* data); - Analyzer* analyzer; - DCE_RPC_Session* dce_rpc_session; + analyzer::Analyzer* analyzer; + dce_rpc::DCE_RPC_Session* dce_rpc_session; enum IPC_named_pipe IPC_pipe; int is_IPC; int req_cmd; @@ -170,7 +163,7 @@ protected: binpac::SMB::SMB_andx* andx_[2]; }; -class Contents_SMB : public TCP_SupportAnalyzer { +class Contents_SMB : public tcp::TCP_SupportAnalyzer { public: Contents_SMB(Connection* conn, bool orig, SMB_Session* smb_session); ~Contents_SMB(); @@ -190,24 +183,20 @@ protected: int buf_len; // size off msg_buf }; -class SMB_Analyzer : public TCP_ApplicationAnalyzer { +class SMB_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SMB_Analyzer(Connection* conn); ~SMB_Analyzer(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SMB_Analyzer(conn); } - static bool Available() - { - return SMB_Session::any_smb_event() || - DCE_RPC_Session::any_dce_rpc_event(); - } - protected: SMB_Session* smb_session; Contents_SMB* o_smb; Contents_SMB* r_smb; }; +} } // namespace analyzer::* + #endif diff --git a/src/SMB_COM.def b/src/analyzer/protocol/smb/SMB_COM.def similarity index 100% rename from src/SMB_COM.def rename to src/analyzer/protocol/smb/SMB_COM.def diff --git a/src/analyzer/protocol/smb/events.bif b/src/analyzer/protocol/smb/events.bif new file mode 100644 index 0000000000..74cb1feb77 --- /dev/null +++ b/src/analyzer/protocol/smb/events.bif @@ -0,0 +1,495 @@ +## Generated for all SMB/CIFS messages. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## is_orig: True if the message was sent by the originator of the underlying +## transport-level connection. +## +## cmd: A string mnemonic of the SMB command code. +## +## body_length: The length of the SMB message body, i.e. the data starting after +## the SMB header. +## +## body: The raw SMB message body, i.e., the data starting after the SMB header. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error +## smb_get_dfs_referral +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_message%(c: connection, hdr: smb_hdr, is_orig: bool, cmd: string, body_length: count, body: string%); + +## Generated for SMB/CIFS messages of type *tree connect andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## path: The ``path`` attribute specified in the message. +## +## service: The ``service`` attribute specified in the message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_tree_connect_andx%(c: connection, hdr: smb_hdr, path: string, service: string%); + +## Generated for SMB/CIFS messages of type *tree disconnect*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_tree_disconnect%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages of type *nt create andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## name: The ``name`` attribute specified in the message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_read_andx +## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_nt_create_andx%(c: connection, hdr: smb_hdr, name: string%); + +## Generated for SMB/CIFS messages of type *nt transaction*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## trans: The parsed transaction header. +## +## data: The raw transaction data. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe +## smb_com_trans_rap smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_transaction%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); + +## Generated for SMB/CIFS messages of type *nt transaction 2*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## trans: The parsed transaction header. +## +## data: The raw transaction data. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe +## smb_com_trans_rap smb_com_transaction smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_transaction2%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); + +## Generated for SMB/CIFS messages of type *transaction mailslot*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## trans: The parsed transaction header. +## +## data: The raw transaction data. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_trans_mailslot%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); + +## Generated for SMB/CIFS messages of type *transaction rap*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## trans: The parsed transaction header. +## +## data: The raw transaction data. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error +## smb_get_dfs_referral smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_trans_rap%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); + +## Generated for SMB/CIFS messages of type *transaction pipe*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## trans: The parsed transaction header. +## +## data: The raw transaction data. +## +## is_orig: True if the message was sent by the originator of the connection. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_trans_pipe%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); + +## Generated for SMB/CIFS messages of type *read andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## data: Always empty. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_read_andx%(c: connection, hdr: smb_hdr, data: string%); + +## Generated for SMB/CIFS messages of type *read andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## data: Always empty. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_tree_disconnect smb_error +## smb_get_dfs_referral smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_write_andx%(c: connection, hdr: smb_hdr, data: string%); + +## Generated for SMB/CIFS messages of type *get dfs referral*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## max_referral_level: The ``max_referral_level`` attribute specified in the +## message. +## +## file_name: The ``filene_name`` attribute specified in the message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_get_dfs_referral%(c: connection, hdr: smb_hdr, max_referral_level: count, file_name: string%); + +## Generated for SMB/CIFS messages of type *negotiate*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx smb_com_setup_andx +## smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap smb_com_transaction +## smb_com_transaction2 smb_com_tree_connect_andx smb_com_tree_disconnect +## smb_com_write_andx smb_error smb_get_dfs_referral smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_negotiate%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages of type *negotiate response*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## dialect_index: The ``dialect`` indicated in the message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_nt_create_andx smb_com_read_andx smb_com_setup_andx +## smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap smb_com_transaction +## smb_com_transaction2 smb_com_tree_connect_andx smb_com_tree_disconnect +## smb_com_write_andx smb_error smb_get_dfs_referral smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_negotiate_response%(c: connection, hdr: smb_hdr, dialect_index: count%); + +## Generated for SMB/CIFS messages of type *setup andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_setup_andx%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages of type *generic andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_close smb_com_logoff_andx smb_com_negotiate +## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx +## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_generic_andx%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages of type *close*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_generic_andx smb_com_logoff_andx smb_com_negotiate +## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx +## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_close%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages of type *logoff andx*. +## +## See `Wikipedia `__ for +## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses +## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_negotiate +## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx +## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap +## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx +## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral +## smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_com_logoff_andx%(c: connection, hdr: smb_hdr%); + +## Generated for SMB/CIFS messages that indicate an error. This event is +## triggered by an SMB header including a status that signals an error. +## +## c: The connection. +## +## hdr: The parsed header of the SMB message. +## +## cmd: The SMB command code. +## +## cmd_str: A string mnemonic of the SMB command code. +## +## data: The raw SMB message body, i.e., the data starting after the SMB header. +## +## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx +## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx +## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot +## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 +## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx +## smb_get_dfs_referral smb_message +## +## .. todo:: Bro's current default configuration does not activate the protocol +## analyzer that generates this event; the corresponding script has not yet +## been ported to Bro 2.x. To still enable this event, one needs to +## register a port for it or add a DPD payload signature. +event smb_error%(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, data: string%); + diff --git a/src/smb-mailslot.pac b/src/analyzer/protocol/smb/smb-mailslot.pac similarity index 100% rename from src/smb-mailslot.pac rename to src/analyzer/protocol/smb/smb-mailslot.pac diff --git a/src/smb-pipe.pac b/src/analyzer/protocol/smb/smb-pipe.pac similarity index 100% rename from src/smb-pipe.pac rename to src/analyzer/protocol/smb/smb-pipe.pac diff --git a/src/smb-protocol.pac b/src/analyzer/protocol/smb/smb-protocol.pac similarity index 100% rename from src/smb-protocol.pac rename to src/analyzer/protocol/smb/smb-protocol.pac diff --git a/src/smb.pac b/src/analyzer/protocol/smb/smb.pac similarity index 79% rename from src/smb.pac rename to src/analyzer/protocol/smb/smb.pac index 740ad47991..1fdab27d90 100644 --- a/src/smb.pac +++ b/src/analyzer/protocol/smb/smb.pac @@ -1,6 +1,10 @@ %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer SMB withcontext { }; %include smb-protocol.pac diff --git a/src/analyzer/protocol/smtp/CMakeLists.txt b/src/analyzer/protocol/smtp/CMakeLists.txt new file mode 100644 index 0000000000..82918656a0 --- /dev/null +++ b/src/analyzer/protocol/smtp/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SMTP) +bro_plugin_cc(SMTP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/smtp/Plugin.cc b/src/analyzer/protocol/smtp/Plugin.cc new file mode 100644 index 0000000000..e089d7ffb1 --- /dev/null +++ b/src/analyzer/protocol/smtp/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "SMTP.h" + +BRO_PLUGIN_BEGIN(Bro, SMTP) + BRO_PLUGIN_DESCRIPTION("SMTP analyzer"); + BRO_PLUGIN_ANALYZER("SMTP", smtp::SMTP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/SMTP.cc b/src/analyzer/protocol/smtp/SMTP.cc similarity index 96% rename from src/SMTP.cc rename to src/analyzer/protocol/smtp/SMTP.cc index 33f65ed743..b496e97c69 100644 --- a/src/SMTP.cc +++ b/src/analyzer/protocol/smtp/SMTP.cc @@ -7,8 +7,12 @@ #include "NetVar.h" #include "SMTP.h" #include "Event.h" -#include "ContentLine.h" #include "Reporter.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +#include "events.bif.h" + +using namespace analyzer::smtp; #undef SMTP_CMD_DEF #define SMTP_CMD_DEF(cmd) #cmd, @@ -21,7 +25,7 @@ static const char* smtp_cmd_word[] = { SMTP_Analyzer::SMTP_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::SMTP, conn) +: tcp::TCP_ApplicationAnalyzer("SMTP", conn) { expect_sender = 0; expect_recver = 1; @@ -40,12 +44,12 @@ SMTP_Analyzer::SMTP_Analyzer(Connection* conn) line_after_gap = 0; mail = 0; UpdateState(first_cmd, 0); - ContentLine_Analyzer* cl_orig = new ContentLine_Analyzer(conn, true); + tcp::ContentLine_Analyzer* cl_orig = new tcp::ContentLine_Analyzer(conn, true); cl_orig->SetIsNULSensitive(true); cl_orig->SetSkipPartial(true); AddSupportAnalyzer(cl_orig); - ContentLine_Analyzer* cl_resp = new ContentLine_Analyzer(conn, false); + tcp::ContentLine_Analyzer* cl_resp = new tcp::ContentLine_Analyzer(conn, false); cl_resp->SetIsNULSensitive(true); cl_resp->SetSkipPartial(true); AddSupportAnalyzer(cl_resp); @@ -53,7 +57,7 @@ SMTP_Analyzer::SMTP_Analyzer(Connection* conn) void SMTP_Analyzer::ConnectionFinished(int half_finished) { - TCP_ApplicationAnalyzer::ConnectionFinished(half_finished); + tcp::TCP_ApplicationAnalyzer::ConnectionFinished(half_finished); if ( ! half_finished && mail ) EndData(); @@ -66,7 +70,7 @@ SMTP_Analyzer::~SMTP_Analyzer() void SMTP_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); if ( mail ) EndData(); @@ -74,7 +78,7 @@ void SMTP_Analyzer::Done() void SMTP_Analyzer::Undelivered(int seq, int len, bool is_orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); if ( len <= 0 ) return; @@ -112,7 +116,7 @@ void SMTP_Analyzer::Undelivered(int seq, int len, bool is_orig) void SMTP_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); // NOTE: do not use IsOrig() here, because of TURN command. int is_sender = orig_is_sender ? orig : ! orig; @@ -873,7 +877,7 @@ void SMTP_Analyzer::BeginData() delete mail; } - mail = new MIME_Mail(this); + mail = new mime::MIME_Mail(this); } void SMTP_Analyzer::EndData() diff --git a/src/SMTP.h b/src/analyzer/protocol/smtp/SMTP.h similarity index 87% rename from src/SMTP.h rename to src/analyzer/protocol/smtp/SMTP.h index 5b15dc44c0..cc12167d30 100644 --- a/src/SMTP.h +++ b/src/analyzer/protocol/smtp/SMTP.h @@ -1,18 +1,19 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef smtp_h -#define smtp_h +#ifndef ANALYZER_PROTOCOL_SMTP_SMTP_H +#define ANALYZER_PROTOCOL_SMTP_SMTP_H #include using namespace std; -#include "TCP.h" -#include "MIME.h" - +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/mime/MIME.h" #undef SMTP_CMD_DEF #define SMTP_CMD_DEF(cmd) SMTP_CMD_##cmd, +namespace analyzer { namespace smtp { + typedef enum { #include "SMTP_cmd.def" } SMTP_Cmd; @@ -35,7 +36,7 @@ typedef enum { } SMTP_State; -class SMTP_Analyzer : public TCP_ApplicationAnalyzer { +class SMTP_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SMTP_Analyzer(Connection* conn); ~SMTP_Analyzer(); @@ -47,17 +48,11 @@ public: void SkipData() { skip_data = 1; } // skip delivery of data lines - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SMTP_Analyzer(conn); } - static bool Available() - { - return smtp_request || smtp_reply || - smtp_data || smtp_unexpected; - } - protected: void ProcessLine(int length, const char* line, bool orig); @@ -93,7 +88,9 @@ protected: BroString* line_after_gap; // last line before the first reply // after a gap - MIME_Mail* mail; + mime::MIME_Mail* mail; }; +} } // namespace analyzer::* + #endif diff --git a/src/SMTP_cmd.def b/src/analyzer/protocol/smtp/SMTP_cmd.def similarity index 100% rename from src/SMTP_cmd.def rename to src/analyzer/protocol/smtp/SMTP_cmd.def diff --git a/src/analyzer/protocol/smtp/events.bif b/src/analyzer/protocol/smtp/events.bif new file mode 100644 index 0000000000..4a376bcbf8 --- /dev/null +++ b/src/analyzer/protocol/smtp/events.bif @@ -0,0 +1,100 @@ +## Generated for client-side SMTP commands. +## +## See `Wikipedia `__ +## for more information about the SMTP protocol. +## +## c: The connection. +## +## is_orig: True if the sender of the command is the originator of the TCP +## connection. Note that this is not redundant: the SMTP ``TURN`` command +## allows client and server to flip roles on established SMTP sessions, +## and hence a "request" might still come from the TCP-level responder. +## In practice, however, that will rarely happen as TURN is considered +## insecure and rarely used. +## +## command: The request's command, without any arguments. +## +## arg: The request command's arguments. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data +## smtp_data smtp_reply +## +## .. note:: Bro does not support the newer ETRN extension yet. +event smtp_request%(c: connection, is_orig: bool, command: string, arg: string%); + +## Generated for server-side SMTP commands. +## +## See `Wikipedia `__ +## for more information about the SMTP protocol. +## +## c: The connection. +## +## is_orig: True if the sender of the command is the originator of the TCP +## connection. Note that this is not redundant: the SMTP ``TURN`` command +## allows client and server to flip roles on established SMTP sessions, +## and hence a "reply" might still come from the TCP-level originator. In +## practice, however, that will rarely happen as TURN is considered +## insecure and rarely used. +## +## code: The reply's numerical code. +## +## cmd: TODO. +## +## msg: The reply's textual description. +## +## cont_resp: True if the reply line is tagged as being continued to the next +## line. If so, further events will be raised and a handler may want to +## reassemble the pieces before processing the response any further. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data +## smtp_data smtp_request +## +## .. note:: Bro doesn't support the newer ETRN extension yet. +event smtp_reply%(c: connection, is_orig: bool, code: count, cmd: string, msg: string, cont_resp: bool%); + +## Generated for DATA transmitted on SMTP sessions. This event is raised for +## subsequent chunks of raw data following the ``DATA`` SMTP command until the +## corresponding end marker ``.`` is seen. A handler may want to reassemble +## the pieces as they come in if stream-analysis is required. +## +## See `Wikipedia `__ +## for more information about the SMTP protocol. +## +## c: The connection. +## +## is_orig: True if the sender of the data is the originator of the TCP +## connection. +## +## data: The raw data. Note that the size of each chunk is undefined and +## depends on specifics of the underlying TCP connection. +## +## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash +## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data +## smtp_reply smtp_request skip_smtp_data +## +## .. note:: This event receives the unprocessed raw data. There is a separate +## set of ``mime_*`` events that strip out the outer MIME-layer of emails and +## provide structured access to their content. +event smtp_data%(c: connection, is_orig: bool, data: string%); + +## Generated for unexpected activity on SMTP sessions. The SMTP analyzer tracks +## the state of SMTP sessions and reports commands and other activity with this +## event that it sees even though it would not expect so at the current point +## of the communication. +## +## See `Wikipedia `__ +## for more information about the SMTP protocol. +## +## c: The connection. +## +## is_orig: True if the sender of the unexpected activity is the originator of +## the TCP connection. +## +## msg: A descriptive message of what was unexpected. +## +## detail: The actual SMTP line triggering the event. +## +## .. bro:see:: smtp_data smtp_request smtp_reply +event smtp_unexpected%(c: connection, is_orig: bool, msg: string, detail: string%); diff --git a/src/analyzer/protocol/smtp/functions.bif b/src/analyzer/protocol/smtp/functions.bif new file mode 100644 index 0000000000..8630685096 --- /dev/null +++ b/src/analyzer/protocol/smtp/functions.bif @@ -0,0 +1,17 @@ + +%%{ +#include "analyzer/protocol/smtp/SMTP.h" +%%} + +## Skips SMTP data until the next email in a connection. +## +## c: The SMTP connection. +## +## .. bro:see:: skip_http_entity_data +function skip_smtp_data%(c: connection%): any + %{ + analyzer::Analyzer* sa = c->FindAnalyzer("SMTP"); + if ( sa ) + static_cast(sa)->SkipData(); + return 0; + %} diff --git a/src/analyzer/protocol/socks/CMakeLists.txt b/src/analyzer/protocol/socks/CMakeLists.txt new file mode 100644 index 0000000000..5157c8d368 --- /dev/null +++ b/src/analyzer/protocol/socks/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SOCKS) +bro_plugin_cc(SOCKS.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(socks.pac socks-protocol.pac socks-analyzer.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/socks/Plugin.cc b/src/analyzer/protocol/socks/Plugin.cc new file mode 100644 index 0000000000..d01f4520b7 --- /dev/null +++ b/src/analyzer/protocol/socks/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "SOCKS.h" + +BRO_PLUGIN_BEGIN(Bro, SOCKS) + BRO_PLUGIN_DESCRIPTION("SOCKS analyzer"); + BRO_PLUGIN_ANALYZER("SOCKS", socks::SOCKS_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/SOCKS.cc b/src/analyzer/protocol/socks/SOCKS.cc similarity index 77% rename from src/SOCKS.cc rename to src/analyzer/protocol/socks/SOCKS.cc index 4a6eda7043..f9d81b8a16 100644 --- a/src/SOCKS.cc +++ b/src/analyzer/protocol/socks/SOCKS.cc @@ -1,9 +1,13 @@ #include "SOCKS.h" #include "socks_pac.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" + +using namespace analyzer::socks; SOCKS_Analyzer::SOCKS_Analyzer(Connection* conn) -: TCP_ApplicationAnalyzer(AnalyzerTag::SOCKS, conn) +: tcp::TCP_ApplicationAnalyzer("SOCKS", conn) { interp = new binpac::SOCKS::SOCKS_Conn(this); orig_done = resp_done = false; @@ -25,7 +29,7 @@ void SOCKS_Analyzer::EndpointDone(bool orig) void SOCKS_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); interp->FlowEOF(true); interp->FlowEOF(false); @@ -33,13 +37,13 @@ void SOCKS_Analyzer::Done() void SOCKS_Analyzer::EndpointEOF(bool is_orig) { - TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); interp->FlowEOF(is_orig); } void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); @@ -57,7 +61,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) if ( ! pia ) { - pia = new PIA_TCP(Conn()); + pia = new pia::PIA_TCP(Conn()); AddChildAnalyzer(pia); pia->FirstPacket(true, 0); pia->FirstPacket(false, 0); @@ -80,7 +84,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) void SOCKS_Analyzer::Undelivered(int seq, int len, bool orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); } diff --git a/src/SOCKS.h b/src/analyzer/protocol/socks/SOCKS.h similarity index 58% rename from src/SOCKS.h rename to src/analyzer/protocol/socks/SOCKS.h index 9753abb660..f005967fd8 100644 --- a/src/SOCKS.h +++ b/src/analyzer/protocol/socks/SOCKS.h @@ -1,10 +1,10 @@ -#ifndef socks_h -#define socks_h +#ifndef ANALYZER_PROTOCOL_SOCKS_SOCKS_H +#define ANALYZER_PROTOCOL_SOCKS_SOCKS_H // SOCKS v4 analyzer. -#include "TCP.h" -#include "PIA.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/pia/PIA.h" namespace binpac { namespace SOCKS { @@ -12,8 +12,9 @@ namespace binpac { } } +namespace analyzer { namespace socks { -class SOCKS_Analyzer : public TCP_ApplicationAnalyzer { +class SOCKS_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SOCKS_Analyzer(Connection* conn); ~SOCKS_Analyzer(); @@ -25,21 +26,18 @@ public: virtual void Undelivered(int seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SOCKS_Analyzer(conn); } - static bool Available() - { - return socks_request || socks_reply; - } - protected: bool orig_done; bool resp_done; - PIA_TCP *pia; + pia::PIA_TCP *pia; binpac::SOCKS::SOCKS_Conn* interp; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/socks/events.bif b/src/analyzer/protocol/socks/events.bif new file mode 100644 index 0000000000..4f1f8ad1cd --- /dev/null +++ b/src/analyzer/protocol/socks/events.bif @@ -0,0 +1,29 @@ +## Generated when a SOCKS request is analyzed. +## +## c: The parent connection of the proxy. +## +## version: The version of SOCKS this message used. +## +## request_type: The type of the request. +## +## sa: Address that the tunneled traffic should be sent to. +## +## p: The destination port for the proxied traffic. +## +## user: Username given for the SOCKS connection. This is not yet implemented +## for SOCKSv5. +event socks_request%(c: connection, version: count, request_type: count, sa: SOCKS::Address, p: port, user: string%); + +## Generated when a SOCKS reply is analyzed. +## +## c: The parent connection of the proxy. +## +## version: The version of SOCKS this message used. +## +## reply: The status reply from the server. +## +## sa: The address that the server sent the traffic to. +## +## p: The destination port for the proxied traffic. +event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Address, p: port%); + diff --git a/src/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac similarity index 93% rename from src/socks-analyzer.pac rename to src/analyzer/protocol/socks/socks-analyzer.pac index 7ce364670b..80051f0b27 100644 --- a/src/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -35,7 +35,7 @@ refine connection SOCKS_Conn += { new PortVal(${request.port} | TCP_PORT_MASK), array_to_string(${request.user})); - static_cast(bro_analyzer())->EndpointDone(true); + static_cast(bro_analyzer())->EndpointDone(true); return true; %} @@ -53,7 +53,7 @@ refine connection SOCKS_Conn += { new PortVal(${reply.port} | TCP_PORT_MASK)); bro_analyzer()->ProtocolConfirmation(); - static_cast(bro_analyzer())->EndpointDone(false); + static_cast(bro_analyzer())->EndpointDone(false); return true; %} @@ -97,7 +97,7 @@ refine connection SOCKS_Conn += { new PortVal(${request.port} | TCP_PORT_MASK), new StringVal("")); - static_cast(bro_analyzer())->EndpointDone(true); + static_cast(bro_analyzer())->EndpointDone(true); return true; %} @@ -136,7 +136,7 @@ refine connection SOCKS_Conn += { new PortVal(${reply.port} | TCP_PORT_MASK)); bro_analyzer()->ProtocolConfirmation(); - static_cast(bro_analyzer())->EndpointDone(false); + static_cast(bro_analyzer())->EndpointDone(false); return true; %} diff --git a/src/socks-protocol.pac b/src/analyzer/protocol/socks/socks-protocol.pac similarity index 100% rename from src/socks-protocol.pac rename to src/analyzer/protocol/socks/socks-protocol.pac diff --git a/src/socks.pac b/src/analyzer/protocol/socks/socks.pac similarity index 88% rename from src/socks.pac rename to src/analyzer/protocol/socks/socks.pac index 15d3580674..a9c4099508 100644 --- a/src/socks.pac +++ b/src/analyzer/protocol/socks/socks.pac @@ -3,6 +3,8 @@ %extern{ #include "SOCKS.h" + +#include "events.bif.h" %} analyzer SOCKS withcontext { @@ -21,4 +23,4 @@ flow SOCKS_Flow(is_orig: bool) { datagram = SOCKS_Version(is_orig) withcontext(connection, this); }; -%include socks-analyzer.pac \ No newline at end of file +%include socks-analyzer.pac diff --git a/src/analyzer/protocol/ssh/CMakeLists.txt b/src/analyzer/protocol/ssh/CMakeLists.txt new file mode 100644 index 0000000000..505c89332e --- /dev/null +++ b/src/analyzer/protocol/ssh/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SSH) +bro_plugin_cc(SSH.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/ssh/Plugin.cc b/src/analyzer/protocol/ssh/Plugin.cc new file mode 100644 index 0000000000..53a0294a88 --- /dev/null +++ b/src/analyzer/protocol/ssh/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "SSH.h" + +BRO_PLUGIN_BEGIN(Bro, SSH) + BRO_PLUGIN_DESCRIPTION("SSH analyzer"); + BRO_PLUGIN_ANALYZER("SSH", ssh::SSH_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc similarity index 84% rename from src/SSH.cc rename to src/analyzer/protocol/ssh/SSH.cc index 3a8f468ae4..ab3f6a5e5b 100644 --- a/src/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -7,17 +7,21 @@ #include "NetVar.h" #include "SSH.h" #include "Event.h" -#include "ContentLine.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +#include "events.bif.h" + +using namespace analyzer::ssh; SSH_Analyzer::SSH_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::SSH, c) +: tcp::TCP_ApplicationAnalyzer("SSH", c) { - orig = new ContentLine_Analyzer(c, true); + orig = new tcp::ContentLine_Analyzer(c, true); orig->SetSkipPartial(true); orig->SetCRLFAsEOL(LF_as_EOL); AddSupportAnalyzer(orig); - resp = new ContentLine_Analyzer(c, false); + resp = new tcp::ContentLine_Analyzer(c, false); resp->SetSkipPartial(true); resp->SetCRLFAsEOL(LF_as_EOL); AddSupportAnalyzer(resp); @@ -25,7 +29,7 @@ SSH_Analyzer::SSH_Analyzer(Connection* c) void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig); // We're all done processing this endpoint - flag it as such, // before we even determine whether we have any event generation @@ -38,7 +42,7 @@ void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) if ( TCP() ) { // Don't try to parse version if there has already been a gap. - TCP_Endpoint* endp = is_orig ? TCP()->Orig() : TCP()->Resp(); + tcp::TCP_Endpoint* endp = is_orig ? TCP()->Orig() : TCP()->Resp(); if ( endp->HadGap() ) return; } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h new file mode 100644 index 0000000000..3878881693 --- /dev/null +++ b/src/analyzer/protocol/ssh/SSH.h @@ -0,0 +1,27 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_PROTOCOL_SSH_SSH_H +#define ANALYZER_PROTOCOL_SSH_SSH_H + +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" + +namespace analyzer { namespace ssh { + +class SSH_Analyzer : public tcp::TCP_ApplicationAnalyzer { +public: + SSH_Analyzer(Connection* conn); + + virtual void DeliverStream(int len, const u_char* data, bool orig); + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new SSH_Analyzer(conn); } + +private: + tcp::ContentLine_Analyzer* orig; + tcp::ContentLine_Analyzer* resp; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif new file mode 100644 index 0000000000..9d73f5e483 --- /dev/null +++ b/src/analyzer/protocol/ssh/events.bif @@ -0,0 +1,38 @@ +## Generated when seeing an SSH client's version identification. The SSH +## protocol starts with a clear-text handshake message that reports client and +## server protocol/software versions. This event provides access to what the +## client sent. +## +## +## See `Wikipedia `__ for more +## information about the SSH protocol. +## +## c: The connection. +## +## version: The version string the client sent (e.g., `SSH-2.0-libssh-0.11`). +## +## .. bro:see:: ssh_server_version +## +## .. note:: As everything after the initial version handshake proceeds +## encrypted, Bro cannot further analyze SSH sessions. +event ssh_client_version%(c: connection, version: string%); + +## Generated when seeing an SSH server's version identification. The SSH +## protocol starts with a clear-text handshake message that reports client and +## server protocol/software versions. This event provides access to what the +## server sent. +## +## See `Wikipedia `__ for more +## information about the SSH protocol. +## +## c: The connection. +## +## version: The version string the server sent (e.g., +## ``SSH-1.99-OpenSSH_3.9p1``). +## +## .. bro:see:: ssh_client_version +## +## .. note:: As everything coming after the initial version handshake proceeds +## encrypted, Bro cannot further analyze SSH sessions. +event ssh_server_version%(c: connection, version: string%); + diff --git a/src/analyzer/protocol/ssl/CMakeLists.txt b/src/analyzer/protocol/ssl/CMakeLists.txt new file mode 100644 index 0000000000..f1838e5f3b --- /dev/null +++ b/src/analyzer/protocol/ssl/CMakeLists.txt @@ -0,0 +1,11 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SSL) +bro_plugin_cc(SSL.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_pac(ssl.pac ssl-analyzer.pac ssl-protocol.pac ssl-defs.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/ssl/Plugin.cc b/src/analyzer/protocol/ssl/Plugin.cc new file mode 100644 index 0000000000..c63be864f8 --- /dev/null +++ b/src/analyzer/protocol/ssl/Plugin.cc @@ -0,0 +1,11 @@ + +#include "plugin/Plugin.h" + +#include "SSL.h" + +BRO_PLUGIN_BEGIN(Bro, SSL) + BRO_PLUGIN_DESCRIPTION("SSL analyzer"); + BRO_PLUGIN_ANALYZER("SSL", ssl::SSL_Analyzer); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc similarity index 72% rename from src/SSL.cc rename to src/analyzer/protocol/ssl/SSL.cc index 4658bbbc16..6cd2fa59f8 100644 --- a/src/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -1,10 +1,15 @@ + #include "SSL.h" -#include "TCP_Reassembler.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" #include "Reporter.h" #include "util.h" +#include "events.bif.h" + +using namespace analyzer::ssl; + SSL_Analyzer::SSL_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c) +: tcp::TCP_ApplicationAnalyzer("SSL", c) { interp = new binpac::SSL::SSL_Conn(this); had_gap = false; @@ -17,7 +22,7 @@ SSL_Analyzer::~SSL_Analyzer() void SSL_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); interp->FlowEOF(true); interp->FlowEOF(false); @@ -25,13 +30,13 @@ void SSL_Analyzer::Done() void SSL_Analyzer::EndpointEOF(bool is_orig) { - TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); interp->FlowEOF(is_orig); } void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); if ( TCP()->IsPartial() ) @@ -54,7 +59,7 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) void SSL_Analyzer::Undelivered(int seq, int len, bool orig) { - TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); had_gap = true; interp->NewGap(orig, len); } diff --git a/src/SSL.h b/src/analyzer/protocol/ssl/SSL.h similarity index 61% rename from src/SSL.h rename to src/analyzer/protocol/ssl/SSL.h index d0ef164877..6423d1b155 100644 --- a/src/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -1,10 +1,14 @@ -#ifndef ssl_h -#define ssl_h +#ifndef ANALYZER_PROTOCOL_SSL_SSL_H +#define ANALYZER_PROTOCOL_SSL_SSL_H -#include "TCP.h" +#include "events.bif.h" + +#include "analyzer/protocol/tcp/TCP.h" #include "ssl_pac.h" -class SSL_Analyzer : public TCP_ApplicationAnalyzer { +namespace analyzer { namespace ssl { + +class SSL_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SSL_Analyzer(Connection* conn); virtual ~SSL_Analyzer(); @@ -14,10 +18,10 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void Undelivered(int seq, int len, bool orig); - // Overriden from TCP_ApplicationAnalyzer. + // Overriden from tcp::TCP_ApplicationAnalyzer. virtual void EndpointEOF(bool is_orig); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SSL_Analyzer(conn); } static bool Available() @@ -33,4 +37,6 @@ protected: }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif new file mode 100644 index 0000000000..3d0c7e9d6a --- /dev/null +++ b/src/analyzer/protocol/ssl/events.bif @@ -0,0 +1,195 @@ +## Generated for an SSL/TLS client's initial *hello* message. SSL/TLS sessions +## start with an unencrypted handshake, and Bro extracts as much information out +## of that as it can. This event provides access to the initial information +## sent by the client. +## +## See `Wikipedia `__ for +## more information about the SSL/TLS protocol. +## +## c: The connection. +## +## version: The protocol version as extracted from the client's message. The +## values are standardized as part of the SSL/TLS protocol. The +## :bro:id:`SSL::version_strings` table maps them to descriptive names. +## +## possible_ts: The current time as sent by the client. Note that SSL/TLS does +## not require clocks to be set correctly, so treat with care. +## +## session_id: The session ID sent by the client (if any). +## +## ciphers: The list of ciphers the client offered to use. The values are +## standardized as part of the SSL/TLS protocol. The +## :bro:id:`SSL::cipher_desc` table maps them to descriptive names. +## +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate x509_error x509_extension +event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%); + +## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions +## start with an unencrypted handshake, and Bro extracts as much information out +## of that as it can. This event provides access to the initial information +## sent by the client. +## +## See `Wikipedia `__ for +## more information about the SSL/TLS protocol. +## +## c: The connection. +## +## version: The protocol version as extracted from the server's message. +## The values are standardized as part of the SSL/TLS protocol. The +## :bro:id:`SSL::version_strings` table maps them to descriptive names. +## +## possible_ts: The current time as sent by the server. Note that SSL/TLS does +## not require clocks to be set correctly, so treat with care. +## +## session_id: The session ID as sent back by the server (if any). +## +## cipher: The cipher chosen by the server. The values are standardized as part +## of the SSL/TLS protocol. The :bro:id:`SSL::cipher_desc` table maps +## them to descriptive names. +## +## comp_method: The compression method chosen by the client. The values are +## standardized as part of the SSL/TLS protocol. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension +## ssl_session_ticket_handshake x509_certificate x509_error x509_extension +event ssl_server_hello%(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count%); + +## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS +## sessions start with an unencrypted handshake, and Bro extracts as much +## information out of that as it can. This event provides access to any +## extensions either side sends as part of an extended *hello* message. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## code: The numerical code of the extension. The values are standardized as +## part of the SSL/TLS protocol. The :bro:id:`SSL::extensions` table maps +## them to descriptive names. +## +## val: The raw extension value that was sent in the message. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake x509_certificate x509_error x509_extension +event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); + +## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with +## an unencrypted handshake, and Bro extracts as much information out of that +## as it can. This event signals the time when an SSL/TLS has finished the +## handshake and its endpoints consider it as fully established. Typically, +## everything from now on will be encrypted. +## +## See `Wikipedia `__ for +## more information about the SSL/TLS protocol. +## +## c: The connection. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate x509_error x509_extension +event ssl_established%(c: connection%); + +## Generated for SSL/TLS alert records. SSL/TLS sessions start with an +## unencrypted handshake, and Bro extracts as much information out of that as +## it can. If during that handshake, an endpoint encounters a fatal error, it +## sends an *alert* record, that in turn triggers this event. After an *alert*, +## any endpoint may close the connection immediately. +## +## See `Wikipedia `__ for +## more information about the SSL/TLS protocol. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## level: The severity level, as sent in the *alert*. The values are defined as +## part of the SSL/TLS protocol. +## +## desc: A numerical value identifying the cause of the *alert*. The values are +## defined as part of the SSL/TLS protocol. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate x509_error x509_extension +event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); + +## Generated for SSL/TLS handshake messages that are a part of the +## stateless-server session resumption mechanism. SSL/TLS sessions start with +## an unencrypted handshake, and Bro extracts as much information out of that +## as it can. This event is raised when an SSL/TLS server passes a session +## ticket to the client that can later be used for resuming the session. The +## mechanism is described in :rfc:`4507` +## +## See `Wikipedia `__ for +## more information about the SSL/TLS protocol. +## +## c: The connection. +## +## ticket_lifetime_hint: A hint from the server about how long the ticket +## should be stored by the client. +## +## ticket: The raw ticket data. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## x509_certificate x509_error x509_extension ssl_alert +event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); + +## Generated for X509 certificates seen in SSL/TLS connections. During the +## initial SSL/TLS handshake, certificates are exchanged in the clear. Bro +## raises this event for each certificate seen (including both a site's primary +## cert, and further certs sent as part of the validation chain). +## +## See `Wikipedia `__ for more information +## about the X.509 format. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## cert: The parsed certificate. +## +## chain_idx: The index in the validation chain that this cert has. Index zero +## indicates an endpoint's primary cert, while higher indices +## indicate the place in the validation chain (which has length +## *chain_len*). +## +## chain_len: The total length of the validation chain that this cert is part +## of. +## +## der_cert: The complete cert encoded in `DER +## `__ +## format. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension +## ssl_server_hello x509_error x509_extension x509_verify +event x509_certificate%(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string%); + +## Generated for X509 extensions seen in a certificate. +## +## See `Wikipedia `__ for more information +## about the X.509 format. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## data: The raw data associated with the extension. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension +## ssl_server_hello x509_certificate x509_error x509_verify +event x509_extension%(c: connection, is_orig: bool, data: string%); + +## Generated when errors occur during parsing an X509 certificate. +## +## See `Wikipedia `__ for more information +## about the X.509 format. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## err: An error code describing what went wrong. :bro:id:`SSL::x509_errors` +## maps error codes to a textual description. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension +## ssl_server_hello x509_certificate x509_extension x509_err2str x509_verify +event x509_error%(c: connection, is_orig: bool, err: count%); diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif new file mode 100644 index 0000000000..f2d4861007 --- /dev/null +++ b/src/analyzer/protocol/ssl/functions.bif @@ -0,0 +1,132 @@ + +%%{ +#include +#include +#include + +// This is the indexed map of X509 certificate stores. +static map x509_stores; + +// ### NOTE: while d2i_X509 does not take a const u_char** pointer, +// here we assume d2i_X509 does not write to , so it is safe to +// convert data to a non-const pointer. Could some X509 guru verify +// this? + +X509* d2i_X509_(X509** px, const u_char** in, int len) + { +#ifdef OPENSSL_D2I_X509_USES_CONST_CHAR + return d2i_X509(px, in, len); +#else + return d2i_X509(px, (u_char**)in, len); +#endif + } + +%%} + + +## Verifies a certificate. +## +## der_cert: The X.509 certificate in DER format. +## +## cert_stack: Specifies a certificate chain to validate against, with index 0 +## typically being the root CA. Bro uses the Mozilla root CA list +## by default. +## +## root_certs: A list of additional root certificates that extends +## *cert_stack*. +## +## Returns: A status code of the verification which can be converted into an +## ASCII string via :bro:id:`x509_err2str`. +## +## .. bro:see:: x509_err2str +function x509_verify%(der_cert: string, cert_stack: string_vec, root_certs: table_string_of_string%): count + %{ + X509_STORE* ctx = 0; + int i = 0; + + // If this certificate store was built previously, just reuse the old one. + if ( x509_stores.count(root_certs) > 0 ) + ctx = x509_stores[root_certs]; + + if ( ! ctx ) // lookup to see if we have this one built already! + { + ctx = X509_STORE_new(); + TableVal* root_certs2 = root_certs->AsTableVal(); + ListVal* idxs = root_certs2->ConvertToPureList(); + + // Build the validation store + for ( i = 0; i < idxs->Length(); ++i ) + { + Val* key = idxs->Index(i); + StringVal *sv = root_certs2->Lookup(key)->AsStringVal(); + const uint8* data = sv->Bytes(); + X509* x = d2i_X509_(NULL, &data, sv->Len()); + if ( ! x ) + { + builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); + return new Val((uint64) ERR_get_error(), TYPE_COUNT); + } + X509_STORE_add_cert(ctx, x); + } + delete idxs; + + // Save the newly constructed certificate store into the cacheing map. + x509_stores[root_certs] = ctx; + } + + const uint8 *cert_data = der_cert->Bytes(); + X509* cert = d2i_X509_(NULL, &cert_data, der_cert->Len()); + if ( ! cert ) + { + builtin_error(fmt("Certificate error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); + return new Val((uint64) ERR_get_error(), TYPE_COUNT); + } + + STACK_OF(X509)* untrusted_certs = sk_X509_new_null(); + if ( ! untrusted_certs ) + { + builtin_error(fmt("Untrusted certificate stack initialization error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); + return new Val((uint64) ERR_get_error(), TYPE_COUNT); + } + + VectorVal *cert_stack_vec = cert_stack->AsVectorVal(); + for ( i = 0; i < (int) cert_stack_vec->Size(); ++i ) + { + StringVal *sv = cert_stack_vec->Lookup(i)->AsStringVal(); + const uint8 *data = sv->Bytes(); + X509* x = d2i_X509_(NULL, &data, sv->Len()); + if ( ! x ) + { + X509_free(cert); + sk_X509_pop_free(untrusted_certs, X509_free); + builtin_error(fmt("Untrusted certificate stack creation error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); + return new Val((uint64) ERR_get_error(), TYPE_COUNT); + } + sk_X509_push(untrusted_certs, x); + } + + X509_STORE_CTX csc; + X509_STORE_CTX_init(&csc, ctx, cert, untrusted_certs); + X509_STORE_CTX_set_time(&csc, 0, (time_t) network_time); + + int result = X509_verify_cert(&csc); + X509_STORE_CTX_cleanup(&csc); + + if ( untrusted_certs ) + sk_X509_pop_free(untrusted_certs, X509_free); + X509_free(cert); + + return new Val((uint64) csc.error, TYPE_COUNT); + %} + +## Converts a certificate verification error code into an ASCII string. +## +## err_num: The error code. +## +## Returns: A string representation of *err_num*. +## +## .. bro:see:: x509_verify +function x509_err2str%(err_num: count%): string + %{ + return new StringVal(X509_verify_cert_error_string(err_num)); + %} diff --git a/src/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac similarity index 100% rename from src/ssl-analyzer.pac rename to src/analyzer/protocol/ssl/ssl-analyzer.pac diff --git a/src/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac similarity index 95% rename from src/ssl-defs.pac rename to src/analyzer/protocol/ssl/ssl-defs.pac index 4f715bbddd..c35fc56e85 100644 --- a/src/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -3,6 +3,8 @@ %extern{ #include using std::string; + +#include "events.bif.h" %} enum ContentType { diff --git a/src/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac similarity index 99% rename from src/ssl-protocol.pac rename to src/analyzer/protocol/ssl/ssl-protocol.pac index 0019478518..b35d07f18b 100644 --- a/src/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -693,7 +693,7 @@ refine connection SSL_Conn += { head2 : uint8) : int %{ if ( head0 >= 20 && head0 <= 23 && - head1 == 0x03 && head2 < 0x03 ) + head1 == 0x03 && head2 <= 0x03 ) // This is most probably SSL version 3. return (head1 << 8) | head2; diff --git a/src/ssl.pac b/src/analyzer/protocol/ssl/ssl.pac similarity index 94% rename from src/ssl.pac rename to src/analyzer/protocol/ssl/ssl.pac index 25aed7a66f..4a32227088 100644 --- a/src/ssl.pac +++ b/src/analyzer/protocol/ssl/ssl.pac @@ -8,6 +8,10 @@ %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer SSL withcontext { connection: SSL_Conn; flow: SSL_Flow; diff --git a/src/analyzer/protocol/stepping-stone/CMakeLists.txt b/src/analyzer/protocol/stepping-stone/CMakeLists.txt new file mode 100644 index 0000000000..042f5bc858 --- /dev/null +++ b/src/analyzer/protocol/stepping-stone/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SteppingStone) +bro_plugin_cc(SteppingStone.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/stepping-stone/Plugin.cc b/src/analyzer/protocol/stepping-stone/Plugin.cc new file mode 100644 index 0000000000..129b95fb25 --- /dev/null +++ b/src/analyzer/protocol/stepping-stone/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "SteppingStone.h" + +BRO_PLUGIN_BEGIN(Bro, SteppingStone) + BRO_PLUGIN_DESCRIPTION("Stepping stone analyzer (deprecated)"); + BRO_PLUGIN_ANALYZER("SteppingStone", stepping_stone::SteppingStone_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/SteppingStone.cc b/src/analyzer/protocol/stepping-stone/SteppingStone.cc similarity index 90% rename from src/SteppingStone.cc rename to src/analyzer/protocol/stepping-stone/SteppingStone.cc index 32850d82c6..09a7444213 100644 --- a/src/SteppingStone.cc +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.cc @@ -7,11 +7,15 @@ #include "Event.h" #include "Net.h" #include "NetVar.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "SteppingStone.h" #include "util.h" -SteppingStoneEndpoint::SteppingStoneEndpoint(TCP_Endpoint* e, SteppingStoneManager* m) +#include "events.bif.h" + +using namespace analyzer::stepping_stone; + +SteppingStoneEndpoint::SteppingStoneEndpoint(tcp::TCP_Endpoint* e, SteppingStoneManager* m) { endp = e; stp_max_top_seq = 0; @@ -157,7 +161,7 @@ void SteppingStoneEndpoint::CreateEndpEvent(int is_orig) } SteppingStone_Analyzer::SteppingStone_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::SteppingStone, c) +: tcp::TCP_ApplicationAnalyzer("STEPPINGSTONE", c) { stp_manager = sessions->GetSTPManager(); @@ -167,7 +171,7 @@ SteppingStone_Analyzer::SteppingStone_Analyzer(Connection* c) void SteppingStone_Analyzer::Init() { - TCP_ApplicationAnalyzer::Init(); + tcp::TCP_ApplicationAnalyzer::Init(); assert(TCP()); orig_endp = new SteppingStoneEndpoint(TCP()->Orig(), stp_manager); @@ -178,7 +182,7 @@ void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) { - TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, + tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); if ( is_orig ) @@ -190,7 +194,7 @@ void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data, void SteppingStone_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) { - TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig); if ( is_orig ) { @@ -209,7 +213,7 @@ void SteppingStone_Analyzer::DeliverStream(int len, const u_char* data, void SteppingStone_Analyzer::Done() { - TCP_ApplicationAnalyzer::Done(); + tcp::TCP_ApplicationAnalyzer::Done(); orig_endp->Done(); resp_endp->Done(); diff --git a/src/SteppingStone.h b/src/analyzer/protocol/stepping-stone/SteppingStone.h similarity index 82% rename from src/SteppingStone.h rename to src/analyzer/protocol/stepping-stone/SteppingStone.h index a47b268c83..1471c08a3b 100644 --- a/src/SteppingStone.h +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.h @@ -1,13 +1,15 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef steppingstone_h -#define steppingstone_h +#ifndef ANALYZER_PROTOCOL_STEPPING_STONE_STEPPINGSTONE_H +#define ANALYZER_PROTOCOL_STEPPING_STONE_STEPPINGSTONE_H #include "Queue.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" class NetSessions; +namespace analyzer { namespace stepping_stone { + class SteppingStoneEndpoint; class SteppingStoneManager; @@ -16,7 +18,7 @@ declare(PDict,SteppingStoneEndpoint); class SteppingStoneEndpoint : public BroObj { public: - SteppingStoneEndpoint(TCP_Endpoint* e, SteppingStoneManager* m); + SteppingStoneEndpoint(tcp::TCP_Endpoint* e, SteppingStoneManager* m); ~SteppingStoneEndpoint(); void Done(); @@ -27,7 +29,7 @@ protected: void Event(EventHandlerPtr f, int id1, int id2 = -1); void CreateEndpEvent(int is_orig); - TCP_Endpoint* endp; + tcp::TCP_Endpoint* endp; int stp_max_top_seq; double stp_last_time; double stp_resume_time; @@ -43,7 +45,7 @@ protected: PDict(SteppingStoneEndpoint) stp_outbound_endps; }; -class SteppingStone_Analyzer : public TCP_ApplicationAnalyzer { +class SteppingStone_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SteppingStone_Analyzer(Connection* c); virtual ~SteppingStone_Analyzer() {}; @@ -51,11 +53,9 @@ public: virtual void Init(); virtual void Done(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SteppingStone_Analyzer(conn); } - static bool Available() { return stp_correlate_pair; } - protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassebmling. @@ -87,4 +87,6 @@ protected: int endp_cnt; }; +} } // namespace analyzer::* + #endif /* steppingstone_h */ diff --git a/src/analyzer/protocol/stepping-stone/events.bif b/src/analyzer/protocol/stepping-stone/events.bif new file mode 100644 index 0000000000..8d578eba64 --- /dev/null +++ b/src/analyzer/protocol/stepping-stone/events.bif @@ -0,0 +1,17 @@ +## Deprecated. Will be removed. +event stp_create_endp%(c: connection, e: int, is_orig: bool%); + +# ##### Internal events. Not further documented. + +## Event internal to the stepping stone detector. +event stp_resume_endp%(e: int%); + +## Event internal to the stepping stone detector. +event stp_correlate_pair%(e1: int, e2: int%); + +## Event internal to the stepping stone detector. +event stp_remove_pair%(e1: int, e2: int%); + +## Event internal to the stepping stone detector. +event stp_remove_endp%(e: int%); + diff --git a/src/analyzer/protocol/syslog/CMakeLists.txt b/src/analyzer/protocol/syslog/CMakeLists.txt new file mode 100644 index 0000000000..5366f94642 --- /dev/null +++ b/src/analyzer/protocol/syslog/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Syslog) +bro_plugin_cc(Syslog.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_pac(syslog.pac syslog-analyzer.pac syslog-protocol.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/syslog/Plugin.cc b/src/analyzer/protocol/syslog/Plugin.cc new file mode 100644 index 0000000000..67abaaf970 --- /dev/null +++ b/src/analyzer/protocol/syslog/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Syslog.h" + +BRO_PLUGIN_BEGIN(Bro, Syslog) + BRO_PLUGIN_DESCRIPTION("Syslog analyzer (UDP-only currently)"); + BRO_PLUGIN_ANALYZER("Syslog", syslog::Syslog_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/Syslog-binpac.cc b/src/analyzer/protocol/syslog/Syslog.cc similarity index 50% rename from src/Syslog-binpac.cc rename to src/analyzer/protocol/syslog/Syslog.cc index c8697d0f3f..2b783afc64 100644 --- a/src/Syslog-binpac.cc +++ b/src/analyzer/protocol/syslog/Syslog.cc @@ -1,21 +1,26 @@ -#include "Syslog-binpac.h" -#include "TCP_Reassembler.h" -Syslog_Analyzer_binpac::Syslog_Analyzer_binpac(Connection* conn) -: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) +#include "Syslog.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" + +using namespace analyzer::syslog; + +Syslog_Analyzer::Syslog_Analyzer(Connection* conn) +: Analyzer("SYSLOG", conn) { interp = new binpac::Syslog::Syslog_Conn(this); did_session_done = 0; - //ADD_ANALYZER_TIMER(&Syslog_Analyzer_binpac::ExpireTimer, + //ADD_ANALYZER_TIMER(&Syslog_Analyzer::ExpireTimer, // network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); } -Syslog_Analyzer_binpac::~Syslog_Analyzer_binpac() +Syslog_Analyzer::~Syslog_Analyzer() { delete interp; } -void Syslog_Analyzer_binpac::Done() +void Syslog_Analyzer::Done() { Analyzer::Done(); @@ -23,13 +28,13 @@ void Syslog_Analyzer_binpac::Done() Event(udp_session_done); } -void Syslog_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void Syslog_Analyzer::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 Syslog_Analyzer_binpac::ExpireTimer(double t) +//void Syslog_Analyzer::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, @@ -40,39 +45,39 @@ void Syslog_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool ori // sessions->Remove(Conn()); // } // else -// ADD_ANALYZER_TIMER(&Syslog_Analyzer_binpac::ExpireTimer, +// ADD_ANALYZER_TIMER(&Syslog_Analyzer::ExpireTimer, // t + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); // } -//Syslog_TCP_Analyzer_binpac::Syslog_TCP_Analyzer_binpac(Connection* conn) -//: TCP_ApplicationAnalyzer(AnalyzerTag::Syslog_TCP_BINPAC, conn) +//Syslog_tcp::TCP_Analyzer::Syslog_tcp::TCP_Analyzer(Connection* conn) +//: tcp::TCP_ApplicationAnalyzer(conn) // { // interp = new binpac::Syslog_on_TCP::Syslog_TCP_Conn(this); // } -//Syslog_TCP_Analyzer_binpac::~Syslog_TCP_Analyzer_binpac() +//Syslog_tcp::TCP_Analyzer::~Syslog_tcp::TCP_Analyzer() // { // delete interp; // } -//void Syslog_TCP_Analyzer_binpac::Done() +//void Syslog_tcp::TCP_Analyzer::Done() // { -// TCP_ApplicationAnalyzer::Done(); +// tcp::TCP_ApplicationAnalyzer::Done(); // // interp->FlowEOF(true); // interp->FlowEOF(false); // } -//void Syslog_TCP_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) +//void Syslog_tcp::TCP_Analyzer::EndpointEOF(tcp::TCP_Reassembler* endp) // { -// TCP_ApplicationAnalyzer::EndpointEOF(endp); +// tcp::TCP_ApplicationAnalyzer::EndpointEOF(endp); // interp->FlowEOF(endp->IsOrig()); // } -//void Syslog_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data, +//void Syslog_tcp::TCP_Analyzer::DeliverStream(int len, const u_char* data, // bool orig) // { -// TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); +// tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); // // assert(TCP()); // @@ -83,8 +88,8 @@ void Syslog_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool ori // interp->NewData(orig, data, data + len); // } -//void Syslog_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig) +//void Syslog_tcp::TCP_Analyzer::Undelivered(int seq, int len, bool orig) // { -// TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); +// tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); // interp->NewGap(orig, len); // } diff --git a/src/analyzer/protocol/syslog/Syslog.h b/src/analyzer/protocol/syslog/Syslog.h new file mode 100644 index 0000000000..355863e36e --- /dev/null +++ b/src/analyzer/protocol/syslog/Syslog.h @@ -0,0 +1,53 @@ + +#ifndef ANALYZER_PROTOCOL_SYSLOG_SYSLOG_H +#define ANALYZER_PROTOCOL_SYSLOG_SYSLOG_H + +#include "analyzer/protocol/udp/UDP.h" +#include "analyzer/protocol/tcp/TCP.h" + +#include "syslog_pac.h" + +namespace analyzer { namespace syslog { + +class Syslog_Analyzer : public analyzer::Analyzer { +public: + Syslog_Analyzer(Connection* conn); + virtual ~Syslog_Analyzer(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new Syslog_Analyzer(conn); } + +protected: + void ExpireTimer(double t); + + int did_session_done; + + binpac::Syslog::Syslog_Conn* interp; +}; + +// #include "Syslog_tcp_pac.h" +// +//class Syslog_tcp::TCP_Analyzer : public tcp::TCP_ApplicationAnalyzer { +//public: +// Syslog_tcp::TCP_Analyzer(Connection* conn); +// virtual ~Syslog_tcp::TCP_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(tcp::TCP_Reassembler* endp); +// +// static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) +// { return new Syslog_tcp::TCP_Analyzer(conn); } +// +//protected: +// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp; +//}; +// +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/syslog/events.bif b/src/analyzer/protocol/syslog/events.bif new file mode 100644 index 0000000000..f82adc7e69 --- /dev/null +++ b/src/analyzer/protocol/syslog/events.bif @@ -0,0 +1,17 @@ + +## Generated for monitored Syslog messages. +## +## See `Wikipedia `__ for more +## information about the Syslog protocol. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## facility: The "facility" included in the message. +## +## severity: The "severity" included in the message. +## +## msg: The message logged. +## +## .. note:: Bro currently parses only UDP syslog traffic. Support for TCP +## syslog will be added soon. +event syslog_message%(c: connection, facility: count, severity: count, msg: string%); diff --git a/src/syslog-analyzer.pac b/src/analyzer/protocol/syslog/syslog-analyzer.pac similarity index 100% rename from src/syslog-analyzer.pac rename to src/analyzer/protocol/syslog/syslog-analyzer.pac diff --git a/src/syslog-protocol.pac b/src/analyzer/protocol/syslog/syslog-protocol.pac similarity index 100% rename from src/syslog-protocol.pac rename to src/analyzer/protocol/syslog/syslog-protocol.pac diff --git a/src/syslog.pac b/src/analyzer/protocol/syslog/syslog.pac similarity index 82% rename from src/syslog.pac rename to src/analyzer/protocol/syslog/syslog.pac index 3c0ecfb10d..2c1fdd10d0 100644 --- a/src/syslog.pac +++ b/src/analyzer/protocol/syslog/syslog.pac @@ -1,6 +1,11 @@ + %include binpac.pac %include bro.pac +%extern{ +#include "events.bif.h" +%} + analyzer Syslog withcontext { connection: Syslog_Conn; flow: Syslog_Flow; diff --git a/src/analyzer/protocol/tcp/CMakeLists.txt b/src/analyzer/protocol/tcp/CMakeLists.txt new file mode 100644 index 0000000000..d4b2dc3eab --- /dev/null +++ b/src/analyzer/protocol/tcp/CMakeLists.txt @@ -0,0 +1,10 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro TCP) +bro_plugin_cc(TCP.cc TCP_Endpoint.cc TCP_Reassembler.cc ContentLine.cc Stats.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) +bro_plugin_end() diff --git a/src/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc similarity index 96% rename from src/ContentLine.cc rename to src/analyzer/protocol/tcp/ContentLine.cc index 5601694e1d..2a810c5dd1 100644 --- a/src/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -1,17 +1,20 @@ #include #include "ContentLine.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" + +#include "events.bif.h" + +using namespace analyzer::tcp; ContentLine_Analyzer::ContentLine_Analyzer(Connection* conn, bool orig) -: TCP_SupportAnalyzer(AnalyzerTag::ContentLine, conn, orig) +: TCP_SupportAnalyzer("CONTENTLINE", conn, orig) { InitState(); } -ContentLine_Analyzer::ContentLine_Analyzer(AnalyzerTag::Tag tag, - Connection* conn, bool orig) -: TCP_SupportAnalyzer(tag, conn, orig) +ContentLine_Analyzer::ContentLine_Analyzer(const char* name, Connection* conn, bool orig) +: TCP_SupportAnalyzer(name, conn, orig) { InitState(); } diff --git a/src/ContentLine.h b/src/analyzer/protocol/tcp/ContentLine.h similarity index 91% rename from src/ContentLine.h rename to src/analyzer/protocol/tcp/ContentLine.h index 5e9f01945f..ecc1347984 100644 --- a/src/ContentLine.h +++ b/src/analyzer/protocol/tcp/ContentLine.h @@ -1,9 +1,11 @@ // Support-analyzer to split a reassembled stream into lines. -#ifndef CONTENTLINE_H -#define CONTENTLINE_H +#ifndef ANALYZER_PROTOCOL_TCP_CONTENTLINE_H +#define ANALYZER_PROTOCOL_TCP_CONTENTLINE_H -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" + +namespace analyzer { namespace tcp { #define CR_as_EOL 1 #define LF_as_EOL 2 @@ -55,7 +57,7 @@ public: { return seq + length <= seq_to_skip; } protected: - ContentLine_Analyzer(AnalyzerTag::Tag tag, Connection* conn, bool orig); + ContentLine_Analyzer(const char* name, Connection* conn, bool orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void Undelivered(int seq, int len, bool orig); @@ -104,4 +106,6 @@ protected: unsigned int skip_partial:1; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/tcp/Plugin.cc b/src/analyzer/protocol/tcp/Plugin.cc new file mode 100644 index 0000000000..6132b6f386 --- /dev/null +++ b/src/analyzer/protocol/tcp/Plugin.cc @@ -0,0 +1,14 @@ + +#include "plugin/Plugin.h" + +#include "TCP.h" + +BRO_PLUGIN_BEGIN(Bro, TCP) + BRO_PLUGIN_DESCRIPTION("TCP analyzer"); + BRO_PLUGIN_ANALYZER("TCP", tcp::TCP_Analyzer); + BRO_PLUGIN_ANALYZER("TCPStats", tcp::TCPStats_Analyzer); + BRO_PLUGIN_SUPPORT_ANALYZER("ContentLine"); + BRO_PLUGIN_SUPPORT_ANALYZER("Contents"); + BRO_PLUGIN_BIF_FILE(events); + BRO_PLUGIN_BIF_FILE(functions); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/tcp/Stats.cc b/src/analyzer/protocol/tcp/Stats.cc new file mode 100644 index 0000000000..b5337fa2db --- /dev/null +++ b/src/analyzer/protocol/tcp/Stats.cc @@ -0,0 +1,83 @@ + +#include "Stats.h" +#include "File.h" + +#include "events.bif.h" + +using namespace analyzer::tcp; + +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"); + } + } diff --git a/src/analyzer/protocol/tcp/Stats.h b/src/analyzer/protocol/tcp/Stats.h new file mode 100644 index 0000000000..721d898d95 --- /dev/null +++ b/src/analyzer/protocol/tcp/Stats.h @@ -0,0 +1,71 @@ + +#ifndef ANALYZER_PROTOCOL_TCP_STATS_H +#define ANALYZER_PROTOCOL_TCP_STATS_H + +#include "TCP_Endpoint.h" + +namespace analyzer { namespace tcp { + +// 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]; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc similarity index 97% rename from src/TCP.cc rename to src/analyzer/protocol/tcp/TCP.cc index c291f8e76c..8f42e0f2b1 100644 --- a/src/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -3,13 +3,18 @@ #include #include "NetVar.h" -#include "PIA.h" #include "File.h" -#include "TCP.h" -#include "TCP_Reassembler.h" #include "OSFinger.h" #include "Event.h" +#include "analyzer/protocol/pia/PIA.h" +#include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "events.bif.h" + +using namespace analyzer::tcp; + namespace { // local namespace const bool DEBUG_tcp_data_sent = false; const bool DEBUG_tcp_connection_close = false; @@ -32,7 +37,7 @@ static const int ORIG = 1; static const int RESP = 2; TCP_Analyzer::TCP_Analyzer(Connection* conn) -: TransportLayerAnalyzer(AnalyzerTag::TCP, conn) +: TransportLayerAnalyzer("TCP", conn) { // Set a timer to eventually time out this connection. ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, @@ -953,7 +958,7 @@ void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) { if ( is_orig && ! (first_packet_seen & ORIG) ) { - PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); if ( pia ) pia->FirstPacket(is_orig, ip); first_packet_seen |= ORIG; @@ -961,7 +966,7 @@ void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) if ( ! is_orig && ! (first_packet_seen & RESP) ) { - PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); if ( pia ) pia->FirstPacket(is_orig, ip); first_packet_seen |= RESP; @@ -1534,12 +1539,10 @@ void TCP_Analyzer::DeleteTimer(double /* t */) sessions->Remove(Conn()); } - -// The following need to be consistent with bro.init. -#define CONTENTS_NONE 0 -#define CONTENTS_ORIG 1 -#define CONTENTS_RESP 2 -#define CONTENTS_BOTH 3 +void TCP_Analyzer::ConnDeleteTimer(double t) + { + Conn()->DeleteTimer(t); + } void TCP_Analyzer::SetContentsFile(unsigned int direction, BroFile* f) { @@ -1830,7 +1833,7 @@ void TCP_ApplicationAnalyzer::Init() { Analyzer::Init(); - if ( Parent()->GetTag() == AnalyzerTag::TCP ) + if ( Parent()->IsAnalyzer("TCP") ) SetTCP(static_cast(Parent())); } @@ -1853,7 +1856,7 @@ void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); - DBG_LOG(DBG_DPD, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } @@ -1866,7 +1869,7 @@ void TCP_ApplicationAnalyzer::SetEnv(bool /* is_orig */, char* name, char* val) void TCP_ApplicationAnalyzer::EndpointEOF(bool is_orig) { - SupportAnalyzer* sa = is_orig ? orig_supporters : resp_supporters; + analyzer::SupportAnalyzer* sa = is_orig ? orig_supporters : resp_supporters; for ( ; sa; sa = sa->Sibling() ) static_cast(sa)->EndpointEOF(is_orig); } @@ -1874,7 +1877,7 @@ void TCP_ApplicationAnalyzer::EndpointEOF(bool is_orig) void TCP_ApplicationAnalyzer::ConnectionClosed(TCP_Endpoint* endpoint, TCP_Endpoint* peer, int gen_event) { - SupportAnalyzer* sa = + analyzer::SupportAnalyzer* sa = endpoint->IsOrig() ? orig_supporters : resp_supporters; for ( ; sa; sa = sa->Sibling() ) @@ -1884,30 +1887,30 @@ void TCP_ApplicationAnalyzer::ConnectionClosed(TCP_Endpoint* endpoint, void TCP_ApplicationAnalyzer::ConnectionFinished(int half_finished) { - for ( SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) static_cast(sa) ->ConnectionFinished(half_finished); - for ( SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) static_cast(sa) ->ConnectionFinished(half_finished); } void TCP_ApplicationAnalyzer::ConnectionReset() { - for ( SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) static_cast(sa)->ConnectionReset(); - for ( SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) static_cast(sa)->ConnectionReset(); } void TCP_ApplicationAnalyzer::PacketWithRST() { - for ( SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = orig_supporters; sa; sa = sa->Sibling() ) static_cast(sa)->PacketWithRST(); - for ( SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) + for ( analyzer::SupportAnalyzer* sa = resp_supporters; sa; sa = sa->Sibling() ) static_cast(sa)->PacketWithRST(); } @@ -2043,7 +2046,7 @@ RecordVal* TCPStats_Endpoint::BuildStats() } TCPStats_Analyzer::TCPStats_Analyzer(Connection* c) -: TCP_ApplicationAnalyzer(AnalyzerTag::TCPStats, c) +: TCP_ApplicationAnalyzer("TCPSTATS", c) { } diff --git a/src/TCP.h b/src/analyzer/protocol/tcp/TCP.h similarity index 89% rename from src/TCP.h rename to src/analyzer/protocol/tcp/TCP.h index 635fda7960..b2649b4ab8 100644 --- a/src/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -1,19 +1,25 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef TCP_H -#define TCP_H +#ifndef ANALYZER_PROTOCOL_TCP_TCP_H +#define ANALYZER_PROTOCOL_TCP_TCP_H -#include "Analyzer.h" -#include "TCP.h" +#include "analyzer/Analyzer.h" +#include "analyzer/protocol/tcp/TCP.h" #include "PacketDumper.h" #include "IPAddr.h" +#include "TCP_Endpoint.h" +#include "Conn.h" // We define two classes here: // - TCP_Analyzer is the analyzer for the TCP protocol itself. // - TCP_ApplicationAnalyzer is an abstract base class for analyzers for a // protocol running on top of TCP. +// +namespace analyzer { namespace pia { class PIA_TCP; } }; -class PIA_TCP; +namespace analyzer { namespace tcp { + +class TCP_Endpoint; class TCP_ApplicationAnalyzer; class TCP_Reassembler; @@ -32,7 +38,7 @@ protected: u_char flags; }; -class TCP_Analyzer : public TransportLayerAnalyzer { +class TCP_Analyzer : public analyzer::TransportLayerAnalyzer { public: TCP_Analyzer(Connection* conn); virtual ~TCP_Analyzer(); @@ -41,7 +47,7 @@ public: // Add a child analyzer that will always get the packets, // independently of whether we do any reassembly. - void AddChildPacketAnalyzer(Analyzer* a) + void AddChildPacketAnalyzer(analyzer::Analyzer* a) { packet_children.push_back(a); a->SetParent(this); } // True if the connection has closed in some sense, false otherwise. @@ -85,15 +91,13 @@ public: proc_tcp_option_t proc, TCP_Analyzer* analyzer, bool is_orig, void* cookie); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new TCP_Analyzer(conn); } - static bool Available() { return true; } - protected: friend class TCP_ApplicationAnalyzer; friend class TCP_Reassembler; - friend class PIA_TCP; + friend class analyzer::pia::PIA_TCP; // Analyzer interface. virtual void Init(); @@ -213,7 +217,7 @@ protected: void ExpireTimer(double t); void ResetTimer(double t); void DeleteTimer(double t); - void ConnDeleteTimer(double t) { Conn()->DeleteTimer(t); } + void ConnDeleteTimer(double t); void EndpointEOF(TCP_Reassembler* endp); void ConnectionClosed(TCP_Endpoint* endpoint, @@ -222,7 +226,7 @@ protected: void ConnectionReset(); void PacketWithRST(); - void SetReassembler(TCP_Reassembler* rorig, TCP_Reassembler* rresp); + void SetReassembler(tcp::TCP_Reassembler* rorig, tcp::TCP_Reassembler* rresp); Val* BuildSYNPacketVal(int is_orig, const IP_Hdr* ip, const struct tcphdr* tcp); @@ -240,6 +244,7 @@ private: TCP_Endpoint* orig; TCP_Endpoint* resp; + typedef list analyzer_list; analyzer_list packet_children; unsigned int first_packet_seen: 2; @@ -259,10 +264,14 @@ private: unsigned int seen_first_ACK: 1; }; -class TCP_ApplicationAnalyzer : public Analyzer { +class TCP_ApplicationAnalyzer : public analyzer::Analyzer { public: - TCP_ApplicationAnalyzer(AnalyzerTag::Tag tag, Connection* conn) - : Analyzer(tag, conn) + TCP_ApplicationAnalyzer(const char* name, Connection* conn) + : Analyzer(name, conn) + { tcp = 0; } + + TCP_ApplicationAnalyzer(Connection* conn) + : Analyzer(conn) { tcp = 0; } virtual ~TCP_ApplicationAnalyzer() { } @@ -273,8 +282,7 @@ public: { return tcp ? tcp : - static_cast( - Conn()->FindAnalyzer(AnalyzerTag::TCP)); + static_cast(Conn()->FindAnalyzer("TCP")); } void SetTCP(TCP_Analyzer* arg_tcp) { tcp = arg_tcp; } @@ -308,17 +316,14 @@ public: // delete them when done with them. virtual void SetEnv(bool orig, char* name, char* val); -protected: - TCP_ApplicationAnalyzer() { }; - private: TCP_Analyzer* tcp; }; -class TCP_SupportAnalyzer : public SupportAnalyzer { +class TCP_SupportAnalyzer : public analyzer::SupportAnalyzer { public: - TCP_SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig) - : SupportAnalyzer(tag, conn, arg_orig) { } + TCP_SupportAnalyzer(const char* name, Connection* conn, bool arg_orig) + : analyzer::SupportAnalyzer(name, conn, arg_orig) { } virtual ~TCP_SupportAnalyzer() {} @@ -354,7 +359,7 @@ protected: int endian_type; }; -class TCPStats_Analyzer : public TCP_ApplicationAnalyzer { +class TCPStats_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: TCPStats_Analyzer(Connection* c); ~TCPStats_Analyzer(); @@ -362,11 +367,9 @@ public: virtual void Init(); virtual void Done(); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new TCPStats_Analyzer(conn); } - static bool Available() { return conn_stats || tcp_rexmit; } - protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen); @@ -375,4 +378,6 @@ protected: TCPStats_Endpoint* resp_stats; }; +} } // namespace analyzer::* + #endif diff --git a/src/TCP_Endpoint.cc b/src/analyzer/protocol/tcp/TCP_Endpoint.cc similarity index 98% rename from src/TCP_Endpoint.cc rename to src/analyzer/protocol/tcp/TCP_Endpoint.cc index 69c08870d9..3beafdeb8a 100644 --- a/src/TCP_Endpoint.cc +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.cc @@ -2,13 +2,17 @@ #include "Net.h" #include "NetVar.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "TCP_Reassembler.h" #include "Sessions.h" #include "Event.h" #include "File.h" #include "Val.h" +#include "events.bif.h" + +using namespace analyzer::tcp; + TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) { contents_processor = 0; diff --git a/src/TCP_Endpoint.h b/src/analyzer/protocol/tcp/TCP_Endpoint.h similarity index 96% rename from src/TCP_Endpoint.h rename to src/analyzer/protocol/tcp/TCP_Endpoint.h index 52a757b256..31e239225b 100644 --- a/src/TCP_Endpoint.h +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.h @@ -1,10 +1,18 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef tcpendpoint_h -#define tcpendpoint_h +#ifndef ANALYZER_PROTOCOL_TCP_TCP_ENDPOINT_H +#define ANALYZER_PROTOCOL_TCP_TCP_ENDPOINT_H #include "IPAddr.h" +class Connection; +class IP_Hdr; + +namespace analyzer { namespace tcp { + +class TCP_Analyzer; +class TCP_Reassembler; + typedef enum { TCP_ENDPOINT_INACTIVE, // no SYN (or other packets) seen for this side TCP_ENDPOINT_SYN_SENT, // SYN seen, but no ack @@ -16,11 +24,6 @@ typedef enum { TCP_ENDPOINT_RESET // RST seen } EndpointState; -class Connection; -class TCP_Reassembler; -class IP_Hdr; -class TCP_Analyzer; - // One endpoint of a TCP connection. class TCP_Endpoint { public: @@ -157,4 +160,6 @@ protected: #define ENDIAN_BIG 2 #define ENDIAN_CONFUSED 3 +} } // namespace analyzer::* + #endif diff --git a/src/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc similarity index 98% rename from src/TCP_Reassembler.cc rename to src/analyzer/protocol/tcp/TCP_Reassembler.cc index eb2709373c..949be9f599 100644 --- a/src/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -1,13 +1,17 @@ #include -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include "TCP_Reassembler.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" #include "TCP_Endpoint.h" // Only needed for gap_report events. #include "Event.h" +#include "events.bif.h" + +using namespace analyzer::tcp; + // Note, sequence numbers are relative. I.e., they start with 1. // TODO: The Reassembler should start using 64 bit ints for keeping track of @@ -25,7 +29,7 @@ static uint64 last_ack_bytes = 0; static uint64 last_gap_events = 0; static uint64 last_gap_bytes = 0; -TCP_Reassembler::TCP_Reassembler(Analyzer* arg_dst_analyzer, +TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer, TCP_Analyzer* arg_tcp_analyzer, TCP_Reassembler::Type arg_type, bool arg_is_orig, TCP_Endpoint* arg_endp) diff --git a/src/TCP_Reassembler.h b/src/analyzer/protocol/tcp/TCP_Reassembler.h similarity index 94% rename from src/TCP_Reassembler.h rename to src/analyzer/protocol/tcp/TCP_Reassembler.h index cb1750e2a2..8bb80a0570 100644 --- a/src/TCP_Reassembler.h +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.h @@ -1,5 +1,5 @@ -#ifndef TCP_REASSEMBLER_H -#define TCP_REASSEMBLER_H +#ifndef ANALYZER_PROTOCOL_TCP_TCP_REASSEMBLER_H +#define ANALYZER_PROTOCOL_TCP_TCP_REASSEMBLER_H #include "Reassem.h" #include "TCP_Endpoint.h" @@ -13,8 +13,10 @@ class BroFile; class Connection; + +namespace analyzer { namespace tcp { + class TCP_Analyzer; -class Analyzer; const int STOP_ON_GAP = 1; const int PUNT_ON_PARTIAL = 1; @@ -69,6 +71,8 @@ public: // Skip up to seq, as if there's a content gap. // Can be used to skip HTTP data for performance considerations. void SkipToSeq(int seq); +} } // namespace analyzer::* + #endif int DataSent(double t, int seq, int len, const u_char* data, @@ -95,6 +99,8 @@ public: #ifdef ENABLE_SEQ_TO_SKIP bool IsSkippedContents(int seq, int length) const { return seq + length <= seq_to_skip; } +} } // namespace analyzer::* + #endif private: @@ -132,4 +138,6 @@ private: bool is_orig; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/tcp/events.bif b/src/analyzer/protocol/tcp/events.bif new file mode 100644 index 0000000000..af61783ac4 --- /dev/null +++ b/src/analyzer/protocol/tcp/events.bif @@ -0,0 +1,289 @@ + +## Generated when reassembly starts for a TCP connection. This event is raised +## at the moment when Bro's TCP analyzer enables stream reassembly for a +## connection. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_partial_close +## connection_pending connection_rejected connection_reset connection_reused +## connection_state_remove connection_status_update connection_timeout +## scheduled_analyzer_applied new_connection partial_connection +event new_connection_contents%(c: connection%); + +## Generated for an unsuccessful connection attempt. This event is raised when +## an originator unsuccessfully attempted to establish a connection. +## "Unsuccessful" is defined as at least :bro:id:`tcp_attempt_delay` seconds +## having elapsed since the originator first sent a connection establishment +## packet to the destination without seeing a reply. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_established +## connection_external connection_finished connection_first_ACK +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_attempt%(c: connection%); + +## Generated when a SYN-ACK packet is seen in response to a SYN packet during +## a TCP handshake. The final ACK of the handshake in response to SYN-ACK may +## or may not occur later, one way to tell is to check the *history* field of +## :bro:type:`connection` to see if the originator sent an ACK, indicated by +## 'A' in the history string. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_external connection_finished connection_first_ACK +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_established%(c: connection%); + +## Generated for a new active TCP connection if Bro did not see the initial +## handshake. This event is raised when Bro has observed traffic from each +## endpoint, but the activity did not begin with the usual connection +## establishment. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_partial_close +## connection_pending connection_rejected connection_reset connection_reused +## connection_state_remove connection_status_update connection_timeout +## scheduled_analyzer_applied new_connection new_connection_contents +## +event partial_connection%(c: connection%); + +## Generated when a previously inactive endpoint attempts to close a TCP +## connection via a normal FIN handshake or an abort RST sequence. When the +## endpoint sent one of these packets, Bro waits +## :bro:id:`tcp_partial_close_delay` prior to generating the event, to give +## the other endpoint a chance to close the connection normally. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_partial_close%(c: connection%); + +## Generated for a TCP connection that finished normally. The event is raised +## when a regular FIN handshake from both endpoints was observed. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_first_ACK +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_finished%(c: connection%); + +## Generated when one endpoint of a TCP connection attempted to gracefully close +## the connection, but the other endpoint is in the TCP_INACTIVE state. This can +## happen due to split routing, in which Bro only sees one side of a connection. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_half_finished%(c: connection%); + +## Generated for a rejected TCP connection. This event is raised when an +## originator attempted to setup a TCP connection but the responder replied +## with a RST packet denying it. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_partial_close +## connection_pending connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +## +## c: The connection. +## +## .. note:: +## +## If the responder does not respond at all, :bro:id:`connection_attempt` is +## raised instead. If the responder initially accepts the connection but +## aborts it later, Bro first generates :bro:id:`connection_established` +## and then :bro:id:`connection_reset`. +event connection_rejected%(c: connection%); + +## Generated when an endpoint aborted a TCP connection. The event is raised +## when one endpoint of an established TCP connection aborted by sending a RST +## packet. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_partial_close +## connection_pending connection_rejected connection_reused +## connection_state_remove connection_status_update connection_timeout +## scheduled_analyzer_applied new_connection new_connection_contents +## partial_connection +event connection_reset%(c: connection%); + +## Generated for each still-open TCP connection when Bro terminates. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_first_ACK connection_half_finished connection_partial_close +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection bro_done +event connection_pending%(c: connection%); + +## Generated for a SYN packet. Bro raises this event for every SYN packet seen +## by its TCP analyzer. +## +## c: The connection. +## +## pkt: Information extracted from the SYN packet. +## +## .. bro:see:: connection_EOF connection_attempt connection_established +## connection_external connection_finished connection_first_ACK +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +## +## .. note:: +## +## This event has quite low-level semantics and can potentially be expensive +## to generate. It should only be used if one really needs the specific +## information passed into the handler via the ``pkt`` argument. If not, +## handling one of the other ``connection_*`` events is typically the +## better approach. +event connection_SYN_packet%(c: connection, pkt: SYN_packet%); + +## Generated for the first ACK packet seen for a TCP connection from +## its *originator*. +## +## c: The connection. +## +## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt +## connection_established connection_external connection_finished +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +## +## .. note:: +## +## This event has quite low-level semantics and should be used only rarely. +event connection_first_ACK%(c: connection%); + +## Generated at the end of reassembled TCP connections. The TCP reassembler +## raised the event once for each endpoint of a connection when it finished +## reassembling the corresponding side of the communication. +## +## c: The connection. +## +## is_orig: True if the event is raised for the originator side. +## +## .. bro:see:: connection_SYN_packet connection_attempt connection_established +## connection_external connection_finished connection_first_ACK +## connection_half_finished connection_partial_close connection_pending +## connection_rejected connection_reset connection_reused connection_state_remove +## connection_status_update connection_timeout scheduled_analyzer_applied +## new_connection new_connection_contents partial_connection +event connection_EOF%(c: connection, is_orig: bool%); + +## Generated for every TCP packet. This is a very low-level and expensive event +## that should be avoided when at all possible. It's usually infeasible to +## handle when processing even medium volumes of traffic in real-time. It's +## slightly better than :bro:id:`new_packet` because it affects only TCP, but +## not much. That said, if you work from a trace and want to do some +## packet-level analysis, it may come in handy. +## +## c: The connection the packet is part of. +## +## is_orig: True if the packet was sent by the connection's originator. +## +## flags: A string with the packet's TCP flags. In the string, each character +## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN; +## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH. +## +## seq: The packet's TCP sequence number. +## +## ack: The packet's ACK number. +## +## len: The length of the TCP payload, as specified in the packet header. +## +## payload: The raw TCP payload. Note that this may be shorter than *len* if +## the packet was not fully captured. +## +## .. bro:see:: new_packet packet_contents tcp_option tcp_contents tcp_rexmit +event tcp_packet%(c: connection, is_orig: bool, flags: string, seq: count, ack: count, len: count, payload: string%); + +## Generated for each option found in a TCP header. Like many of the ``tcp_*`` +## events, this is a very low-level event and potentially expensive as it may +## be raised very often. +## +## c: The connection the packet is part of. +## +## is_orig: True if the packet was sent by the connection's originator. +## +## opt: The numerical option number, as found in the TCP header. +## +## optlen: The length of the options value. +## +## .. bro:see:: tcp_packet tcp_contents tcp_rexmit +## +## .. note:: There is currently no way to get the actual option value, if any. +event tcp_option%(c: connection, is_orig: bool, opt: count, optlen: count%); + +## Generated for each chunk of reassembled TCP payload. When content delivery is +## enabled for a TCP connection (via :bro:id:`tcp_content_delivery_ports_orig`, +## :bro:id:`tcp_content_delivery_ports_resp`, +## :bro:id:`tcp_content_deliver_all_orig`, +## :bro:id:`tcp_content_deliver_all_resp`), this event is raised for each chunk +## of in-order payload reconstructed from the packet stream. Note that this +## event is potentially expensive if many connections carry significant amounts +## of data as then all that data needs to be passed on to the scripting layer. +## +## c: The connection the payload is part of. +## +## is_orig: True if the packet was sent by the connection's originator. +## +## seq: The sequence number corresponding to the first byte of the payload +## chunk. +## +## contents: The raw payload, which will be non-empty. +## +## .. bro:see:: tcp_packet tcp_option tcp_rexmit +## tcp_content_delivery_ports_orig tcp_content_delivery_ports_resp +## tcp_content_deliver_all_resp tcp_content_deliver_all_orig +## +## .. note:: +## +## The payload received by this event is the same that is also passed into +## application-layer protocol analyzers internally. Subsequent invocations of +## this event for the same connection receive non-overlapping in-order chunks +## of its TCP payload stream. It is however undefined what size each chunk +## has; while Bro passes the data on as soon as possible, specifics depend on +## network-level effects such as latency, acknowledgements, reordering, etc. +event tcp_contents%(c: connection, is_orig: bool, seq: count, contents: string%); + +## TODO. +event tcp_rexmit%(c: connection, is_orig: bool, seq: count, len: count, data_in_flight: count, window: count%); + diff --git a/src/analyzer/protocol/tcp/functions.bif b/src/analyzer/protocol/tcp/functions.bif new file mode 100644 index 0000000000..ff812b80ee --- /dev/null +++ b/src/analyzer/protocol/tcp/functions.bif @@ -0,0 +1,159 @@ + +%%{ +#include "analyzer/protocol/tcp/TCP.h" +%%} + +## Get the originator sequence number of a TCP connection. Sequence numbers +## are absolute (i.e., they reflect the values seen directly in packet headers; +## they are not relative to the beginning of the connection). +## +## cid: The connection ID. +## +## Returns: The highest sequence number sent by a connection's originator, or 0 +## if *cid* does not point to an active TCP connection. +## +## .. bro:see:: get_resp_seq +function get_orig_seq%(cid: conn_id%): count + %{ + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + return new Val(0, TYPE_COUNT); + + if ( c->ConnTransport() != TRANSPORT_TCP ) + return new Val(0, TYPE_COUNT); + + analyzer::Analyzer* tc = c->FindAnalyzer("TCP"); + if ( tc ) + return new Val(static_cast(tc)->OrigSeq(), + TYPE_COUNT); + else + { + reporter->Error("connection does not have TCP analyzer"); + return new Val(0, TYPE_COUNT); + } + %} + +## Get the responder sequence number of a TCP connection. Sequence numbers +## are absolute (i.e., they reflect the values seen directly in packet headers; +## they are not relative to the beginning of the connection). +## +## cid: The connection ID. +## +## Returns: The highest sequence number sent by a connection's responder, or 0 +## if *cid* does not point to an active TCP connection. +## +## .. bro:see:: get_orig_seq +function get_resp_seq%(cid: conn_id%): count + %{ + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + return new Val(0, TYPE_COUNT); + + if ( c->ConnTransport() != TRANSPORT_TCP ) + return new Val(0, TYPE_COUNT); + + analyzer::Analyzer* tc = c->FindAnalyzer("TCP"); + if ( tc ) + return new Val(static_cast(tc)->RespSeq(), + TYPE_COUNT); + else + { + reporter->Error("connection does not have TCP analyzer"); + return new Val(0, TYPE_COUNT); + } + %} + +## Returns statistics about TCP gaps. +## +## Returns: A record with TCP gap statistics. +## +## .. bro:see:: do_profiling +## net_stats +## resource_usage +## dump_rule_stats +## get_matcher_stats +function get_gap_summary%(%): gap_info + %{ + RecordVal* r = new RecordVal(gap_info); + r->Assign(0, new Val(tot_ack_events, TYPE_COUNT)); + r->Assign(1, new Val(tot_ack_bytes, TYPE_COUNT)); + r->Assign(2, new Val(tot_gap_events, TYPE_COUNT)); + r->Assign(3, new Val(tot_gap_bytes, TYPE_COUNT)); + + return r; + %} + +## Associates a file handle with a connection for writing TCP byte stream +## contents. +## +## cid: The connection ID. +## +## direction: Controls what sides of the connection to record. The argument can +## take one of the four values: +## +## - ``CONTENTS_NONE``: Stop recording the connection's content. +## - ``CONTENTS_ORIG``: Record the data sent by the connection +## originator (often the client). +## - ``CONTENTS_RESP``: Record the data sent by the connection +## responder (often the server). +## - ``CONTENTS_BOTH``: Record the data sent in both directions. +## Results in the two directions being +## intermixed in the file, in the order the +## data was seen by Bro. +## +## f: The file handle of the file to write the contents to. +## +## Returns: Returns false if *cid* does not point to an active connection, and +## true otherwise. +## +## .. note:: +## +## The data recorded to the file reflects the byte stream, not the +## contents of individual packets. Reordering and duplicates are +## removed. If any data is missing, the recording stops at the +## missing data; this can happen, e.g., due to an +## :bro:id:`ack_above_hole` event. +## +## .. bro:see:: get_contents_file set_record_packets +function set_contents_file%(cid: conn_id, direction: count, f: file%): bool + %{ + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + return new Val(0, TYPE_BOOL); + + c->GetRootAnalyzer()->SetContentsFile(direction, f); + return new Val(1, TYPE_BOOL); + %} + +## Returns the file handle of the contents file of a connection. +## +## cid: The connection ID. +## +## direction: Controls what sides of the connection to record. See +## :bro:id:`set_contents_file` for possible values. +## +## Returns: The :bro:type:`file` handle for the contents file of the +## connection identified by *cid*. If the connection exists +## but there is no contents file for *direction*, then the function +## generates an error and returns a file handle to ``stderr``. +## +## .. bro:see:: set_contents_file set_record_packets +function get_contents_file%(cid: conn_id, direction: count%): file + %{ + Connection* c = sessions->FindConnection(cid); + BroFile* f = c ? c->GetRootAnalyzer()->GetContentsFile(direction) : 0; + + if ( f ) + { + Ref(f); + return new Val(f); + } + + // Return some sort of error value. + if ( ! c ) + builtin_error("unknown connection id in get_contents_file()", cid); + else + builtin_error("no contents file for given direction"); + + return new Val(new BroFile(stderr, "-", "w")); + %} diff --git a/src/analyzer/protocol/teredo/CMakeLists.txt b/src/analyzer/protocol/teredo/CMakeLists.txt new file mode 100644 index 0000000000..c9c4a84db6 --- /dev/null +++ b/src/analyzer/protocol/teredo/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro Teredo) +bro_plugin_cc(Teredo.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/teredo/Plugin.cc b/src/analyzer/protocol/teredo/Plugin.cc new file mode 100644 index 0000000000..91de23b318 --- /dev/null +++ b/src/analyzer/protocol/teredo/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "Teredo.h" + +BRO_PLUGIN_BEGIN(Bro, Teredo) + BRO_PLUGIN_DESCRIPTION("Teredo analyzer"); + BRO_PLUGIN_ANALYZER("Teredo", teredo::Teredo_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/Teredo.cc b/src/analyzer/protocol/teredo/Teredo.cc similarity index 98% rename from src/Teredo.cc rename to src/analyzer/protocol/teredo/Teredo.cc index 7794d1cb3b..d81f90d840 100644 --- a/src/Teredo.cc +++ b/src/analyzer/protocol/teredo/Teredo.cc @@ -1,8 +1,14 @@ #include "Teredo.h" +#include "TunnelEncapsulation.h" +#include "Conn.h" #include "IP.h" #include "Reporter.h" +#include "events.bif.h" + +using namespace analyzer::teredo; + void Teredo_Analyzer::Done() { Analyzer::Done(); diff --git a/src/Teredo.h b/src/analyzer/protocol/teredo/Teredo.h similarity index 84% rename from src/Teredo.h rename to src/analyzer/protocol/teredo/Teredo.h index e720d3f37c..0da007187d 100644 --- a/src/Teredo.h +++ b/src/analyzer/protocol/teredo/Teredo.h @@ -1,12 +1,15 @@ -#ifndef Teredo_h -#define Teredo_h +#ifndef ANALYZER_PROTOCOL_TEREDO_TEREDO_H +#define ANALYZER_PROTOCOL_TEREDO_TEREDO_H -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include "NetVar.h" +#include "Reporter.h" -class Teredo_Analyzer : public Analyzer { +namespace analyzer { namespace teredo { + +class Teredo_Analyzer : public analyzer::Analyzer { public: - Teredo_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::Teredo, conn), + Teredo_Analyzer(Connection* conn) : Analyzer("TEREDO", conn), valid_orig(false), valid_resp(false) {} @@ -18,13 +21,9 @@ public: virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Teredo_Analyzer(conn); } - static bool Available() - { return BifConst::Tunnel::enable_teredo && - BifConst::Tunnel::max_depth > 0; } - /** * Emits a weird only if the analyzer has previously been able to * decapsulate a Teredo packet in both directions or if *force* param is @@ -50,7 +49,6 @@ public: } protected: - friend class AnalyzerTimer; void ExpireTimer(double t); bool valid_orig; @@ -93,4 +91,6 @@ protected: const Teredo_Analyzer* analyzer; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/teredo/events.bif b/src/analyzer/protocol/teredo/events.bif new file mode 100644 index 0000000000..62bc7d06cd --- /dev/null +++ b/src/analyzer/protocol/teredo/events.bif @@ -0,0 +1,55 @@ +## Generated for any IPv6 packet encapsulated in a Teredo tunnel. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_authentication teredo_origin_indication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event teredo_packet%(outer: connection, inner: teredo_hdr%); + +## Generated for IPv6 packets encapsulated in a Teredo tunnel that +## use the Teredo authentication encapsulation method. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_origin_indication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event teredo_authentication%(outer: connection, inner: teredo_hdr%); + +## Generated for IPv6 packets encapsulated in a Teredo tunnel that +## use the Teredo origin indication encapsulation method. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_authentication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event teredo_origin_indication%(outer: connection, inner: teredo_hdr%); + +## Generated for Teredo bubble packets. That is, IPv6 packets encapsulated +## in a Teredo tunnel that have a Next Header value of :bro:id:`IPPROTO_NONE`. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_authentication teredo_origin_indication +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event teredo_bubble%(outer: connection, inner: teredo_hdr%); + diff --git a/src/analyzer/protocol/udp/CMakeLists.txt b/src/analyzer/protocol/udp/CMakeLists.txt new file mode 100644 index 0000000000..0c92be60a3 --- /dev/null +++ b/src/analyzer/protocol/udp/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro UDP) +bro_plugin_cc(UDP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/udp/Plugin.cc b/src/analyzer/protocol/udp/Plugin.cc new file mode 100644 index 0000000000..0dbf0f80ca --- /dev/null +++ b/src/analyzer/protocol/udp/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "analyzer/protocol/udp/UDP.h" + +BRO_PLUGIN_BEGIN(Bro, UDP) + BRO_PLUGIN_DESCRIPTION("UDP Analyzer"); + BRO_PLUGIN_ANALYZER("UDP", udp::UDP_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/UDP.cc b/src/analyzer/protocol/udp/UDP.cc similarity index 97% rename from src/UDP.cc rename to src/analyzer/protocol/udp/UDP.cc index d85cb39edd..3050ea5648 100644 --- a/src/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -6,11 +6,16 @@ #include "Net.h" #include "NetVar.h" -#include "UDP.h" +#include "analyzer/protocol/udp/UDP.h" #include "Reporter.h" +#include "Conn.h" + +#include "events.bif.h" + +using namespace analyzer::udp; UDP_Analyzer::UDP_Analyzer(Connection* conn) -: TransportLayerAnalyzer(AnalyzerTag::UDP, conn) +: TransportLayerAnalyzer("UDP", conn) { conn->EnableStatusUpdateTimer(); conn->SetInactivityTimeout(udp_inactivity_timeout); diff --git a/src/UDP.h b/src/analyzer/protocol/udp/UDP.h similarity index 77% rename from src/UDP.h rename to src/analyzer/protocol/udp/UDP.h index b93d4da97f..bcfee401b0 100644 --- a/src/UDP.h +++ b/src/analyzer/protocol/udp/UDP.h @@ -1,17 +1,19 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef udp_h -#define udp_h +#ifndef ANALYZER_PROTOCOL_UDP_UDP_H +#define ANALYZER_PROTOCOL_UDP_UDP_H -#include "Analyzer.h" +#include "analyzer/Analyzer.h" #include +namespace analyzer { namespace udp { + typedef enum { UDP_INACTIVE, // no packet seen UDP_ACTIVE, // packets seen } UDP_EndpointState; -class UDP_Analyzer : public TransportLayerAnalyzer { +class UDP_Analyzer : public analyzer::TransportLayerAnalyzer { public: UDP_Analyzer(Connection* conn); virtual ~UDP_Analyzer(); @@ -20,11 +22,9 @@ public: virtual void UpdateConnVal(RecordVal *conn_val); - static Analyzer* InstantiateAnalyzer(Connection* conn) + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new UDP_Analyzer(conn); } - static bool Available() { return true; } - protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, @@ -47,4 +47,6 @@ private: #define HIST_RESP_CORRUPT_PKT 0x8 }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/udp/events.bif b/src/analyzer/protocol/udp/events.bif new file mode 100644 index 0000000000..394181cf5d --- /dev/null +++ b/src/analyzer/protocol/udp/events.bif @@ -0,0 +1,38 @@ +## Generated for each packet sent by a UDP flow's originator. This a potentially +## expensive event due to the volume of UDP traffic and should be used with +## care. +## +## u: The connection record for the corresponding UDP flow. +## +## .. bro:see:: udp_contents udp_reply udp_session_done +event udp_request%(u: connection%); + +## Generated for each packet sent by a UDP flow's responder. This a potentially +## expensive event due to the volume of UDP traffic and should be used with +## care. +## +## u: The connection record for the corresponding UDP flow. +## +## .. bro:see:: udp_contents udp_request udp_session_done +event udp_reply%(u: connection%); + +## Generated for UDP packets to pass on their payload. As the number of UDP +## packets can be very large, this event is normally raised only for those on +## ports configured in :bro:id:`udp_content_delivery_ports_orig` (for packets +## sent by the flow's originator) or :bro:id:`udp_content_delivery_ports_resp` +## (for packets sent by the flow's responder). However, delivery can be enabled +## for all UDP request and reply packets by setting +## :bro:id:`udp_content_deliver_all_orig` or +## :bro:id:`udp_content_deliver_all_resp`, respectively. Note that this +## event is also raised for all matching UDP packets, including empty ones. +## +## u: The connection record for the corresponding UDP flow. +## +## is_orig: True if the event is raised for the originator side. +## +## contents: TODO. +## +## .. bro:see:: udp_reply udp_request udp_session_done +## udp_content_deliver_all_orig udp_content_deliver_all_resp +## udp_content_delivery_ports_orig udp_content_delivery_ports_resp +event udp_contents%(u: connection, is_orig: bool, contents: string%); diff --git a/src/analyzer/protocol/zip/CMakeLists.txt b/src/analyzer/protocol/zip/CMakeLists.txt new file mode 100644 index 0000000000..814119f9f7 --- /dev/null +++ b/src/analyzer/protocol/zip/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro ZIP) +bro_plugin_cc(ZIP.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/analyzer/protocol/zip/Plugin.cc b/src/analyzer/protocol/zip/Plugin.cc new file mode 100644 index 0000000000..b55accccb3 --- /dev/null +++ b/src/analyzer/protocol/zip/Plugin.cc @@ -0,0 +1,10 @@ + +#include "plugin/Plugin.h" + +#include "ZIP.h" + +BRO_PLUGIN_BEGIN(Bro, ZIP) + BRO_PLUGIN_DESCRIPTION("Generic ZIP support analyzer"); + BRO_PLUGIN_ANALYZER_BARE("ZIP"); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/ZIP.cc b/src/analyzer/protocol/zip/ZIP.cc similarity index 90% rename from src/ZIP.cc rename to src/analyzer/protocol/zip/ZIP.cc index 0ebe93abe6..132515f29a 100644 --- a/src/ZIP.cc +++ b/src/analyzer/protocol/zip/ZIP.cc @@ -2,8 +2,12 @@ #include "ZIP.h" +#include "events.bif.h" + +using namespace analyzer::zip; + ZIP_Analyzer::ZIP_Analyzer(Connection* conn, bool orig, Method arg_method) -: TCP_SupportAnalyzer(AnalyzerTag::Zip, conn, orig) +: tcp::TCP_SupportAnalyzer("ZIP", conn, orig) { zip = 0; zip_status = Z_OK; @@ -44,7 +48,7 @@ void ZIP_Analyzer::Done() void ZIP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { - TCP_SupportAnalyzer::DeliverStream(len, data, orig); + tcp::TCP_SupportAnalyzer::DeliverStream(len, data, orig); if ( ! len || zip_status != Z_OK ) return; diff --git a/src/ZIP.h b/src/analyzer/protocol/zip/ZIP.h similarity index 65% rename from src/ZIP.h rename to src/analyzer/protocol/zip/ZIP.h index 6a8a180d1a..b284529d86 100644 --- a/src/ZIP.h +++ b/src/analyzer/protocol/zip/ZIP.h @@ -1,14 +1,16 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef zip_h -#define zip_h +#ifndef ANALYZER_PROTOCOL_ZIP_ZIP_H +#define ANALYZER_PROTOCOL_ZIP_ZIP_H #include "config.h" #include "zlib.h" -#include "TCP.h" +#include "analyzer/protocol/tcp/TCP.h" -class ZIP_Analyzer : public TCP_SupportAnalyzer { +namespace analyzer { namespace zip { + +class ZIP_Analyzer : public tcp::TCP_SupportAnalyzer { public: enum Method { GZIP, DEFLATE }; @@ -26,4 +28,6 @@ protected: Method method; }; +} } // namespace analyzer::* + #endif diff --git a/src/analyzer/protocol/zip/events.bif b/src/analyzer/protocol/zip/events.bif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/binpac_bro.h b/src/binpac_bro.h index dcdbe94f57..5902c52113 100644 --- a/src/binpac_bro.h +++ b/src/binpac_bro.h @@ -1,20 +1,24 @@ #ifndef binpac_bro_h #define binpac_bro_h -class Analyzer; +class Connection; class Val; class PortVal; +namespace analyzer { class Analyzer; } + #include "util.h" -#include "Analyzer.h" #include "Val.h" #include "event.bif.func_h" +#include "TunnelEncapsulation.h" +#include "analyzer/Analyzer.h" +#include "Conn.h" #include "binpac.h" namespace binpac { -typedef Analyzer* BroAnalyzer; +typedef analyzer::Analyzer* BroAnalyzer; typedef Val* BroVal; typedef PortVal* BroPortVal; typedef StringVal* BroStringVal; @@ -31,6 +35,4 @@ inline StringVal* bytestring_to_val(const_bytestring const &str) } // namespace binpac -extern int FLAGS_use_binpac; - #endif diff --git a/src/bro-bif.h b/src/bro-bif.h new file mode 100644 index 0000000000..24312e4753 --- /dev/null +++ b/src/bro-bif.h @@ -0,0 +1,11 @@ + +#ifndef BRO_BIF_H +#define BRO_BIF_H + +// Headers to include by generated BiF code. +#include "analyzer/Analyzer.h" +#include "Conn.h" +#include "NetVar.h" +#include "Event.h" + +#endif diff --git a/src/bro.bif b/src/bro.bif index 26fe16d821..efb913bbf7 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -21,7 +21,6 @@ using namespace std; -RecordType* ftp_port; RecordType* net_stats; RecordType* bro_resources; RecordType* matcher_stats; @@ -1783,26 +1782,6 @@ function get_matcher_stats%(%): matcher_stats return r; %} -## Returns statistics about TCP gaps. -## -## Returns: A record with TCP gap statistics. -## -## .. bro:see:: do_profiling -## net_stats -## resource_usage -## dump_rule_stats -## get_matcher_stats -function get_gap_summary%(%): gap_info - %{ - RecordVal* r = new RecordVal(gap_info); - r->Assign(0, new Val(tot_ack_events, TYPE_COUNT)); - r->Assign(1, new Val(tot_ack_bytes, TYPE_COUNT)); - r->Assign(2, new Val(tot_gap_events, TYPE_COUNT)); - r->Assign(3, new Val(tot_gap_bytes, TYPE_COUNT)); - - return r; - %} - ## Generates a table of the size of all global variables. The table index is ## the variable name and the value is the variable size in bytes. ## @@ -2629,273 +2608,6 @@ function addr_to_ptr_name%(a: addr%): string return new StringVal(a->AsAddr().PtrName().c_str()); %} - -%%{ -static Val* parse_port(const char* line) - { - RecordVal* r = new RecordVal(ftp_port); - - int bytes[6]; - if ( line && sscanf(line, "%d,%d,%d,%d,%d,%d", - &bytes[0], &bytes[1], &bytes[2], - &bytes[3], &bytes[4], &bytes[5]) == 6 ) - { - int good = 1; - - for ( int i = 0; i < 6; ++i ) - if ( bytes[i] < 0 || bytes[i] > 255 ) - { - good = 0; - break; - } - - uint32 addr = (bytes[0] << 24) | (bytes[1] << 16) | - (bytes[2] << 8) | bytes[3]; - uint32 port = (bytes[4] << 8) | bytes[5]; - - // Since port is unsigned, no need to check for < 0. - if ( port > 65535 ) - { - port = 0; - good = 0; - } - - r->Assign(0, new AddrVal(htonl(addr))); - r->Assign(1, new PortVal(port, TRANSPORT_TCP)); - r->Assign(2, new Val(good, TYPE_BOOL)); - } - else - { - r->Assign(0, new AddrVal(uint32(0))); - r->Assign(1, new PortVal(0, TRANSPORT_TCP)); - r->Assign(2, new Val(0, TYPE_BOOL)); - } - - return r; - } - -static Val* parse_eftp(const char* line) - { - RecordVal* r = new RecordVal(ftp_port); - - int net_proto = 0; // currently not used - IPAddr addr; // unspecified IPv6 address (all 128 bits zero) - int port = 0; - int good = 0; - - if ( line ) - { - while ( isspace(*line) ) // skip whitespace - ++line; - - char delimiter = *line; - char* next_delim; - - if ( *line ) - { - good = 1; - ++line; // skip delimiter - - net_proto = strtol(line, &next_delim, 10); - if ( *next_delim != delimiter ) - good = 0; - - line = next_delim; - if ( *line ) - ++line; - - if ( *line && *line != delimiter ) - { - const char* nptr = strchr(line, delimiter); - if ( nptr == NULL ) - { - nptr = line + strlen(line); - good = 0; - } - - string s(line, nptr-line); // extract IP address - IPAddr tmp(s); - // on error, "tmp" will have all 128 bits zero - if ( tmp == addr ) - good = 0; - - addr = tmp; - } - - line = strchr(line, delimiter); - - if ( line != NULL ) - { - ++line; // now the port - port = strtol(line, &next_delim, 10); - if ( *next_delim != delimiter ) - good = 0; - } - - } - - } - - r->Assign(0, new AddrVal(addr)); - r->Assign(1, new PortVal(port, TRANSPORT_TCP)); - r->Assign(2, new Val(good, TYPE_BOOL)); - - return r; - } -%%} - -## Converts a string representation of the FTP PORT command to an ``ftp_port``. -## -## s: The string of the FTP PORT command, e.g., ``"10,0,0,1,4,31"``. -## -## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` -## -## .. bro:see:: parse_eftp_port parse_ftp_pasv parse_ftp_epsv fmt_ftp_port -function parse_ftp_port%(s: string%): ftp_port - %{ - return parse_port(s->CheckString()); - %} - -## Converts a string representation of the FTP EPRT command to an ``ftp_port``. -## See `RFC 2428 `_. -## The format is ``EPRT``, -## where ```` is a delimiter in the ASCII range 33-126 (usually ``|``). -## -## s: The string of the FTP EPRT command, e.g., ``"|1|10.0.0.1|1055|"``. -## -## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` -## -## .. bro:see:: parse_ftp_port parse_ftp_pasv parse_ftp_epsv fmt_ftp_port -function parse_eftp_port%(s: string%): ftp_port - %{ - return parse_eftp(s->CheckString()); - %} - -## Converts the result of the FTP PASV command to an ``ftp_port``. -## -## str: The string containing the result of the FTP PASV command. -## -## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` -## -## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_epsv fmt_ftp_port -function parse_ftp_pasv%(str: string%): ftp_port - %{ - const char* s = str->CheckString(); - const char* line = strchr(s, '('); - if ( line ) - ++line; // move past '(' - else if ( (line = strstr(s, "PORT")) ) - line += 5; // Skip over - else if ( (line = strchr(s, ',')) ) - { // Look for comma-separated list. - while ( --line >= s && isdigit(*line) ) - ; // Back up over preceding digits. - ++line; // now points to first digit, or beginning of s - } - - return parse_port(line); - %} - -## Converts the result of the FTP EPSV command to an ``ftp_port``. -## See `RFC 2428 `_. -## The format is `` ()``, where ```` is a -## delimiter in the ASCII range 33-126 (usually ``|``). -## -## str: The string containing the result of the FTP EPSV command. -## -## Returns: The FTP PORT, e.g., ``[h=10.0.0.1, p=1055/tcp, valid=T]`` -## -## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_pasv fmt_ftp_port -function parse_ftp_epsv%(str: string%): ftp_port - %{ - const char* s = str->CheckString(); - const char* line = strchr(s, '('); - if ( line ) - ++line; // move past '(' - return parse_eftp(line); - %} - -## Formats an IP address and TCP port as an FTP PORT command. For example, -## ``10.0.0.1`` and ``1055/tcp`` yields ``"10,0,0,1,4,31"``. -## -## a: The IP address. -## -## p: The TCP port. -## -## Returns: The FTP PORT string. -## -## .. bro:see:: parse_ftp_port parse_eftp_port parse_ftp_pasv parse_ftp_epsv -function fmt_ftp_port%(a: addr, p: port%): string - %{ - const uint32* addr; - int len = a->AsAddr().GetBytes(&addr); - if ( len == 1 ) - { - uint32 a = ntohl(addr[0]); - uint32 pn = p->Port(); - return new StringVal(fmt("%d,%d,%d,%d,%d,%d", - a >> 24, (a >> 16) & 0xff, - (a >> 8) & 0xff, a & 0xff, - pn >> 8, pn & 0xff)); - } - else - { - builtin_error("conversion of non-IPv4 address in fmt_ftp_port", - @ARG@[0]); - return new StringVal(""); - } - %} - -## Decode a NetBIOS name. See http://support.microsoft.com/kb/194203. -## -## name: The encoded NetBIOS name, e.g., ``"FEEIEFCAEOEFFEECEJEPFDCAEOEBENEF"``. -## -## Returns: The decoded NetBIOS name, e.g., ``"THE NETBIOS NAME"``. -## -## .. bro:see:: decode_netbios_name_type -function decode_netbios_name%(name: string%): string - %{ - char buf[16]; - char result[16]; - const u_char* s = name->Bytes(); - int i, j; - - for ( i = 0, j = 0; i < 16; ++i ) - { - char c0 = (j < name->Len()) ? toupper(s[j++]) : 'A'; - char c1 = (j < name->Len()) ? toupper(s[j++]) : 'A'; - buf[i] = ((c0 - 'A') << 4) + (c1 - 'A'); - } - - for ( i = 0; i < 15; ++i ) - { - if ( isalnum(buf[i]) || ispunct(buf[i]) || - // \x01\x02 is seen in at least one case as the first two bytes. - // I think that any \x01 and \x02 should always be passed through. - buf[i] < 3 ) - result[i] = buf[i]; - else - break; - } - - return new StringVal(i, result); - %} - -## Converts a NetBIOS name type to its corresponding numeric value. -## See http://support.microsoft.com/kb/163409. -## -## name: The NetBIOS name type. -## -## Returns: The numeric value of *name*. -## -## .. bro:see:: decode_netbios_name -function decode_netbios_name_type%(name: string%): count - %{ - const u_char* s = name->Bytes(); - char return_val = ((toupper(s[30]) - 'A') << 4) + (toupper(s[31]) - 'A'); - return new Val(return_val, TYPE_COUNT); - %} - ## Converts a string of bytes into its hexadecimal representation. ## For example, ``"04"`` would be converted to ``"3034"``. ## @@ -3002,8 +2714,6 @@ function decode_base64_custom%(s: string, a: string%): string %} %%{ -#include "DCE_RPC.h" - typedef struct { uint32 time_low; uint16 time_mid; @@ -3415,8 +3125,6 @@ function lookup_connection%(cid: conn_id%): connection %} %%{ -#include "HTTP.h" - const char* conn_id_string(Val* c) { Val* id = (*(c->AsRecord()))[0]; @@ -3432,58 +3140,6 @@ const char* conn_id_string(Val* c) } %%} -## Skips the data of the HTTP entity. -## -## c: The HTTP connection. -## -## is_orig: If true, the client data is skipped, and the server data otherwise. -## -## .. bro:see:: skip_smtp_data -function skip_http_entity_data%(c: connection, is_orig: bool%): any - %{ - AnalyzerID id = mgr.CurrentAnalyzer(); - if ( id ) - { - Analyzer* ha = c->FindAnalyzer(id); - - if ( ha ) - { - if ( ha->GetTag() == AnalyzerTag::HTTP ) - static_cast(ha)->SkipEntityData(is_orig); - else - reporter->Error("non-HTTP analyzer associated with connection record"); - } - else - reporter->Error("could not find analyzer for skip_http_entity_data"); - - } - else - reporter->Error("no analyzer associated with connection record"); - - return 0; - %} - -## Unescapes all characters in a URI (decode every ``%xx`` group). -## -## URI: The URI to unescape. -## -## Returns: The unescaped URI with all ``%xx`` groups decoded. -## -## .. note:: -## -## Unescaping reserved characters may cause loss of information. RFC 2396: -## A URI is always in an "escaped" form, since escaping or unescaping a -## completed URI might change its semantics. Normally, the only time -## escape encodings can safely be made is when the URI is being created -## from its component parts. -function unescape_URI%(URI: string%): string - %{ - const u_char* line = URI->Bytes(); - const u_char* const line_end = line + URI->Len(); - - return new StringVal(unescape_URI(line, line_end, 0)); - %} - ## Writes the current packet to a file. ## ## file_name: The name of the file to write the packet to. @@ -3931,138 +3587,6 @@ function lookup_asn%(a: addr%) : count return new Val(0, TYPE_COUNT); %} -%%{ -#include -#include -#include - -// This is the indexed map of X509 certificate stores. -static map x509_stores; - -// ### NOTE: while d2i_X509 does not take a const u_char** pointer, -// here we assume d2i_X509 does not write to , so it is safe to -// convert data to a non-const pointer. Could some X509 guru verify -// this? - -X509* d2i_X509_(X509** px, const u_char** in, int len) - { -#ifdef OPENSSL_D2I_X509_USES_CONST_CHAR - return d2i_X509(px, in, len); -#else - return d2i_X509(px, (u_char**)in, len); -#endif - } - -%%} - - -## Verifies a certificate. -## -## der_cert: The X.509 certificate in DER format. -## -## cert_stack: Specifies a certificate chain to validate against, with index 0 -## typically being the root CA. Bro uses the Mozilla root CA list -## by default. -## -## root_certs: A list of additional root certificates that extends -## *cert_stack*. -## -## Returns: A status code of the verification which can be converted into an -## ASCII string via :bro:id:`x509_err2str`. -## -## .. bro:see:: x509_err2str -function x509_verify%(der_cert: string, cert_stack: string_vec, root_certs: table_string_of_string%): count - %{ - X509_STORE* ctx = 0; - int i = 0; - - // If this certificate store was built previously, just reuse the old one. - if ( x509_stores.count(root_certs) > 0 ) - ctx = x509_stores[root_certs]; - - if ( ! ctx ) // lookup to see if we have this one built already! - { - ctx = X509_STORE_new(); - TableVal* root_certs2 = root_certs->AsTableVal(); - ListVal* idxs = root_certs2->ConvertToPureList(); - - // Build the validation store - for ( i = 0; i < idxs->Length(); ++i ) - { - Val* key = idxs->Index(i); - StringVal *sv = root_certs2->Lookup(key)->AsStringVal(); - const uint8* data = sv->Bytes(); - X509* x = d2i_X509_(NULL, &data, sv->Len()); - if ( ! x ) - { - builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return new Val((uint64) ERR_get_error(), TYPE_COUNT); - } - X509_STORE_add_cert(ctx, x); - } - delete idxs; - - // Save the newly constructed certificate store into the cacheing map. - x509_stores[root_certs] = ctx; - } - - const uint8 *cert_data = der_cert->Bytes(); - X509* cert = d2i_X509_(NULL, &cert_data, der_cert->Len()); - if ( ! cert ) - { - builtin_error(fmt("Certificate error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return new Val((uint64) ERR_get_error(), TYPE_COUNT); - } - - STACK_OF(X509)* untrusted_certs = sk_X509_new_null(); - if ( ! untrusted_certs ) - { - builtin_error(fmt("Untrusted certificate stack initialization error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return new Val((uint64) ERR_get_error(), TYPE_COUNT); - } - - VectorVal *cert_stack_vec = cert_stack->AsVectorVal(); - for ( i = 0; i < (int) cert_stack_vec->Size(); ++i ) - { - StringVal *sv = cert_stack_vec->Lookup(i)->AsStringVal(); - const uint8 *data = sv->Bytes(); - X509* x = d2i_X509_(NULL, &data, sv->Len()); - if ( ! x ) - { - X509_free(cert); - sk_X509_pop_free(untrusted_certs, X509_free); - builtin_error(fmt("Untrusted certificate stack creation error: %s", ERR_error_string(ERR_peek_last_error(),NULL))); - return new Val((uint64) ERR_get_error(), TYPE_COUNT); - } - sk_X509_push(untrusted_certs, x); - } - - X509_STORE_CTX csc; - X509_STORE_CTX_init(&csc, ctx, cert, untrusted_certs); - X509_STORE_CTX_set_time(&csc, 0, (time_t) network_time); - - int result = X509_verify_cert(&csc); - X509_STORE_CTX_cleanup(&csc); - - if ( untrusted_certs ) - sk_X509_pop_free(untrusted_certs, X509_free); - X509_free(cert); - - return new Val((uint64) csc.error, TYPE_COUNT); - %} - -## Converts a certificate verification error code into an ASCII string. -## -## err_num: The error code. -## -## Returns: A string representation of *err_num*. -## -## .. bro:see:: x509_verify -function x509_err2str%(err_num: count%): string - %{ - return new StringVal(X509_verify_cert_error_string(err_num)); - %} - ## Converts UNIX file permissions given by a mode to an ASCII string. ## ## mode: The permissions (an octal number like 0644 converted to decimal). @@ -4162,36 +3686,9 @@ function file_mode%(mode: count%): string # =========================================================================== %%{ -#include "DPM.h" +#include "analyzer/Manager.h" %%} -## Schedules an analyzer for a future connection from a given IP address and -## port. The function ignores the scheduling request if the connection did -## not occur within the specified time interval. -## -## orig: The IP address originating a connection in the future. -## -## resp: The IP address responding to a connection from *orig*. -## -## resp_p: The destination port at *resp*. -## -## analyzer: The analyzer ID. -## -## tout: The timeout interval after which to ignore the scheduling request. -## -## Returns: True (unconditionally). -## -## .. bro:see:: disable_analyzer analyzer_name -## -## .. todo:: The return value should be changed to any. -function expect_connection%(orig: addr, resp: addr, resp_p: port, - analyzer: count, tout: interval%) : any - %{ - dpm->ExpectConnection(orig->AsAddr(), resp->AsAddr(), resp_p->Port(), - resp_p->PortType(), (AnalyzerTag::Tag) analyzer, tout, 0); - return new Val(1, TYPE_BOOL); - %} - ## Disables the analyzer which raised the current event (if the analyzer ## belongs to the given connection). ## @@ -4202,7 +3699,7 @@ function expect_connection%(orig: addr, resp: addr, resp_p: port, ## Returns: True if the connection identified by *cid* exists and has analyzer ## *aid*. ## -## .. bro:see:: expect_connection analyzer_name +## .. bro:see:: Analyzer::schedule_analyzer Analyzer::name function disable_analyzer%(cid: conn_id, aid: count%) : bool %{ Connection* c = sessions->FindConnection(cid); @@ -4212,7 +3709,7 @@ function disable_analyzer%(cid: conn_id, aid: count%) : bool return new Val(0, TYPE_BOOL); } - Analyzer* a = c->FindAnalyzer(aid); + analyzer::Analyzer* a = c->FindAnalyzer(aid); if ( ! a ) { reporter->Error("connection does not have analyzer specified to disable"); @@ -4223,18 +3720,6 @@ function disable_analyzer%(cid: conn_id, aid: count%) : bool return new Val(1, TYPE_BOOL); %} -## Translate an analyzer type to an ASCII string. -## -## aid: The analyzer ID. -## -## Returns: The analyzer *aid* as string. -## -## .. bro:see:: expect_connection disable_analyzer current_analyzer -function analyzer_name%(aid: count%) : string - %{ - return new StringVal(Analyzer::GetTagName((AnalyzerTag::Tag) aid)); - %} - ## Informs Bro that it should skip any further processing of the contents of ## a given connection. In particular, Bro will refrain from reassembling the ## TCP byte stream and from generating events relating to any analyzers that @@ -4289,81 +3774,6 @@ function set_record_packets%(cid: conn_id, do_record: bool%): bool return new Val(1, TYPE_BOOL); %} -## Associates a file handle with a connection for writing TCP byte stream -## contents. -## -## cid: The connection ID. -## -## direction: Controls what sides of the connection to record. The argument can -## take one of the four values: -## -## - ``CONTENTS_NONE``: Stop recording the connection's content. -## - ``CONTENTS_ORIG``: Record the data sent by the connection -## originator (often the client). -## - ``CONTENTS_RESP``: Record the data sent by the connection -## responder (often the server). -## - ``CONTENTS_BOTH``: Record the data sent in both directions. -## Results in the two directions being -## intermixed in the file, in the order the -## data was seen by Bro. -## -## f: The file handle of the file to write the contents to. -## -## Returns: Returns false if *cid* does not point to an active connection, and -## true otherwise. -## -## .. note:: -## -## The data recorded to the file reflects the byte stream, not the -## contents of individual packets. Reordering and duplicates are -## removed. If any data is missing, the recording stops at the -## missing data; this can happen, e.g., due to an -## :bro:id:`ack_above_hole` event. -## -## .. bro:see:: get_contents_file set_record_packets -function set_contents_file%(cid: conn_id, direction: count, f: file%): bool - %{ - Connection* c = sessions->FindConnection(cid); - if ( ! c ) - return new Val(0, TYPE_BOOL); - - c->GetRootAnalyzer()->SetContentsFile(direction, f); - return new Val(1, TYPE_BOOL); - %} - -## Returns the file handle of the contents file of a connection. -## -## cid: The connection ID. -## -## direction: Controls what sides of the connection to record. See -## :bro:id:`set_contents_file` for possible values. -## -## Returns: The :bro:type:`file` handle for the contents file of the -## connection identified by *cid*. If the connection exists -## but there is no contents file for *direction*, then the function -## generates an error and returns a file handle to ``stderr``. -## -## .. bro:see:: set_contents_file set_record_packets -function get_contents_file%(cid: conn_id, direction: count%): file - %{ - Connection* c = sessions->FindConnection(cid); - BroFile* f = c ? c->GetRootAnalyzer()->GetContentsFile(direction) : 0; - - if ( f ) - { - Ref(f); - return new Val(f); - } - - // Return some sort of error value. - if ( ! c ) - builtin_error("unknown connection id in get_contents_file()", cid); - else - builtin_error("no contents file for given direction"); - - return new Val(new BroFile(stderr, "-", "w")); - %} - ## Sets an individual inactivity timeout for a connection and thus ## overrides the global inactivity timeout. ## @@ -4384,170 +3794,6 @@ function set_inactivity_timeout%(cid: conn_id, t: interval%): interval return new Val(old_timeout, TYPE_INTERVAL); %} -## Returns the state of the given login (Telnet or Rlogin) connection. -## -## cid: The connection ID. -## -## Returns: False if the connection is not active or is not tagged as a -## login analyzer. Otherwise the function returns the state, which can -## be one of: -## -## - ``LOGIN_STATE_AUTHENTICATE``: The connection is in its -## initial authentication dialog. -## - ``LOGIN_STATE_LOGGED_IN``: The analyzer believes the user has -## successfully authenticated. -## - ``LOGIN_STATE_SKIP``: The analyzer has skipped any further -## processing of the connection. -## - ``LOGIN_STATE_CONFUSED``: The analyzer has concluded that it -## does not correctly know the state of the connection, and/or -## the username associated with it. -## -## .. bro:see:: set_login_state -function get_login_state%(cid: conn_id%): count - %{ - Connection* c = sessions->FindConnection(cid); - if ( ! c ) - return new Val(0, TYPE_BOOL); - - Analyzer* la = c->FindAnalyzer(AnalyzerTag::Login); - if ( ! la ) - return new Val(0, TYPE_BOOL); - - return new Val(int(static_cast(la)->LoginState()), - TYPE_COUNT); - %} - -## Sets the login state of a connection with a login analyzer. -## -## cid: The connection ID. -## -## new_state: The new state of the login analyzer. See -## :bro:id:`get_login_state` for possible values. -## -## Returns: Returns false if *cid* is not an active connection -## or is not tagged as a login analyzer, and true otherwise. -## -## .. bro:see:: get_login_state -function set_login_state%(cid: conn_id, new_state: count%): bool - %{ - Connection* c = sessions->FindConnection(cid); - if ( ! c ) - return new Val(0, TYPE_BOOL); - - Analyzer* la = c->FindAnalyzer(AnalyzerTag::Login); - if ( ! la ) - return new Val(0, TYPE_BOOL); - - static_cast(la)->SetLoginState(login_state(new_state)); - return new Val(1, TYPE_BOOL); - %} - -%%{ -#include "TCP.h" -%%} - -## Get the originator sequence number of a TCP connection. Sequence numbers -## are absolute (i.e., they reflect the values seen directly in packet headers; -## they are not relative to the beginning of the connection). -## -## cid: The connection ID. -## -## Returns: The highest sequence number sent by a connection's originator, or 0 -## if *cid* does not point to an active TCP connection. -## -## .. bro:see:: get_resp_seq -function get_orig_seq%(cid: conn_id%): count - %{ - Connection* c = sessions->FindConnection(cid); - if ( ! c ) - return new Val(0, TYPE_COUNT); - - if ( c->ConnTransport() != TRANSPORT_TCP ) - return new Val(0, TYPE_COUNT); - - Analyzer* tc = c->FindAnalyzer(AnalyzerTag::TCP); - if ( tc ) - return new Val(static_cast(tc)->OrigSeq(), - TYPE_COUNT); - else - { - reporter->Error("connection does not have TCP analyzer"); - return new Val(0, TYPE_COUNT); - } - %} - -## Get the responder sequence number of a TCP connection. Sequence numbers -## are absolute (i.e., they reflect the values seen directly in packet headers; -## they are not relative to the beginning of the connection). -## -## cid: The connection ID. -## -## Returns: The highest sequence number sent by a connection's responder, or 0 -## if *cid* does not point to an active TCP connection. -## -## .. bro:see:: get_orig_seq -function get_resp_seq%(cid: conn_id%): count - %{ - Connection* c = sessions->FindConnection(cid); - if ( ! c ) - return new Val(0, TYPE_COUNT); - - if ( c->ConnTransport() != TRANSPORT_TCP ) - return new Val(0, TYPE_COUNT); - - Analyzer* tc = c->FindAnalyzer(AnalyzerTag::TCP); - if ( tc ) - return new Val(static_cast(tc)->RespSeq(), - TYPE_COUNT); - else - { - reporter->Error("connection does not have TCP analyzer"); - return new Val(0, TYPE_COUNT); - } - %} - -%%{ -#include "SMTP.h" -%%} - -## Skips SMTP data until the next email in a connection. -## -## c: The SMTP connection. -## -## .. bro:see:: skip_http_entity_data -function skip_smtp_data%(c: connection%): any - %{ - Analyzer* sa = c->FindAnalyzer(AnalyzerTag::SMTP); - if ( sa ) - static_cast(sa)->SkipData(); - return 0; - %} - -## Enables all event handlers in a given group. One can tag event handlers with -## the :bro:attr:`&group` attribute to logically group them together, e.g, -## ``event foo() &group="bar"``. This function enables all event handlers that -## belong to such a group. -## -## group: The group. -## -## .. bro:see:: disable_event_group -function enable_event_group%(group: string%) : any - %{ - event_registry->EnableGroup(group->CheckString(), true); - return 0; - %} - -## Disables all event handlers in a given group. -## -## group: The group. -## -## .. bro:see:: enable_event_group -function disable_event_group%(group: string%) : any - %{ - event_registry->EnableGroup(group->CheckString(), false); - return 0; - %} - # =========================================================================== # # Files and Directories diff --git a/src/builtin-func.l b/src/builtin-func.l index fa9915077f..5d053c555d 100644 --- a/src/builtin-func.l +++ b/src/builtin-func.l @@ -28,7 +28,7 @@ int check_c_mode(int t) WS [ \t]+ OWS [ \t]* /* Note, bifcl only accepts a single "::" in IDs while the policy - layer acceptes multiple. (But the policy layer doesn't have + layer acceptes multiple. (But the policy layer doesn't have a hierachy. */ IDCOMPONENT [A-Za-z_][A-Za-z_0-9]* ID {IDCOMPONENT}(::{IDCOMPONENT})? @@ -144,6 +144,9 @@ int yywrap() extern int yyparse(); char* input_filename = 0; +char* input_filename_with_path = 0; +char* plugin = 0; +int alternative_mode = 0; FILE* fp_bro_init = 0; FILE* fp_func_def = 0; @@ -175,15 +178,124 @@ FILE* open_output_file(const char* surfix) return fp; } +void usage() + { + fprintf(stderr, "usage: bifcl [-p] *.bif\n"); + exit(1); + } + +void init_alternative_mode() + { + fp_bro_init = open_output_file("bro"); + fp_func_h = open_output_file("h"); + fp_func_def = open_output_file("cc"); + fp_func_init = open_output_file("init.cc"); + + fp_netvar_h = fp_func_h; + fp_netvar_def = fp_func_def; + fp_netvar_init = fp_func_init; + + int n = 1024 + strlen(input_filename); + char auto_gen_comment[n]; + + snprintf(auto_gen_comment, n, + "This file was automatically generated by bifcl from %s (%s mode).", + input_filename_with_path, plugin ? "plugin" : "alternative"); + + fprintf(fp_bro_init, "# %s\n\n", auto_gen_comment); + fprintf(fp_func_def, "// %s\n\n", auto_gen_comment); + fprintf(fp_func_h, "// %s\n\n", auto_gen_comment); + fprintf(fp_func_init, "// %s\n\n", auto_gen_comment); + + static char guard[1024]; + getcwd(guard, sizeof(guard)); + strncat(guard, "/", sizeof(guard)); + strncat(guard, input_filename, sizeof(guard)); + + for ( char* p = guard; *p; p++ ) + { + if ( strchr("/.-", *p) ) + *p = '_'; + } + + fprintf(fp_func_h, "#if defined(BRO_IN_NETVAR) || ! defined(%s)\n", guard); + + fprintf(fp_func_h, "#ifndef BRO_IN_NETVAR\n"); + fprintf(fp_func_h, "#ifndef %s\n", guard); + fprintf(fp_func_h, "#define %s\n", guard); + fprintf(fp_func_h, "#include \"bro-bif.h\"\n"); + fprintf(fp_func_h, "#endif\n"); + fprintf(fp_func_h, "#endif\n"); + fprintf(fp_func_h, "\n"); + + fprintf(fp_func_def, "\n"); + fprintf(fp_func_def, "#include \"%s.h\"\n", input_filename); + fprintf(fp_func_def, "\n"); + + static char name[1024]; + strncpy(name, input_filename, sizeof(name)); + char* dot = strchr(name, '.'); + if ( dot ) + *dot = '\0'; + + if ( plugin ) + { + fprintf(fp_func_init, "\n"); + fprintf(fp_func_init, "#include \n"); + fprintf(fp_func_init, "#include \n"); + fprintf(fp_func_init, "#include \"%s.h\"\n", input_filename); + fprintf(fp_func_init, "\n"); + fprintf(fp_func_init, "namespace plugin { namespace %s {\n", plugin); + fprintf(fp_func_init, "\n"); + fprintf(fp_func_init, "std::list > __bif_%s_init()\n", name); + fprintf(fp_func_init, "\t{\n"); + fprintf(fp_func_init, "\tstd::list > bifs;\n"); + fprintf(fp_func_init, "\n"); + } + } + +void finish_alternative_mode() + { + fprintf(fp_func_h, "\n"); + fprintf(fp_func_h, "#endif\n"); + + if ( plugin ) + { + fprintf(fp_func_init, "\n"); + fprintf(fp_func_init, "\treturn bifs;\n"); + fprintf(fp_func_init, "\t}\n"); + fprintf(fp_func_init, "} }\n"); + fprintf(fp_func_init, "\n"); + } + } int main(int argc, char* argv[]) { - for ( int i = 1; i < argc; i++ ) + char opt; + + while ( (opt = getopt(argc, argv, "p:s")) != -1 ) + { + switch ( opt ) { + case 'p': + alternative_mode = 1; + plugin = optarg; + break; + + case 's': + alternative_mode = 1; + break; + + default: + usage(); + } + } + + for ( int i = optind; i < argc; i++ ) { FILE* fp_input; char* slash; - input_filename = argv[i]; + input_filename = input_filename_with_path = argv[i]; slash = strrchr(input_filename, '/'); if ( (fp_input = fopen(input_filename, "r")) == NULL ) @@ -196,17 +308,41 @@ int main(int argc, char* argv[]) if ( slash ) input_filename = slash + 1; - fp_bro_init = open_output_file("bro"); - fp_func_h = open_output_file("func_h"); - fp_func_def = open_output_file("func_def"); - fp_func_init = open_output_file("func_init"); - fp_netvar_h = open_output_file("netvar_h"); - fp_netvar_def = open_output_file("netvar_def"); - fp_netvar_init = open_output_file("netvar_init"); + if ( ! alternative_mode ) + { + fp_bro_init = open_output_file("bro"); + fp_func_h = open_output_file("func_h"); + fp_func_def = open_output_file("func_def"); + fp_func_init = open_output_file("func_init"); + fp_netvar_h = open_output_file("netvar_h"); + fp_netvar_def = open_output_file("netvar_def"); + fp_netvar_init = open_output_file("netvar_init"); + + int n = 1024 + strlen(input_filename); + char auto_gen_comment[n]; + + snprintf(auto_gen_comment, n, + "This file was automatically generated by bifcl from %s.", + input_filename); + + fprintf(fp_bro_init, "# %s\n\n", auto_gen_comment); + fprintf(fp_func_def, "// %s\n\n", auto_gen_comment); + fprintf(fp_func_h, "// %s\n\n", auto_gen_comment); + fprintf(fp_func_init, "// %s\n\n", auto_gen_comment); + fprintf(fp_netvar_def, "// %s\n\n", auto_gen_comment); + fprintf(fp_netvar_h, "// %s\n\n", auto_gen_comment); + fprintf(fp_netvar_init, "// %s\n\n", auto_gen_comment); + } + + else + init_alternative_mode(); yy_switch_to_buffer(yy_create_buffer(fp_input, YY_BUF_SIZE)); yyparse(); + if ( alternative_mode ) + finish_alternative_mode(); + fclose(fp_input); close_all_output_files(); @@ -226,9 +362,13 @@ void close_all_output_files(void) close_if_open(&fp_func_h); close_if_open(&fp_func_def); close_if_open(&fp_func_init); - close_if_open(&fp_netvar_h); - close_if_open(&fp_netvar_def); - close_if_open(&fp_netvar_init); + + if ( ! alternative_mode ) + { + close_if_open(&fp_netvar_h); + close_if_open(&fp_netvar_def); + close_if_open(&fp_netvar_init); + } } void remove_file(const char *surfix) @@ -239,7 +379,7 @@ void remove_file(const char *surfix) unlink(fn); } -void err_exit(void) +void err_exit(void) { close_all_output_files(); /* clean up. remove all output files we've generated so far */ diff --git a/src/builtin-func.y b/src/builtin-func.y index 54ec5a29f6..662256b8d6 100644 --- a/src/builtin-func.y +++ b/src/builtin-func.y @@ -15,6 +15,7 @@ using namespace std; extern int line_number; extern char* input_filename; +extern char* plugin; #define print_line_directive(fp) fprintf(fp, "\n#line %d \"%s\"\n", line_number, input_filename) @@ -197,11 +198,11 @@ char* concat(const char* str1, const char* str2) void print_event_c_prototype(FILE *fp, bool is_header) { if ( is_header ) - fprintf(fp, "%s void %s(Analyzer* analyzer%s", + fprintf(fp, "%s void %s(analyzer::Analyzer* analyzer%s", decl.generate_c_namespace_start.c_str(), decl.generate_bare_name.c_str(), args.size() ? ", " : "" ); else - fprintf(fp, "void %s(Analyzer* analyzer%s", + fprintf(fp, "void %s(analyzer::Analyzer* analyzer%s", decl.generate_c_fullname.c_str(), args.size() ? ", " : "" ); for ( int i = 0; i < (int) args.size(); ++i ) @@ -265,6 +266,15 @@ void print_event_c_body(FILE *fp) fprintf(fp, "\t} // event generation\n"); //fprintf(fp, "%s // end namespace\n", decl.generate_c_namespace_end.c_str()); } + +void record_bif_item(const char* id, int type) + { + if ( ! plugin ) + return; + + fprintf(fp_func_init, "\tbifs.push_back(std::make_pair(\"%s\", %d));\n", id, type); + } + %} %token TOK_LPP TOK_RPP TOK_LPB TOK_RPB TOK_LPPB TOK_RPPB TOK_VAR_ARG @@ -304,21 +314,6 @@ definitions: definitions definition opt_ws } | opt_ws { - int n = 1024 + strlen(input_filename); - char auto_gen_comment[n]; - - snprintf(auto_gen_comment, n, - "This file was automatically generated by bifcl from %s.", - input_filename); - - fprintf(fp_bro_init, "# %s\n\n", auto_gen_comment); - fprintf(fp_func_def, "// %s\n\n", auto_gen_comment); - fprintf(fp_func_h, "// %s\n\n", auto_gen_comment); - fprintf(fp_func_init, "// %s\n\n", auto_gen_comment); - fprintf(fp_netvar_def, "// %s\n\n", auto_gen_comment); - fprintf(fp_netvar_h, "// %s\n\n", auto_gen_comment); - fprintf(fp_netvar_init, "// %s\n\n", auto_gen_comment); - fprintf(fp_bro_init, "%s", $1); fprintf(fp_bro_init, "export {\n"); } @@ -362,6 +357,8 @@ type_def: TOK_TYPE opt_ws TOK_ID opt_ws ':' opt_ws type_def_types opt_ws ';' "\t%s = internal_type(\"%s\")->As%sType();\n", decl.c_fullname.c_str(), decl.bro_fullname.c_str(), type_name.c_str()); + + record_bif_item(decl.bro_fullname.c_str(), 5); } ; @@ -403,6 +400,8 @@ enum_def: enum_def_1 enum_list TOK_RPB fprintf(fp_netvar_init, "\t%s = internal_type(\"%s\")->AsEnumType();\n", decl.c_fullname.c_str(), decl.bro_fullname.c_str()); + + record_bif_item(decl.bro_fullname.c_str(), 5); } ; @@ -457,6 +456,8 @@ const_def: TOK_CONST opt_ws TOK_ID opt_ws ':' opt_ws TOK_ID opt_ws ';' fprintf(fp_netvar_init, "\t%s = internal_const_val(\"%s\")%s;\n", decl.c_fullname.c_str(), decl.bro_fullname.c_str(), accessor); + + record_bif_item(decl.bro_fullname.c_str(), 3); } attr_list: @@ -543,6 +544,8 @@ head_1: TOK_ID opt_ws arg_begin fprintf(fp_func_def, "Val* %s(Frame* frame, val_list* %s)", decl.c_fullname.c_str(), arg_list_name); + + record_bif_item(decl.bro_fullname.c_str(), 1); } else if ( definition_type == EVENT_DEF ) { @@ -559,6 +562,8 @@ head_1: TOK_ID opt_ws arg_begin "\t%s = internal_handler(\"%s\");\n", decl.c_fullname.c_str(), decl.bro_fullname.c_str()); + record_bif_item(decl.bro_fullname.c_str(), 2); + // C++ prototypes of bro_event_* functions will // be generated later. } diff --git a/src/const.bif b/src/const.bif index 10dceda6ff..ea84b3363d 100644 --- a/src/const.bif +++ b/src/const.bif @@ -23,5 +23,3 @@ const Tunnel::delay_gtp_confirmation: bool; const Tunnel::ip_tunnel_timeout: interval; const Threading::heartbeat_interval: interval; - -const Files::salt: string; diff --git a/src/dns-analyzer.pac b/src/dns-analyzer.pac deleted file mode 100644 index e92b6ef709..0000000000 --- a/src/dns-analyzer.pac +++ /dev/null @@ -1,343 +0,0 @@ -%extern{ -#include -%} - -%code{ -int add_to_name_buffer(DNS_name* name, char* buf, const int buf_n, int buf_i) - { - for ( int i = 0; i < int(name->labels()->size()); ++i ) - { - DNS_label* label = (*name->labels())[i]; - if ( label->label_type() == 0 ) - { - bytestring const &label_str = label->label(); - if ( buf_i > 0 && buf_i < buf_n ) - buf[buf_i++] = '.'; - BINPAC_ASSERT(buf_i + label_str.length() <= buf_n); - memcpy(buf + buf_i, label_str.begin(), - label_str.length()); - buf_i += label_str.length(); - } - else if ( label->label_type() == 3 ) - { - return add_to_name_buffer(label->ptr(), buf, - buf_n, buf_i); - } - } - - return buf_i; - } - -StringVal* name_to_val(DNS_name* name) - { - char name_buf[520]; - int n = add_to_name_buffer(name, name_buf, sizeof(name_buf), 0); - if ( n > 0 ) - --n; // remove the trailing '.' - - BINPAC_ASSERT(n < int(sizeof(name_buf))); - - name_buf[n] = 0; - for ( int i = 0; i < n; ++i ) - if ( isupper(name_buf[i]) ) - name_buf[i] = tolower(name_buf[i]); - - return new StringVal(name_buf); - } -%} - -connection DNS_Conn(bro_analyzer: BroAnalyzer) -{ - upflow = DNS_Flow; - downflow = DNS_Flow; -}; - -flow DNS_Flow -{ - datagram = DNS_message withcontext(connection, this); - - %member{ - set pointer_set; - BroVal dns_msg_val_; - %} - - %init{ - dns_msg_val_ = 0; - %} - - %cleanup{ - Unref(dns_msg_val_); - dns_msg_val_ = 0; - %} - - # Return a byte segment starting at in the original message. - function get_pointer(msgdata: const_bytestring, - offset: int): const_bytestring - %{ - if ( offset < 0 || offset >= msgdata.length() ) - return const_bytestring(0, 0); - - if ( pointer_set.find(offset) != pointer_set.end() ) - throw Exception("DNS pointer loop!"); - - pointer_set.insert(offset); - return const_bytestring(msgdata.begin() + offset, msgdata.end()); - %} - - function reset_pointer_set(): bool - %{ - pointer_set.clear(); - return true; - %} - - function process_dns_header(hdr: DNS_header): bool - %{ - Unref(dns_msg_val_); - - RecordVal* r = new RecordVal(dns_msg); - - r->Assign(0, new Val(${hdr.id}, TYPE_COUNT)); - r->Assign(1, new Val(${hdr.opcode}, TYPE_COUNT)); - r->Assign(2, new Val(${hdr.rcode}, TYPE_COUNT)); - r->Assign(3, new Val(${hdr.qr}, TYPE_BOOL)); - r->Assign(4, new Val(${hdr.aa}, TYPE_BOOL)); - r->Assign(5, new Val(${hdr.tc}, TYPE_BOOL)); - r->Assign(6, new Val(${hdr.rd}, TYPE_BOOL)); - r->Assign(7, new Val(${hdr.ra}, TYPE_BOOL)); - r->Assign(8, new Val(${hdr.z}, TYPE_COUNT)); - - r->Assign(9, new Val(${hdr.qdcount}, TYPE_COUNT)); - r->Assign(10, new Val(${hdr.ancount}, TYPE_COUNT)); - r->Assign(11, new Val(${hdr.nscount}, TYPE_COUNT)); - r->Assign(12, new Val(${hdr.arcount}, TYPE_COUNT)); - - dns_msg_val_ = r; - - return true; - %} - - function process_dns_question(question: DNS_question): bool - %{ - DNS_message* msg = question->msg(); - - if ( msg->header()->qr() == 0 ) - { - BifEvent::generate_dns_request( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - name_to_val(question->qname()), - question->qtype(), - question->qclass()); - } - - else if ( msg->header()->ancount() == 0 && - msg->header()->nscount() == 0 && - msg->header()->arcount() == 0 ) - { - BifEvent::generate_dns_rejected( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - name_to_val(question->qname()), - question->qtype(), - question->qclass()); - } - - return true; - %} - - function build_dns_answer(rr: DNS_rr): BroVal - %{ - RecordVal* r = new RecordVal(dns_answer); - - r->Assign(0, new Val(rr->answer_type(), TYPE_COUNT)); - r->Assign(1, name_to_val(rr->rr_name())); - r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT)); - r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT)); - r->Assign(4, new IntervalVal(double(rr->rr_ttl()), Seconds)); - - return r; - %} - - function build_dns_soa(soa: DNS_rdata_SOA): BroVal - %{ - RecordVal* r = new RecordVal(dns_soa); - - r->Assign(0, name_to_val(soa->mname())); - r->Assign(1, name_to_val(soa->rname())); - r->Assign(2, new Val(soa->serial(), TYPE_COUNT)); - r->Assign(3, new IntervalVal(double(soa->refresh()), Seconds)); - r->Assign(4, new IntervalVal(double(soa->retry()), Seconds)); - r->Assign(5, new IntervalVal(double(soa->expire()), Seconds)); - r->Assign(6, new IntervalVal(double(soa->minimum()), Seconds)); - - return r; - %} - - function build_edns_additional(rr: DNS_rr): BroVal - %{ - // We have to treat the additional record type in EDNS - // differently than a regular resource record. - RecordVal* r = new RecordVal(dns_edns_additional); - - r->Assign(0, new Val(int(rr->answer_type()), TYPE_COUNT)); - r->Assign(1, name_to_val(rr->rr_name())); - - // Type = 0x29 or 41 = EDNS - r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT)); - - // Sender's UDP payload size, per RFC 2671 4.3 - r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT)); - - // Need to break the TTL field into three components: - // initial: [------------- ttl (32) ---------------------] - // after: [DO][ ext rcode (7)][ver # (8)][ Z field (16)] - - unsigned int ercode = (rr->rr_ttl() & 0xff000000) >> 24; - unsigned int version = (rr->rr_ttl() & 0x00ff0000) >> 16; - unsigned int z = (rr->rr_ttl() & 0x0000ffff); - - int rcode = rr->msg()->header()->rcode(); - unsigned int return_error = (ercode << 8) | rcode; - - r->Assign(4, new Val(return_error, TYPE_COUNT)); - r->Assign(5, new Val(version, TYPE_COUNT)); - r->Assign(6, new Val(z, TYPE_COUNT)); - r->Assign(7, new IntervalVal(double(rr->rr_ttl()), Seconds)); - r->Assign(8, new Val(rr->msg()->header()->qr() == 0, TYPE_COUNT)); - - return r; - %} - - function process_dns_rr(rr: DNS_rr): bool - %{ - const DNS_rdata* rd = rr->rr_rdata(); - - switch ( rr->rr_type() ) { - case TYPE_A: - if ( dns_A_reply ) - { - ::uint32 addr = rd->type_a(); - BifEvent::generate_dns_A_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), build_dns_answer(rr), - new AddrVal(htonl(addr))); - } - break; - - case TYPE_A6: - if ( dns_A6_reply ) - { - ::uint32 addr[4]; - for ( unsigned int i = 0; i < 4; ++i ) - addr[i] = htonl((*rd->type_aaaa())[i]); - - BifEvent::generate_dns_A6_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), build_dns_answer(rr), - new AddrVal(addr)); - } - break; - - case TYPE_AAAA: - if ( dns_AAAA_reply ) - { - ::uint32 addr[4]; - for ( unsigned int i = 0; i < 4; ++i ) - addr[i] = htonl((*rd->type_aaaa())[i]); - - BifEvent::generate_dns_AAAA_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), build_dns_answer(rr), - new AddrVal(addr)); - } - break; - - case TYPE_NS: - if ( dns_NS_reply ) - { - BifEvent::generate_dns_NS_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_dns_answer(rr), - name_to_val(rr->rr_rdata()->type_ns())); - } - break; - - case TYPE_CNAME: - if ( dns_CNAME_reply ) - { - BifEvent::generate_dns_CNAME_reply( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_dns_answer(rr), - name_to_val(rr->rr_rdata()->type_cname())); - } - break; - - case TYPE_SOA: - if ( dns_SOA_reply ) - { - BifEvent::generate_dns_SOA_reply( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_dns_answer(rr), - build_dns_soa(rr->rr_rdata()->type_soa())); - } - break; - - case TYPE_PTR: - if ( dns_PTR_reply ) - { - BifEvent::generate_dns_PTR_reply( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_dns_answer(rr), - name_to_val(rr->rr_rdata()->type_ptr())); - } - break; - - case TYPE_MX: - if ( dns_MX_reply ) - { - BifEvent::generate_dns_MX_reply( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_dns_answer(rr), - name_to_val(rr->rr_rdata()->type_mx()->name()), - rr->rr_rdata()->type_mx()->preference()); - } - break; - - case TYPE_EDNS: - if ( dns_EDNS_addl ) - { - BifEvent::generate_dns_EDNS_addl( - connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - dns_msg_val_->Ref(), - build_edns_additional(rr)); - } - break; - } - - return true; - %} -}; - -refine typeattr DNS_header += &let { - proc_dns_header = $context.flow.process_dns_header(this); -}; - -refine typeattr DNS_question += &let { - proc_dns_question = $context.flow.process_dns_question(this); -}; - -refine typeattr DNS_rr += &let { - proc_dns_rr = $context.flow.process_dns_rr(this); -}; diff --git a/src/dns-protocol.pac b/src/dns-protocol.pac deleted file mode 100644 index fbeb9d0fa3..0000000000 --- a/src/dns-protocol.pac +++ /dev/null @@ -1,215 +0,0 @@ -enum DNS_answer_type { - DNS_QUESTION, - DNS_ANSWER, - DNS_AUTHORITY, - DNS_ADDITIONAL, -}; - -enum DNS_rdata_type { - TYPE_A = 1, - TYPE_NS = 2, - TYPE_MD = 3, - TYPE_MF = 4, - TYPE_CNAME = 5, - TYPE_SOA = 6, - TYPE_MB = 7, - TYPE_MG = 8, - TYPE_MR = 9, - TYPE_NULL = 10, - TYPE_WKS = 11, - TYPE_PTR = 12, - TYPE_HINFO = 13, - TYPE_MINFO = 14, - TYPE_MX = 15, - TYPE_TXT = 16, - TYPE_AAAA = 28, # IPv6 (RFC 1886) - TYPE_NBS = 32, # Netbios name (RFC 1002) - TYPE_A6 = 38, # IPv6 with indirection (RFC 2874) - TYPE_EDNS = 41, # < OPT pseudo-RR (RFC 2671) -}; - -# 1 1 1 1 1 1 -# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | ID | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# |QR| Opcode |AA|TC|RD|RA| Z | RCODE | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | QDCOUNT | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | ANCOUNT | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | NSCOUNT | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | ARCOUNT | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type DNS_header = record { - id : uint16; - qrop : uint16; - qdcount : uint16; - ancount : uint16; - nscount : uint16; - arcount : uint16; -} &let { - qr: bool = qrop >> 15; - opcode: uint8 = (qrop >> 11) & 0xf; - aa: bool = (qrop >> 10) & 0x1; - tc: bool = (qrop >> 9) & 0x1; - rd: bool = (qrop >> 8) & 0x1; - ra: bool = (qrop >> 7) & 0x1; - z: uint8 = (qrop >> 4) & 0x7; - rcode: uint8 = qrop & 0xf; -}; - -type DNS_label(msg: DNS_message) = record { - length: uint8; - data: case label_type of { - 0 -> label: bytestring &length = length; - 3 -> ptr_lo: uint8; - }; -} &let { - label_type: uint8 = length >> 6; - last: bool = (length == 0) || (label_type == 3); - - # A name pointer. - ptr: DNS_name(msg) - withinput $context.flow.get_pointer(msg.sourcedata, - ((length & 0x3f) << 8) | ptr_lo) - &if(label_type == 3); - - clear_pointer_set: bool = $context.flow.reset_pointer_set() - &if(last); -}; - -type DNS_name(msg: DNS_message) = record { - labels: DNS_label(msg)[] &until($element.last); -}; - -type DNS_char_string = record { - length: uint8; - data: bytestring &length = length; -}; - -# 1 1 1 1 1 1 -# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | | -# / QNAME / -# / / -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | QTYPE | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | QCLASS | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type DNS_question(msg: DNS_message) = record { - qname: DNS_name(msg); - qtype: uint16; - qclass: uint16; -}; - -type DNS_rdata_MX(msg: DNS_message) = record { - preference: uint16; - name: DNS_name(msg); -}; - -type DNS_rdata_SOA(msg: DNS_message) = record { - mname: DNS_name(msg); - rname: DNS_name(msg); - serial: uint32; - refresh: uint32; - retry: uint32; - expire: uint32; - minimum: uint32; -}; - -type DNS_rdata_WKS = record { - address: uint32; - protocol: uint8; - bitmap: bytestring &restofdata; -}; - -type DNS_rdata_HINFO = record { - cpu: DNS_char_string; - os: DNS_char_string; -}; - -type DNS_rdata(msg: DNS_message, - rr_type: uint16, - rr_class: uint16) = case rr_type of { - - TYPE_A -> type_a: uint32 &check(rr_class == CLASS_IN); - TYPE_NS -> type_ns: DNS_name(msg); - TYPE_CNAME -> type_cname: DNS_name(msg); - TYPE_SOA -> type_soa: DNS_rdata_SOA(msg); - TYPE_PTR -> type_ptr: DNS_name(msg); - TYPE_MX -> type_mx: DNS_rdata_MX(msg); - TYPE_AAAA, TYPE_A6 - -> type_aaaa: uint32[4]; - - # TYPE_WKS -> type_wks: DNS_rdata_WKS; - # TYPE_HINFO -> type_hinfo: DNS_rdata_HINFO; - # TYPE_TXT -> type_txt: bytestring &restofdata; - - # 3 -> type_md: DNS_rdata_MD; - # 4 -> type_mf: DNS_rdata_MF; - # 7 -> type_mb: DNS_rdata_MB; - # 8 -> type_mg: DNS_rdata_MG; - # 9 -> type_mr: DNS_rdata_MR; - # 10 -> type_null: DNS_rdata_NULL; - # 14 -> type_minfo: DNS_rdata_MINFO; - # 32 -> type_nbs: DNS_rdata_NBS; - - default -> unknown: bytestring &restofdata; -}; - -# 1 1 1 1 1 1 -# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | | -# / / -# / NAME / -# | | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | TYPE | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | CLASS | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | TTL | -# | | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -# | RDLENGTH | -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| -# / RDATA / -# / / -# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type DNS_rr(msg: DNS_message, answer_type: DNS_answer_type) = record { - rr_name: DNS_name(msg); - rr_type: uint16; - rr_class: uint16; - rr_ttl: uint32; - rr_rdlength: uint16; - rr_rdata: DNS_rdata(msg, rr_type, rr_class) &length = rr_rdlength; -}; - -# +---------------------+ -# | Header | -# +---------------------+ -# | Question | the question for the name server -# +---------------------+ -# | Answer | RRs answering the question -# +---------------------+ -# | Authority | RRs pointing toward an authority -# +---------------------+ -# | Additional | RRs holding additional information -# +---------------------+ - -type DNS_message = record { - header: DNS_header; - question: DNS_question(this)[header.qdcount]; - answer: DNS_rr(this, DNS_ANSWER)[header.ancount]; - authority: DNS_rr(this, DNS_AUTHORITY)[header.nscount]; - additional: DNS_rr(this, DNS_ADDITIONAL)[header.arcount]; -} &byteorder = bigendian, &exportsourcedata; diff --git a/src/dns.pac b/src/dns.pac deleted file mode 100644 index aeffdf0bc7..0000000000 --- a/src/dns.pac +++ /dev/null @@ -1,9 +0,0 @@ -%include bro.pac - -analyzer DNS withcontext { - connection: DNS_Conn; - flow: DNS_Flow; -}; - -%include dns-protocol.pac -%include dns-analyzer.pac diff --git a/src/dns_tcp.pac b/src/dns_tcp.pac deleted file mode 100644 index d31ff58c6e..0000000000 --- a/src/dns_tcp.pac +++ /dev/null @@ -1,45 +0,0 @@ -%extern{ -#include "dns_pac.h" // for DNS_Conn -%} - -%include bro.pac - -analyzer DNS_on_TCP withcontext { - connection: DNS_TCP_Conn; - flow: DNS_TCP_Flow; -}; - -type DNS_TCP_PDU(is_orig: bool) = record { - msglen: uint16; - msg: bytestring &length = msglen; -} &byteorder = bigendian, &length = 2 + msglen, &let { - deliver: bool = $context.connection.deliver_dns_message(is_orig, msg); -}; - -connection DNS_TCP_Conn(bro_analyzer: BroAnalyzer) { - upflow = DNS_TCP_Flow(true); - downflow = DNS_TCP_Flow(false); - - %member{ - DNS::DNS_Conn *abstract_dns_connection_; - %} - - %init{ - abstract_dns_connection_ = new DNS::DNS_Conn(bro_analyzer); - %} - - %cleanup{ - delete abstract_dns_connection_; - abstract_dns_connection_ = 0; - %} - - function deliver_dns_message(is_orig: bool, msg: const_bytestring): bool - %{ - abstract_dns_connection_->NewData(is_orig, msg.begin(), msg.end()); - return true; - %} -}; - -flow DNS_TCP_Flow(is_orig: bool) { - flowunit = DNS_TCP_PDU(is_orig) withcontext(connection, this); -}; diff --git a/src/event.bif b/src/event.bif index 23ebc0591b..df22902094 100644 --- a/src/event.bif +++ b/src/event.bif @@ -1,7 +1,9 @@ -##! The events that the C/C++ core of Bro can generate. This is mostly -##! consisting of high-level network events that protocol analyzers detect, -##! but there are also several general-utility events generated by internal -##! Bro frameworks. +##! The protocol-independent events that the C/C++ core of Bro can generate. +##! +##! This is mostly events not related to a specific transport- or +##! application-layer protocol, but also includes a few that may be generated +##! by more than one protocols analyzer (like events generated by both UDP and +##! TCP analysis.) # # Documentation conventions: @@ -59,69 +61,6 @@ event bro_init%(%); ## is not generated. event bro_done%(%); -## Generated when an internal DNS lookup produces the same result as last time. -## Bro keeps an internal DNS cache for host names and IP addresses it has -## already resolved. This event is generated when a subsequent lookup returns -## the same result as stored in the cache. -## -## dm: A record describing the new resolver result (which matches the old one). -## -## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified -event dns_mapping_valid%(dm: dns_mapping%); - -## Generated when an internal DNS lookup got no answer even though it had -## succeeded in the past. Bro keeps an internal DNS cache for host names and IP -## addresses it has already resolved. This event is generated when a -## subsequent lookup does not produce an answer even though we have -## already stored a result in the cache. -## -## dm: A record describing the old resolver result. -## -## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_valid -event dns_mapping_unverified%(dm: dns_mapping%); - -## Generated when an internal DNS lookup succeeded but an earlier attempt -## did not. Bro keeps an internal DNS cache for host names and IP -## addresses it has already resolved. This event is generated when a subsequent -## lookup produces an answer for a query that was marked as failed in the cache. -## -## dm: A record describing the new resolver result. -## -## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_unverified -## dns_mapping_valid -event dns_mapping_new_name%(dm: dns_mapping%); - -## Generated when an internal DNS lookup returned zero answers even though it -## had succeeded in the past. Bro keeps an internal DNS cache for host names -## and IP addresses it has already resolved. This event is generated when -## on a subsequent lookup we receive an answer that is empty even -## though we have already stored a result in the cache. -## -## dm: A record describing the old resolver result. -## -## .. bro:see:: dns_mapping_altered dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid -event dns_mapping_lost_name%(dm: dns_mapping%); - -## Generated when an internal DNS lookup produced a different result than in -## the past. Bro keeps an internal DNS cache for host names and IP addresses -## it has already resolved. This event is generated when a subsequent lookup -## returns a different answer than we have stored in the cache. -## -## dm: A record describing the new resolver result. -## -## old_addrs: Addresses that used to be part of the returned set for the query -## described by *dm*, but are not anymore. -## -## new_addrs: Addresses that were not part of the returned set for the query -## described by *dm*, but now are. -## -## .. bro:see:: dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid -event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr_set%); - ## Generated for every new connection. This event is raised with the first ## packet of a previously unknown connection. Bro uses a flow-based definition ## of "connection" here that includes not only TCP sessions but also UDP and @@ -134,7 +73,7 @@ event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused ## connection_state_remove connection_status_update connection_timeout -## expected_connection_seen new_connection_contents partial_connection +## scheduled_analyzer_applied new_connection_contents partial_connection ## ## .. note:: ## @@ -157,9 +96,10 @@ event new_connection%(c: connection%); ## e: The new encapsulation. event tunnel_changed%(c: connection, e: EncapsulatingConnVector%); -## Generated when reassembly starts for a TCP connection. This event is raised -## at the moment when Bro's TCP analyzer enables stream reassembly for a -## connection. +## Generated when a TCP connection timed out. This event is raised when +## no activity was seen for an interval of at least +## :bro:id:`tcp_connection_linger`, and either one endpoint has already +## closed the connection or one side never became active. ## ## c: The connection. ## @@ -167,148 +107,19 @@ event tunnel_changed%(c: connection, e: EncapsulatingConnVector%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused -## connection_state_remove connection_status_update connection_timeout -## expected_connection_seen new_connection partial_connection -event new_connection_contents%(c: connection%); - -## Generated for an unsuccessful connection attempt. This event is raised when -## an originator unsuccessfully attempted to establish a connection. -## "Unsuccessful" is defined as at least :bro:id:`tcp_attempt_delay` seconds -## having elapsed since the originator first sent a connection establishment -## packet to the destination without seeing a reply. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_established -## connection_external connection_finished connection_first_ACK -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_attempt%(c: connection%); - -## Generated when a SYN-ACK packet is seen in response to a SYN packet during -## a TCP handshake. The final ACK of the handshake in response to SYN-ACK may -## or may not occur later, one way to tell is to check the *history* field of -## :bro:type:`connection` to see if the originator sent an ACK, indicated by -## 'A' in the history string. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_external connection_finished connection_first_ACK -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_established%(c: connection%); - -## Generated for a new active TCP connection if Bro did not see the initial -## handshake. This event is raised when Bro has observed traffic from each -## endpoint, but the activity did not begin with the usual connection -## establishment. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_partial_close -## connection_pending connection_rejected connection_reset connection_reused -## connection_state_remove connection_status_update connection_timeout -## expected_connection_seen new_connection new_connection_contents -## -event partial_connection%(c: connection%); - -## Generated when a previously inactive endpoint attempts to close a TCP -## connection via a normal FIN handshake or an abort RST sequence. When the -## endpoint sent one of these packets, Bro waits -## :bro:id:`tcp_partial_close_delay` prior to generating the event, to give -## the other endpoint a chance to close the connection normally. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_partial_close%(c: connection%); - -## Generated for a TCP connection that finished normally. The event is raised -## when a regular FIN handshake from both endpoints was observed. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_first_ACK -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_finished%(c: connection%); - -## Generated when one endpoint of a TCP connection attempted to gracefully close -## the connection, but the other endpoint is in the TCP_INACTIVE state. This can -## happen due to split routing, in which Bro only sees one side of a connection. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_half_finished%(c: connection%); - -## Generated for a rejected TCP connection. This event is raised when an -## originator attempted to setup a TCP connection but the responder replied -## with a RST packet denying it. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_partial_close -## connection_pending connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -## -## c: The connection. +## connection_state_remove connection_status_update +## scheduled_analyzer_applied new_connection new_connection_contents +## partial_connection ## ## .. note:: ## -## If the responder does not respond at all, :bro:id:`connection_attempt` is -## raised instead. If the responder initially accepts the connection but -## aborts it later, Bro first generates :bro:id:`connection_established` -## and then :bro:id:`connection_reset`. -event connection_rejected%(c: connection%); - -## Generated when an endpoint aborted a TCP connection. The event is raised -## when one endpoint of an established TCP connection aborted by sending a RST -## packet. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_partial_close -## connection_pending connection_rejected connection_reused -## connection_state_remove connection_status_update connection_timeout -## expected_connection_seen new_connection new_connection_contents -## partial_connection -event connection_reset%(c: connection%); - -## Generated for each still-open connection when Bro terminates. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_partial_close -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection bro_done -event connection_pending%(c: connection%); +## The precise semantics of this event can be unintuitive as it only +## covers a subset of cases where a connection times out. Often, handling +## :bro:id:`connection_state_remove` is the better option. That one will be +## generated reliably when an interval of ``tcp_inactivity_timeout`` has +## passed without any activity seen (but also for all other ways a +## connection may terminate). +event connection_timeout%(c: connection%); ## Generated when a connection's internal state is about to be removed from ## memory. Bro generates this event reliably once for every connection when it @@ -323,75 +134,11 @@ event connection_pending%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused -## connection_status_update connection_timeout expected_connection_seen +## connection_status_update connection_timeout scheduled_analyzer_applied ## new_connection new_connection_contents partial_connection udp_inactivity_timeout ## tcp_inactivity_timeout icmp_inactivity_timeout conn_stats event connection_state_remove%(c: connection%); -## Generated for a SYN packet. Bro raises this event for every SYN packet seen -## by its TCP analyzer. -## -## c: The connection. -## -## pkt: Information extracted from the SYN packet. -## -## .. bro:see:: connection_EOF connection_attempt connection_established -## connection_external connection_finished connection_first_ACK -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -## -## .. note:: -## -## This event has quite low-level semantics and can potentially be expensive -## to generate. It should only be used if one really needs the specific -## information passed into the handler via the ``pkt`` argument. If not, -## handling one of the other ``connection_*`` events is typically the -## better approach. -event connection_SYN_packet%(c: connection, pkt: SYN_packet%); - -## Generated for the first ACK packet seen for a TCP connection from -## its *originator*. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -## -## .. note:: -## -## This event has quite low-level semantics and should be used only rarely. -event connection_first_ACK%(c: connection%); - -## Generated when a TCP connection timed out. This event is raised when -## no activity was seen for an interval of at least -## :bro:id:`tcp_connection_linger`, and either one endpoint has already -## closed the connection or one side never became active. -## -## c: The connection. -## -## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt -## connection_established connection_external connection_finished -## connection_first_ACK connection_half_finished connection_partial_close -## connection_pending connection_rejected connection_reset connection_reused -## connection_state_remove connection_status_update expected_connection_seen -## new_connection new_connection_contents partial_connection -## -## .. note:: -## -## The precise semantics of this event can be unintuitive as it only -## covers a subset of cases where a connection times out. Often, handling -## :bro:id:`connection_state_remove` is the better option. That one will be -## generated reliably when an interval of ``tcp_inactivity_timeout`` has -## passed without any activity seen (but also for all other ways a -## connection may terminate). -event connection_timeout%(c: connection%); - ## Generated when a connection 4-tuple is reused. This event is raised when Bro ## sees a new TCP session or UDP flow using a 4-tuple matching that of an ## earlier connection it still considers active. @@ -402,7 +149,7 @@ event connection_timeout%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_state_remove -## connection_status_update connection_timeout expected_connection_seen +## connection_status_update connection_timeout scheduled_analyzer_applied ## new_connection new_connection_contents partial_connection event connection_reused%(c: connection%); @@ -416,7 +163,7 @@ event connection_reused%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused -## connection_state_remove connection_timeout expected_connection_seen +## connection_state_remove connection_timeout scheduled_analyzer_applied ## new_connection new_connection_contents partial_connection event connection_status_update%(c: connection%); @@ -434,22 +181,6 @@ event connection_status_update%(c: connection%); ## .. bro:see:: connection_established new_connection event connection_flow_label_changed%(c: connection, is_orig: bool, old_label: count, new_label: count%); -## Generated at the end of reassembled TCP connections. The TCP reassembler -## raised the event once for each endpoint of a connection when it finished -## reassembling the corresponding side of the communication. -## -## c: The connection. -## -## is_orig: True if the event is raised for the originator side. -## -## .. bro:see:: connection_SYN_packet connection_attempt connection_established -## connection_external connection_finished connection_first_ACK -## connection_half_finished connection_partial_close connection_pending -## connection_rejected connection_reset connection_reused connection_state_remove -## connection_status_update connection_timeout expected_connection_seen -## new_connection new_connection_contents partial_connection -event connection_EOF%(c: connection, is_orig: bool%); - ## Generated for a new connection received from the communication subsystem. ## Remote peers can inject packets into Bro's packet loop, for example via ## :doc:`Broccoli `. The communication system @@ -460,15 +191,26 @@ event connection_EOF%(c: connection, is_orig: bool%); ## tag: TODO. event connection_external%(c: connection, tag: string%); +## Generated when a UDP session for a supported protocol has finished. Some of +## Bro's application-layer UDP analyzers flag the end of a session by raising +## this event. Currently, the analyzers for DNS, NTP, Netbios, Syslog, AYIYA, +## Teredo, and GTPv1 support this. +## +## u: The connection record for the corresponding UDP flow. +## +## .. bro:see:: udp_contents udp_reply udp_request +event udp_session_done%(u: connection%); + ## Generated when a connection is seen that is marked as being expected. -## The function :bro:id:`expect_connection` tells Bro to expect a particular -## connection to come up, and which analyzer to associate with it. Once the -## first packet of such a connection is indeed seen, this event is raised. +## The function :bro:id:`Analyzer::schedule_analyzer` tells Bro to expect a +## particular connection to come up, and which analyzer to associate with it. +## Once the first packet of such a connection is indeed seen, this event is +## raised. ## ## c: The connection. ## ## a: The analyzer that was scheduled for the connection with the -## :bro:id:`expect_connection` call. When the event is raised, that +## :bro:id:`Analyzer::schedule_analyzer` call. When the event is raised, that ## analyzer will already have been activated to process the connection. The ## ``count`` is one of the ``ANALYZER_*`` constants, e.g., ``ANALYZER_HTTP``. ## @@ -481,7 +223,7 @@ event connection_external%(c: connection, tag: string%); ## ## .. todo:: We don't have a good way to document the automatically generated ## ``ANALYZER_*`` constants right now. -event expected_connection_seen%(c: connection, a: count%); +event scheduled_analyzer_applied%(c: connection, a: Analyzer::Tag%); ## Generated for every packet Bro sees. This is a very low-level and expensive ## event that should be avoided when at all possible. It's usually infeasible to @@ -522,135 +264,6 @@ event esp_packet%(p: pkt_hdr%); ## .. bro:see:: new_packet tcp_packet ipv6_ext_headers event mobile_ipv6_message%(p: pkt_hdr%); -## Generated for any IPv6 packet encapsulated in a Teredo tunnel. -## See :rfc:`4380` for more information about the Teredo protocol. -## -## outer: The Teredo tunnel connection. -## -## inner: The Teredo-encapsulated IPv6 packet header and transport header. -## -## .. bro:see:: teredo_authentication teredo_origin_indication teredo_bubble -## -## .. note:: Since this event may be raised on a per-packet basis, handling -## it may become particularly expensive for real-time analysis. -event teredo_packet%(outer: connection, inner: teredo_hdr%); - -## Generated for IPv6 packets encapsulated in a Teredo tunnel that -## use the Teredo authentication encapsulation method. -## See :rfc:`4380` for more information about the Teredo protocol. -## -## outer: The Teredo tunnel connection. -## -## inner: The Teredo-encapsulated IPv6 packet header and transport header. -## -## .. bro:see:: teredo_packet teredo_origin_indication teredo_bubble -## -## .. note:: Since this event may be raised on a per-packet basis, handling -## it may become particularly expensive for real-time analysis. -event teredo_authentication%(outer: connection, inner: teredo_hdr%); - -## Generated for IPv6 packets encapsulated in a Teredo tunnel that -## use the Teredo origin indication encapsulation method. -## See :rfc:`4380` for more information about the Teredo protocol. -## -## outer: The Teredo tunnel connection. -## -## inner: The Teredo-encapsulated IPv6 packet header and transport header. -## -## .. bro:see:: teredo_packet teredo_authentication teredo_bubble -## -## .. note:: Since this event may be raised on a per-packet basis, handling -## it may become particularly expensive for real-time analysis. -event teredo_origin_indication%(outer: connection, inner: teredo_hdr%); - -## Generated for Teredo bubble packets. That is, IPv6 packets encapsulated -## in a Teredo tunnel that have a Next Header value of :bro:id:`IPPROTO_NONE`. -## See :rfc:`4380` for more information about the Teredo protocol. -## -## outer: The Teredo tunnel connection. -## -## inner: The Teredo-encapsulated IPv6 packet header and transport header. -## -## .. bro:see:: teredo_packet teredo_authentication teredo_origin_indication -## -## .. note:: Since this event may be raised on a per-packet basis, handling -## it may become particularly expensive for real-time analysis. -event teredo_bubble%(outer: connection, inner: teredo_hdr%); - -## Generated for any GTP message with a GTPv1 header. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -event gtpv1_message%(c: connection, hdr: gtpv1_hdr%); - -## Generated for GTPv1 G-PDU packets. That is, packets with a UDP payload -## that includes a GTP header followed by an IPv4 or IPv6 packet. -## -## outer: The GTP outer tunnel connection. -## -## inner_gtp: The GTP header. -## -## inner_ip: The inner IP and transport layer packet headers. -## -## .. note:: Since this event may be raised on a per-packet basis, handling -## it may become particularly expensive for real-time analysis. -event gtpv1_g_pdu_packet%(outer: connection, inner_gtp: gtpv1_hdr, inner_ip: pkt_hdr%); - -## Generated for GTPv1-C Create PDP Context Request messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_create_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_create_pdp_ctx_request_elements%); - -## Generated for GTPv1-C Create PDP Context Response messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_create_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_create_pdp_ctx_response_elements%); - -## Generated for GTPv1-C Update PDP Context Request messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_update_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_update_pdp_ctx_request_elements%); - -## Generated for GTPv1-C Update PDP Context Response messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_update_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_update_pdp_ctx_response_elements%); - -## Generated for GTPv1-C Delete PDP Context Request messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_delete_pdp_ctx_request%(c: connection, hdr: gtpv1_hdr, elements: gtp_delete_pdp_ctx_request_elements%); - -## Generated for GTPv1-C Delete PDP Context Response messages. -## -## c: The connection over which the message is sent. -## -## hdr: The GTPv1 header. -## -## elements: The set of Information Elements comprising the message. -event gtpv1_delete_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gtp_delete_pdp_ctx_response_elements%); - ## Generated for every packet that has a non-empty transport-layer payload. ## This is a very low-level and expensive event that should be avoided when ## at all possible. It's usually infeasible to handle when processing even @@ -665,85 +278,6 @@ event gtpv1_delete_pdp_ctx_response%(c: connection, hdr: gtpv1_hdr, elements: gt ## .. bro:see:: new_packet tcp_packet event packet_contents%(c: connection, contents: string%); -## Generated for every TCP packet. This is a very low-level and expensive event -## that should be avoided when at all possible. It's usually infeasible to -## handle when processing even medium volumes of traffic in real-time. It's -## slightly better than :bro:id:`new_packet` because it affects only TCP, but -## not much. That said, if you work from a trace and want to do some -## packet-level analysis, it may come in handy. -## -## c: The connection the packet is part of. -## -## is_orig: True if the packet was sent by the connection's originator. -## -## flags: A string with the packet's TCP flags. In the string, each character -## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN; -## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH. -## -## seq: The packet's TCP sequence number. -## -## ack: The packet's ACK number. -## -## len: The length of the TCP payload, as specified in the packet header. -## -## payload: The raw TCP payload. Note that this may be shorter than *len* if -## the packet was not fully captured. -## -## .. bro:see:: new_packet packet_contents tcp_option tcp_contents tcp_rexmit -event tcp_packet%(c: connection, is_orig: bool, flags: string, seq: count, ack: count, len: count, payload: string%); - -## Generated for each option found in a TCP header. Like many of the ``tcp_*`` -## events, this is a very low-level event and potentially expensive as it may -## be raised very often. -## -## c: The connection the packet is part of. -## -## is_orig: True if the packet was sent by the connection's originator. -## -## opt: The numerical option number, as found in the TCP header. -## -## optlen: The length of the options value. -## -## .. bro:see:: tcp_packet tcp_contents tcp_rexmit -## -## .. note:: There is currently no way to get the actual option value, if any. -event tcp_option%(c: connection, is_orig: bool, opt: count, optlen: count%); - -## Generated for each chunk of reassembled TCP payload. When content delivery is -## enabled for a TCP connection (via :bro:id:`tcp_content_delivery_ports_orig`, -## :bro:id:`tcp_content_delivery_ports_resp`, -## :bro:id:`tcp_content_deliver_all_orig`, -## :bro:id:`tcp_content_deliver_all_resp`), this event is raised for each chunk -## of in-order payload reconstructed from the packet stream. Note that this -## event is potentially expensive if many connections carry significant amounts -## of data as then all that data needs to be passed on to the scripting layer. -## -## c: The connection the payload is part of. -## -## is_orig: True if the packet was sent by the connection's originator. -## -## seq: The sequence number corresponding to the first byte of the payload -## chunk. -## -## contents: The raw payload, which will be non-empty. -## -## .. bro:see:: tcp_packet tcp_option tcp_rexmit -## tcp_content_delivery_ports_orig tcp_content_delivery_ports_resp -## tcp_content_deliver_all_resp tcp_content_deliver_all_orig -## -## .. note:: -## -## The payload received by this event is the same that is also passed into -## application-layer protocol analyzers internally. Subsequent invocations of -## this event for the same connection receive non-overlapping in-order chunks -## of its TCP payload stream. It is however undefined what size each chunk -## has; while Bro passes the data on as soon as possible, specifics depend on -## network-level effects such as latency, acknowledgements, reordering, etc. -event tcp_contents%(c: connection, is_orig: bool, seq: count, contents: string%); - -## TODO. -event tcp_rexmit%(c: connection, is_orig: bool, seq: count, len: count, data_in_flight: count, window: count%); - ## Generated when Bro detects a TCP retransmission inconsistency. When ## reassembling a TCP stream, Bro buffers all payload until it sees the ## responder acking it. If during that time, the sender resends a chunk of @@ -831,7 +365,6 @@ event content_gap%(c: connection, is_orig: bool, seq: count, length: count%); ## is exceeded. event gap_report%(dt: interval, info: gap_info%); - ## Generated when a protocol analyzer confirms that a connection is indeed ## using that protocol. Bro's dynamic protocol detection heuristically activates ## analyzers as soon as it believes a connection *could* be using a particular @@ -841,8 +374,8 @@ event gap_report%(dt: interval, info: gap_info%); ## c: The connection. ## ## atype: The type of the analyzer confirming that its protocol is in -## use. The value is one of the ``ANALYZER_*`` constants. For example, -## ``ANALYZER_HTTP`` means the HTTP analyzers determined that it's indeed +## use. The value is one of the ``Analyzer::ANALYZER_*`` constants. For example, +## ``Analyzer::ANALYZER_HTTP`` means the HTTP analyzer determined that it's indeed ## parsing an HTTP connection. ## ## aid: A unique integer ID identifying the specific *instance* of the @@ -857,7 +390,7 @@ event gap_report%(dt: interval, info: gap_info%); ## Bro's default scripts use this event to determine the ``service`` column ## of :bro:type:`Conn::Info`: once confirmed, the protocol will be listed ## there (and thus in ``conn.log``). -event protocol_confirmation%(c: connection, atype: count, aid: count%); +event protocol_confirmation%(c: connection, atype: Analyzer::Tag, aid: count%); ## Generated when a protocol analyzer determines that a connection it is parsing ## is not conforming to the protocol it expects. Bro's dynamic protocol @@ -869,8 +402,8 @@ event protocol_confirmation%(c: connection, atype: count, aid: count%); ## c: The connection. ## ## atype: The type of the analyzer confirming that its protocol is in -## use. The value is one of the ``ANALYZER_*`` constants. For example, -## ``ANALYZER_HTTP`` means the HTTP analyzers determined that it's indeed +## use. The value is one of the ``Analyzer::ANALYZER_*`` constants. For example, +## ``Analyzer::ANALYZER_HTTP`` means the HTTP analyzer determined that it's indeed ## parsing an HTTP connection. ## ## aid: A unique integer ID identifying the specific *instance* of the @@ -888,356 +421,7 @@ event protocol_confirmation%(c: connection, atype: count, aid: count%); ## :bro:id:`disable_analyzer` if it's parsing the wrong protocol. That's ## however a script-level decision and not done automatically by the event ## engine. -event protocol_violation%(c: connection, atype: count, aid: count, reason: string%); - -## Generated for each packet sent by a UDP flow's originator. This a potentially -## expensive event due to the volume of UDP traffic and should be used with -## care. -## -## u: The connection record for the corresponding UDP flow. -## -## .. bro:see:: udp_contents udp_reply udp_session_done -event udp_request%(u: connection%); - -## Generated for each packet sent by a UDP flow's responder. This a potentially -## expensive event due to the volume of UDP traffic and should be used with -## care. -## -## u: The connection record for the corresponding UDP flow. -## -## .. bro:see:: udp_contents udp_request udp_session_done -event udp_reply%(u: connection%); - -## Generated for UDP packets to pass on their payload. As the number of UDP -## packets can be very large, this event is normally raised only for those on -## ports configured in :bro:id:`udp_content_delivery_ports_orig` (for packets -## sent by the flow's originator) or :bro:id:`udp_content_delivery_ports_resp` -## (for packets sent by the flow's responder). However, delivery can be enabled -## for all UDP request and reply packets by setting -## :bro:id:`udp_content_deliver_all_orig` or -## :bro:id:`udp_content_deliver_all_resp`, respectively. Note that this -## event is also raised for all matching UDP packets, including empty ones. -## -## u: The connection record for the corresponding UDP flow. -## -## is_orig: True if the event is raised for the originator side. -## -## contents: TODO. -## -## .. bro:see:: udp_reply udp_request udp_session_done -## udp_content_deliver_all_orig udp_content_deliver_all_resp -## udp_content_delivery_ports_orig udp_content_delivery_ports_resp -event udp_contents%(u: connection, is_orig: bool, contents: string%); - -## Generated when a UDP session for a supported protocol has finished. Some of -## Bro's application-layer UDP analyzers flag the end of a session by raising -## this event. Currently, the analyzers for DNS, NTP, Netbios, Syslog, AYIYA, -## Teredo, and GTPv1 support this. -## -## u: The connection record for the corresponding UDP flow. -## -## .. bro:see:: udp_contents udp_reply udp_request -event udp_session_done%(u: connection%); - -## Generated for all ICMP messages that are not handled separately with -## dedicated ICMP events. Bro's ICMP analyzer handles a number of ICMP messages -## directly with dedicated events. This event acts as a fallback for those it -## doesn't. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard -## connection record *c*. -## -## .. bro:see:: icmp_error_message -event icmp_sent%(c: connection, icmp: icmp_conn%); - -## Generated for ICMP *echo request* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard -## connection record *c*. -## -## id: The *echo request* identifier. -## -## seq: The *echo request* sequence number. -## -## payload: The message-specific data of the packet payload, i.e., everything -## after the first 8 bytes of the ICMP header. -## -## .. bro:see:: icmp_echo_reply -event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); - -## Generated for ICMP *echo reply* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## id: The *echo reply* identifier. -## -## seq: The *echo reply* sequence number. -## -## payload: The message-specific data of the packet payload, i.e., everything -## after the first 8 bytes of the ICMP header. -## -## .. bro:see:: icmp_echo_request -event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); - -## Generated for all ICMPv6 error messages that are not handled -## separately with dedicated events. Bro's ICMP analyzer handles a number -## of ICMP error messages directly with dedicated events. This event acts -## as a fallback for those it doesn't. -## -## See `Wikipedia -## `__ for more -## information about the ICMPv6 protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard -## connection record *c*. -## -## code: The ICMP code of the error message. -## -## context: A record with specifics of the original packet that the message -## refers to. -## -## .. bro:see:: icmp_unreachable icmp_packet_too_big -## icmp_time_exceeded icmp_parameter_problem -event icmp_error_message%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); - -## Generated for ICMP *destination unreachable* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## code: The ICMP code of the *unreachable* message. -## -## context: A record with specifics of the original packet that the message -## refers to. *Unreachable* messages should include the original IP -## header from the packet that triggered them, and Bro parses that -## into the *context* structure. Note that if the *unreachable* -## includes only a partial IP header for some reason, no -## fields of *context* will be filled out. -## -## .. bro:see:: icmp_error_message icmp_packet_too_big -## icmp_time_exceeded icmp_parameter_problem -event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); - -## Generated for ICMPv6 *packet too big* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMPv6 protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## code: The ICMP code of the *too big* message. -## -## context: A record with specifics of the original packet that the message -## refers to. *Too big* messages should include the original IP header -## from the packet that triggered them, and Bro parses that into -## the *context* structure. Note that if the *too big* includes only -## a partial IP header for some reason, no fields of *context* will -## be filled out. -## -## .. bro:see:: icmp_error_message icmp_unreachable -## icmp_time_exceeded icmp_parameter_problem -event icmp_packet_too_big%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); - -## Generated for ICMP *time exceeded* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## code: The ICMP code of the *exceeded* message. -## -## context: A record with specifics of the original packet that the message -## refers to. *Unreachable* messages should include the original IP -## header from the packet that triggered them, and Bro parses that -## into the *context* structure. Note that if the *exceeded* includes -## only a partial IP header for some reason, no fields of *context* -## will be filled out. -## -## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big -## icmp_parameter_problem -event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); - -## Generated for ICMPv6 *parameter problem* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMPv6 protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## code: The ICMP code of the *parameter problem* message. -## -## context: A record with specifics of the original packet that the message -## refers to. *Parameter problem* messages should include the original -## IP header from the packet that triggered them, and Bro parses that -## into the *context* structure. Note that if the *parameter problem* -## includes only a partial IP header for some reason, no fields -## of *context* will be filled out. -## -## .. bro:see:: icmp_error_message icmp_unreachable icmp_packet_too_big -## icmp_time_exceeded -event icmp_parameter_problem%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); - -## Generated for ICMP *router solicitation* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## options: Any Neighbor Discovery options included with message (:rfc:`4861`). -## -## .. bro:see:: icmp_router_advertisement -## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect -event icmp_router_solicitation%(c: connection, icmp: icmp_conn, options: icmp6_nd_options%); - -## Generated for ICMP *router advertisement* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## cur_hop_limit: The default value that should be placed in Hop Count field -## for outgoing IP packets. -## -## managed: Managed address configuration flag, :rfc:`4861`. -## -## other: Other stateful configuration flag, :rfc:`4861`. -## -## home_agent: Mobile IPv6 home agent flag, :rfc:`3775`. -## -## pref: Router selection preferences, :rfc:`4191`. -## -## proxy: Neighbor discovery proxy flag, :rfc:`4389`. -## -## rsv: Remaining two reserved bits of router advertisement flags. -## -## router_lifetime: How long this router should be used as a default router. -## -## reachable_time: How long a neighbor should be considered reachable. -## -## retrans_timer: How long a host should wait before retransmitting. -## -## options: Any Neighbor Discovery options included with message (:rfc:`4861`). -## -## .. bro:see:: icmp_router_solicitation -## icmp_neighbor_solicitation icmp_neighbor_advertisement icmp_redirect -event icmp_router_advertisement%(c: connection, icmp: icmp_conn, cur_hop_limit: count, managed: bool, other: bool, home_agent: bool, pref: count, proxy: bool, rsv: count, router_lifetime: interval, reachable_time: interval, retrans_timer: interval, options: icmp6_nd_options%); - -## Generated for ICMP *neighbor solicitation* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## tgt: The IP address of the target of the solicitation. -## -## options: Any Neighbor Discovery options included with message (:rfc:`4861`). -## -## .. bro:see:: icmp_router_solicitation icmp_router_advertisement -## icmp_neighbor_advertisement icmp_redirect -event icmp_neighbor_solicitation%(c: connection, icmp: icmp_conn, tgt: addr, options: icmp6_nd_options%); - -## Generated for ICMP *neighbor advertisement* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## router: Flag indicating the sender is a router. -## -## solicited: Flag indicating advertisement is in response to a solicitation. -## -## override: Flag indicating advertisement should override existing caches. -## -## tgt: the Target Address in the soliciting message or the address whose -## link-layer address has changed for unsolicited adverts. -## -## options: Any Neighbor Discovery options included with message (:rfc:`4861`). -## -## .. bro:see:: icmp_router_solicitation icmp_router_advertisement -## icmp_neighbor_solicitation icmp_redirect -event icmp_neighbor_advertisement%(c: connection, icmp: icmp_conn, router: bool, solicited: bool, override: bool, tgt: addr, options: icmp6_nd_options%); - -## Generated for ICMP *redirect* messages. -## -## See `Wikipedia -## `__ for more -## information about the ICMP protocol. -## -## c: The connection record for the corresponding ICMP flow. -## -## icmp: Additional ICMP-specific information augmenting the standard connection -## record *c*. -## -## tgt: The address that is supposed to be a better first hop to use for -## ICMP Destination Address. -## -## dest: The address of the destination which is redirected to the target. -## -## options: Any Neighbor Discovery options included with message (:rfc:`4861`). -## -## .. bro:see:: icmp_router_solicitation icmp_router_advertisement -## icmp_neighbor_solicitation icmp_neighbor_advertisement -event icmp_redirect%(c: connection, icmp: icmp_conn, tgt: addr, dest: addr, options: icmp6_nd_options%); +event protocol_violation%(c: connection, atype: Analyzer::Tag, aid: count, reason: string%); ## Generated when a TCP connection terminated, passing on statistics about the ## two endpoints. This event is always generated when Bro flushes the internal @@ -1329,4950 +513,6 @@ event net_weird%(name: string%); ## dmem: The difference in memory usage caused by processing the sampled packet. event load_sample%(samples: load_sample_info, CPU: interval, dmem: int%); -## Generated for ARP requests. -## -## See `Wikipedia `__ -## for more information about the ARP protocol. -## -## mac_src: The request's source MAC address. -## -## mac_dst: The request's destination MAC address. -## -## SPA: The sender protocol address. -## -## SHA: The sender hardware address. -## -## TPA: The target protocol address. -## -## THA: The target hardware address. -## -## .. bro:see:: arp_reply bad_arp -event arp_request%(mac_src: string, mac_dst: string, SPA: addr, SHA: string, - TPA: addr, THA: string%); - -## Generated for ARP replies. -## -## See `Wikipedia `__ -## for more information about the ARP protocol. -## -## mac_src: The reply's source MAC address. -## -## mac_dst: The reply's destination MAC address. -## -## SPA: The sender protocol address. -## -## SHA: The sender hardware address. -## -## TPA: The target protocol address. -## -## THA: The target hardware address. -## -## .. bro:see:: arp_request bad_arp -event arp_reply%(mac_src: string, mac_dst: string, SPA: addr, SHA: string, - TPA: addr, THA: string%); - -## Generated for ARP packets that Bro cannot interpret. Examples are packets -## with non-standard hardware address formats or hardware addresses that do not -## match the originator of the packet. -## -## SPA: The sender protocol address. -## -## SHA: The sender hardware address. -## -## TPA: The target protocol address. -## -## THA: The target hardware address. -## -## explanation: A short description of why the ARP packet is considered "bad". -## -## .. bro:see:: arp_reply arp_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event bad_arp%(SPA: addr, SHA: string, TPA: addr, THA: string, explanation: string%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_have bittorrent_peer_interested bittorrent_peer_keep_alive -## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_handshake%(c: connection, is_orig: bool, - reserved: string, info_hash: string, peer_id: string%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_keep_alive%(c: connection, is_orig: bool%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bittorrent_peer_choke%(c: connection, is_orig: bool%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request -## bittorrent_peer_unknown bittorrent_peer_weird -event bittorrent_peer_unchoke%(c: connection, is_orig: bool%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_keep_alive -## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_interested%(c: connection, is_orig: bool%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_not_interested%(c: connection, is_orig: bool%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_interested bittorrent_peer_keep_alive -## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_have%(c: connection, is_orig: bool, piece_index: count%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_cancel bittorrent_peer_choke bittorrent_peer_handshake -## bittorrent_peer_have bittorrent_peer_interested bittorrent_peer_keep_alive -## bittorrent_peer_not_interested bittorrent_peer_piece bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_bitfield%(c: connection, is_orig: bool, bitfield: string%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_request%(c: connection, is_orig: bool, index: count, - begin: count, length: count%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_port -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_piece%(c: connection, is_orig: bool, index: count, - begin: count, piece_length: count%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bittorrent_peer_cancel%(c: connection, is_orig: bool, index: count, - begin: count, length: count%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_request bittorrent_peer_unchoke bittorrent_peer_unknown -## bittorrent_peer_weird -event bittorrent_peer_port%(c: connection, is_orig: bool, listen_port: port%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_weird -event bittorrent_peer_unknown%(c: connection, is_orig: bool, message_id: count, - data: string%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown -event bittorrent_peer_weird%(c: connection, is_orig: bool, msg: string%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bt_tracker_request%(c: connection, uri: string, - headers: bt_tracker_headers%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bt_tracker_response%(c: connection, status: count, - headers: bt_tracker_headers, - peers: bittorrent_peer_set, - benc: bittorrent_benc_dir%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bt_tracker_response_not_ok%(c: connection, status: count, - headers: bt_tracker_headers%); - -## TODO. -## -## See `Wikipedia `__ for -## more information about the BitTorrent protocol. -## -## .. bro:see:: bittorrent_peer_bitfield bittorrent_peer_cancel bittorrent_peer_choke -## bittorrent_peer_handshake bittorrent_peer_have bittorrent_peer_interested -## bittorrent_peer_keep_alive bittorrent_peer_not_interested bittorrent_peer_piece -## bittorrent_peer_port bittorrent_peer_request bittorrent_peer_unchoke -## bittorrent_peer_unknown bittorrent_peer_weird -event bt_tracker_weird%(c: connection, is_orig: bool, msg: string%); - -## Generated for Finger requests. -## -## See `Wikipedia `__ for more -## information about the Finger protocol. -## -## c: The connection. -## -## full: True if verbose information is requested (``/W`` switch). -## -## username: The request's user name. -## -## hostname: The request's host name. -## -## .. bro:see:: finger_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event finger_request%(c: connection, full: bool, username: string, hostname: string%); - -## Generated for Finger replies. -## -## See `Wikipedia `__ for more -## information about the Finger protocol. -## -## c: The connection. -## -## reply_line: The reply as returned by the server -## -## .. bro:see:: finger_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event finger_reply%(c: connection, reply_line: string%); - - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify -## gnutella_not_establish gnutella_partial_binary_msg gnutella_signature_found -## -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_text_msg%(c: connection, orig: bool, headers: string%); - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_establish gnutella_http_notify gnutella_not_establish -## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_binary_msg%(c: connection, orig: bool, msg_type: count, - ttl: count, hops: count, msg_len: count, - payload: string, payload_len: count, - trunc: bool, complete: bool%); - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify -## gnutella_not_establish gnutella_signature_found gnutella_text_msg -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_partial_binary_msg%(c: connection, orig: bool, - msg: string, len: count%); - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_binary_msg gnutella_http_notify gnutella_not_establish -## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_establish%(c: connection%); - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_http_notify -## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_not_establish%(c: connection%); - -## TODO. -## -## See `Wikipedia `__ for more -## information about the Gnutella protocol. -## -## .. bro:see:: gnutella_binary_msg gnutella_establish gnutella_not_establish -## gnutella_partial_binary_msg gnutella_signature_found gnutella_text_msg -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event gnutella_http_notify%(c: connection%); - -## Generated for Ident requests. -## -## See `Wikipedia `__ for more -## information about the Ident protocol. -## -## c: The connection. -## -## lport: The request's local port. -## -## rport: The request's remote port. -## -## .. bro:see:: ident_error ident_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ident_request%(c: connection, lport: port, rport: port%); - -## Generated for Ident replies. -## -## See `Wikipedia `__ for more -## information about the Ident protocol. -## -## c: The connection. -## -## lport: The corresponding request's local port. -## -## rport: The corresponding request's remote port. -## -## user_id: The user id returned by the reply. -## -## system: The operating system returned by the reply. -## -## .. bro:see:: ident_error ident_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ident_reply%(c: connection, lport: port, rport: port, user_id: string, system: string%); - -## Generated for Ident error replies. -## -## See `Wikipedia `__ for more -## information about the Ident protocol. -## -## c: The connection. -## -## lport: The corresponding request's local port. -## -## rport: The corresponding request's remote port. -## -## line: The error description returned by the reply. -## -## .. bro:see:: ident_reply ident_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ident_error%(c: connection, lport: port, rport: port, line: string%); - -## Generated for Telnet/Rlogin login failures. The *login* analyzer inspects -## Telnet/Rlogin sessions to heuristically extract username and password -## information as well as the text returned by the login server. This event is -## raised if a login attempt appears to have been unsuccessful. -## -## c: The connection. -## -## user: The user name tried. -## -## client_user: For Telnet connections, this is an empty string, but for Rlogin -## connections, it is the client name passed in the initial authentication -## information (to check against .rhosts). -## -## password: The password tried. -## -## line: The line of text that led the analyzer to conclude that the -## authentication had failed. -## -## .. bro:see:: login_confused login_confused_text login_display login_input_line -## login_output_line login_prompt login_success login_terminal direct_login_prompts -## get_login_state login_failure_msgs login_non_failure_msgs login_prompts login_success_msgs -## login_timeouts set_login_state -## -## .. note:: The login analyzer depends on a set of script-level variables that -## need to be configured with patterns identifying login attempts. This -## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and -## the analyzer is therefore not directly usable at the moment. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_failure%(c: connection, user: string, client_user: string, password: string, line: string%); - -## Generated for successful Telnet/Rlogin logins. The *login* analyzer inspects -## Telnet/Rlogin sessions to heuristically extract username and password -## information as well as the text returned by the login server. This event is -## raised if a login attempt appears to have been successful. -## -## c: The connection. -## -## user: The user name used. -## -## client_user: For Telnet connections, this is an empty string, but for Rlogin -## connections, it is the client name passed in the initial authentication -## information (to check against .rhosts). -## -## password: The password used. -## -## line: The line of text that led the analyzer to conclude that the -## authentication had succeeded. -## -## .. bro:see:: login_confused login_confused_text login_display login_failure -## login_input_line login_output_line login_prompt login_terminal -## direct_login_prompts get_login_state login_failure_msgs login_non_failure_msgs -## login_prompts login_success_msgs login_timeouts set_login_state -## -## .. note:: The login analyzer depends on a set of script-level variables that -## need to be configured with patterns identifying login attempts. This -## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and -## the analyzer is therefore not directly usable at the moment. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_success%(c: connection, user: string, client_user: string, password: string, line: string%); - -## Generated for lines of input on Telnet/Rlogin sessions. The line will have -## control characters (such as in-band Telnet options) removed. -## -## c: The connection. -## -## line: The input line. -## -## .. bro:see:: login_confused login_confused_text login_display login_failure -## login_output_line login_prompt login_success login_terminal rsh_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_input_line%(c: connection, line: string%); - -## Generated for lines of output on Telnet/Rlogin sessions. The line will have -## control characters (such as in-band Telnet options) removed. -## -## c: The connection. -## -## line: The ouput line. -## -## .. bro:see:: login_confused login_confused_text login_display login_failure -## login_input_line login_prompt login_success login_terminal rsh_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_output_line%(c: connection, line: string%); - -## Generated when tracking of Telnet/Rlogin authentication failed. As Bro's -## *login* analyzer uses a number of heuristics to extract authentication -## information, it may become confused. If it can no longer correctly track -## the authentication dialog, it raises this event. -## -## c: The connection. -## -## msg: Gives the particular problem the heuristics detected (for example, -## ``multiple_login_prompts`` means that the engine saw several login -## prompts in a row, without the type-ahead from the client side presumed -## necessary to cause them) -## -## line: The line of text that caused the heuristics to conclude they were -## confused. -## -## .. bro:see:: login_confused_text login_display login_failure login_input_line login_output_line -## login_prompt login_success login_terminal direct_login_prompts get_login_state -## login_failure_msgs login_non_failure_msgs login_prompts login_success_msgs -## login_timeouts set_login_state -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_confused%(c: connection, msg: string, line: string%); - -## Generated after getting confused while tracking a Telnet/Rlogin -## authentication dialog. The *login* analyzer generates this even for every -## line of user input after it has reported :bro:id:`login_confused` for a -## connection. -## -## c: The connection. -## -## line: The line the user typed. -## -## .. bro:see:: login_confused login_display login_failure login_input_line -## login_output_line login_prompt login_success login_terminal direct_login_prompts -## get_login_state login_failure_msgs login_non_failure_msgs login_prompts -## login_success_msgs login_timeouts set_login_state -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_confused_text%(c: connection, line: string%); - -## Generated for clients transmitting a terminal type in a Telnet session. This -## information is extracted out of environment variables sent as Telnet options. -## -## c: The connection. -## -## terminal: The TERM value transmitted. -## -## .. bro:see:: login_confused login_confused_text login_display login_failure -## login_input_line login_output_line login_prompt login_success -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_terminal%(c: connection, terminal: string%); - -## Generated for clients transmitting an X11 DISPLAY in a Telnet session. This -## information is extracted out of environment variables sent as Telnet options. -## -## c: The connection. -## -## display: The DISPLAY transmitted. -## -## .. bro:see:: login_confused login_confused_text login_failure login_input_line -## login_output_line login_prompt login_success login_terminal -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_display%(c: connection, display: string%); - -## Generated when a Telnet authentication has been successful. The Telnet -## protocol includes options for negotiating authentication. When such an -## option is sent from client to server and the server replies that it accepts -## the authentication, then the event engine generates this event. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## name: The authenticated name. -## -## c: The connection. -## -## .. bro:see:: authentication_rejected authentication_skipped login_success -## -## .. note:: This event inspects the corresponding Telnet option -## while :bro:id:`login_success` heuristically determines success by watching -## session data. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event authentication_accepted%(name: string, c: connection%); - -## Generated when a Telnet authentication has been unsuccessful. The Telnet -## protocol includes options for negotiating authentication. When such an option -## is sent from client to server and the server replies that it did not accept -## the authentication, then the event engine generates this event. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## name: The attempted authentication name. -## -## c: The connection. -## -## .. bro:see:: authentication_accepted authentication_skipped login_failure -## -## .. note:: This event inspects the corresponding Telnet option -## while :bro:id:`login_success` heuristically determines failure by watching -## session data. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event authentication_rejected%(name: string, c: connection%); - -## Generated for Telnet/Rlogin sessions when a pattern match indicates -## that no authentication is performed. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## .. bro:see:: authentication_accepted authentication_rejected direct_login_prompts -## get_login_state login_failure_msgs login_non_failure_msgs login_prompts -## login_success_msgs login_timeouts set_login_state -## -## .. note:: The login analyzer depends on a set of script-level variables that -## need to be configured with patterns identifying activity. This -## configuration has not yet been ported over from Bro 1.5 to Bro 2.x, and -## the analyzer is therefore not directly usable at the moment. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event authentication_skipped%(c: connection%); - -## Generated for clients transmitting a terminal prompt in a Telnet session. -## This information is extracted out of environment variables sent as Telnet -## options. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## prompt: The TTYPROMPT transmitted. -## -## .. bro:see:: login_confused login_confused_text login_display login_failure -## login_input_line login_output_line login_success login_terminal -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event login_prompt%(c: connection, prompt: string%); - -## Generated for Telnet sessions when encryption is activated. The Telnet -## protocol includes options for negotiating encryption. When such a series of -## options is successfully negotiated, the event engine generates this event. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## .. bro:see:: authentication_accepted authentication_rejected authentication_skipped -## login_confused login_confused_text login_display login_failure login_input_line -## login_output_line login_prompt login_success login_terminal -event activating_encryption%(c: connection%); - -## Generated for an inconsistent Telnet option. Telnet options are specified -## by the client and server stating which options they are willing to -## support vs. which they are not, and then instructing one another which in -## fact they should or should not use for the current connection. If the event -## engine sees a peer violate either what the other peer has instructed it to -## do, or what it itself offered in terms of options in the past, then the -## engine generates this event. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## .. bro:see:: bad_option bad_option_termination authentication_accepted -## authentication_rejected authentication_skipped login_confused -## login_confused_text login_display login_failure login_input_line -## login_output_line login_prompt login_success login_terminal -event inconsistent_option%(c: connection%); - -## Generated for an ill-formed or unrecognized Telnet option. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## .. bro:see:: inconsistent_option bad_option_termination authentication_accepted -## authentication_rejected authentication_skipped login_confused -## login_confused_text login_display login_failure login_input_line -## login_output_line login_prompt login_success login_terminal -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event bad_option%(c: connection%); - -## Generated for a Telnet option that's incorrectly terminated. -## -## See `Wikipedia `__ for more information -## about the Telnet protocol. -## -## c: The connection. -## -## .. bro:see:: inconsistent_option bad_option authentication_accepted -## authentication_rejected authentication_skipped login_confused -## login_confused_text login_display login_failure login_input_line -## login_output_line login_prompt login_success login_terminal -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event bad_option_termination%(c: connection%); - -## Generated for client side commands on an RSH connection. -## -## See `RFC 1258 `__ for more information -## about the Rlogin/Rsh protocol. -## -## c: The connection. -## -## client_user: The client-side user name as sent in the initial protocol -## handshake. -## -## server_user: The server-side user name as sent in the initial protocol -## handshake. -## -## line: The command line sent in the request. -## -## new_session: True if this is the first command of the Rsh session. -## -## .. bro:see:: rsh_reply login_confused login_confused_text login_display -## login_failure login_input_line login_output_line login_prompt login_success -## login_terminal -## -## .. note:: For historical reasons, these events are separate from the -## ``login_`` events. Ideally, they would all be handled uniquely. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event rsh_request%(c: connection, client_user: string, server_user: string, line: string, new_session: bool%); - -## Generated for client side commands on an RSH connection. -## -## See `RFC 1258 `__ for more information -## about the Rlogin/Rsh protocol. -## -## c: The connection. -## -## client_user: The client-side user name as sent in the initial protocol -## handshake. -## -## server_user: The server-side user name as sent in the initial protocol -## handshake. -## -## line: The command line sent in the request. -## -## .. bro:see:: rsh_request login_confused login_confused_text login_display -## login_failure login_input_line login_output_line login_prompt login_success -## login_terminal -## -## .. note:: For historical reasons, these events are separate from the -## ``login_`` events. Ideally, they would all be handled uniquely. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event rsh_reply%(c: connection, client_user: string, server_user: string, line: string%); - -## Generated for client-side FTP commands. -## -## See `Wikipedia `__ for -## more information about the FTP protocol. -## -## c: The connection. -## -## command: The FTP command issued by the client (without any arguments). -## -## arg: The arguments going with the command. -## -## .. bro:see:: ftp_reply fmt_ftp_port parse_eftp_port -## parse_ftp_epsv parse_ftp_pasv parse_ftp_port -event ftp_request%(c: connection, command: string, arg: string%) &group="ftp"; - -## Generated for server-side FTP replies. -## -## See `Wikipedia `__ for -## more information about the FTP protocol. -## -## c: The connection. -## -## code: The numerical response code the server responded with. -## -## msg: The textual message of the response. -## -## cont_resp: True if the reply line is tagged as being continued to the next -## line. If so, further events will be raised and a handler may want -## to reassemble the pieces before processing the response any -## further. -## -## .. bro:see:: ftp_request fmt_ftp_port parse_eftp_port -## parse_ftp_epsv parse_ftp_pasv parse_ftp_port -event ftp_reply%(c: connection, code: count, msg: string, cont_resp: bool%) &group="ftp"; - -## Generated for client-side SMTP commands. -## -## See `Wikipedia `__ -## for more information about the SMTP protocol. -## -## c: The connection. -## -## is_orig: True if the sender of the command is the originator of the TCP -## connection. Note that this is not redundant: the SMTP ``TURN`` command -## allows client and server to flip roles on established SMTP sessions, -## and hence a "request" might still come from the TCP-level responder. -## In practice, however, that will rarely happen as TURN is considered -## insecure and rarely used. -## -## command: The request's command, without any arguments. -## -## arg: The request command's arguments. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data -## smtp_data smtp_reply -## -## .. note:: Bro does not support the newer ETRN extension yet. -event smtp_request%(c: connection, is_orig: bool, command: string, arg: string%) &group="smtp"; - -## Generated for server-side SMTP commands. -## -## See `Wikipedia `__ -## for more information about the SMTP protocol. -## -## c: The connection. -## -## is_orig: True if the sender of the command is the originator of the TCP -## connection. Note that this is not redundant: the SMTP ``TURN`` command -## allows client and server to flip roles on established SMTP sessions, -## and hence a "reply" might still come from the TCP-level originator. In -## practice, however, that will rarely happen as TURN is considered -## insecure and rarely used. -## -## code: The reply's numerical code. -## -## cmd: TODO. -## -## msg: The reply's textual description. -## -## cont_resp: True if the reply line is tagged as being continued to the next -## line. If so, further events will be raised and a handler may want to -## reassemble the pieces before processing the response any further. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data -## smtp_data smtp_request -## -## .. note:: Bro doesn't support the newer ETRN extension yet. -event smtp_reply%(c: connection, is_orig: bool, code: count, cmd: string, msg: string, cont_resp: bool%) &group="smtp"; - -## Generated for DATA transmitted on SMTP sessions. This event is raised for -## subsequent chunks of raw data following the ``DATA`` SMTP command until the -## corresponding end marker ``.`` is seen. A handler may want to reassemble -## the pieces as they come in if stream-analysis is required. -## -## See `Wikipedia `__ -## for more information about the SMTP protocol. -## -## c: The connection. -## -## is_orig: True if the sender of the data is the originator of the TCP -## connection. -## -## data: The raw data. Note that the size of each chunk is undefined and -## depends on specifics of the underlying TCP connection. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_event mime_one_header mime_segment_data -## smtp_reply smtp_request skip_smtp_data -## -## .. note:: This event receives the unprocessed raw data. There is a separate -## set of ``mime_*`` events that strip out the outer MIME-layer of emails and -## provide structured access to their content. -event smtp_data%(c: connection, is_orig: bool, data: string%) &group="smtp"; - -## Generated for unexpected activity on SMTP sessions. The SMTP analyzer tracks -## the state of SMTP sessions and reports commands and other activity with this -## event that it sees even though it would not expect so at the current point -## of the communication. -## -## See `Wikipedia `__ -## for more information about the SMTP protocol. -## -## c: The connection. -## -## is_orig: True if the sender of the unexpected activity is the originator of -## the TCP connection. -## -## msg: A descriptive message of what was unexpected. -## -## detail: The actual SMTP line triggering the event. -## -## .. bro:see:: smtp_data smtp_request smtp_reply -event smtp_unexpected%(c: connection, is_orig: bool, msg: string, detail: string%) &group="smtp"; - -## Generated when starting to parse an email MIME entity. MIME is a -## protocol-independent data format for encoding text and files, along with -## corresponding metadata, for transmission. Bro raises this event when it -## begins parsing a MIME entity extracted from an email protocol. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## .. bro:see:: mime_all_data mime_all_headers mime_content_hash mime_end_entity -## mime_entity_data mime_event mime_one_header mime_segment_data smtp_data -## http_begin_entity -## -## .. note:: Bro also extracts MIME entities from HTTP sessions. For those, -## however, it raises :bro:id:`http_begin_entity` instead. -event mime_begin_entity%(c: connection%); - -## Generated when finishing parsing an email MIME entity. MIME is a -## protocol-independent data format for encoding text and files, along with -## corresponding metadata, for transmission. Bro raises this event when it -## finished parsing a MIME entity extracted from an email protocol. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_entity_data mime_event mime_one_header mime_segment_data smtp_data -## http_end_entity -## -## .. note:: Bro also extracts MIME entities from HTTP sessions. For those, -## however, it raises :bro:id:`http_end_entity` instead. -event mime_end_entity%(c: connection%); - -## Generated for individual MIME headers extracted from email MIME -## entities. MIME is a protocol-independent data format for encoding text and -## files, along with corresponding metadata, for transmission. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## h: The parsed MIME header. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_event mime_segment_data -## http_header http_all_headers -## -## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, -## however, it raises :bro:id:`http_header` instead. -event mime_one_header%(c: connection, h: mime_header_rec%); - -## Generated for MIME headers extracted from email MIME entities, passing all -## headers at once. MIME is a protocol-independent data format for encoding -## text and files, along with corresponding metadata, for transmission. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## hlist: A *table* containing all headers extracted from the current entity. -## The table is indexed by the position of the header (1 for the first, -## 2 for the second, etc.). -## -## .. bro:see:: mime_all_data mime_begin_entity mime_content_hash mime_end_entity -## mime_entity_data mime_event mime_one_header mime_segment_data -## http_header http_all_headers -## -## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, -## however, it raises :bro:id:`http_header` instead. -event mime_all_headers%(c: connection, hlist: mime_header_list%); - -## Generated for chunks of decoded MIME data from email MIME entities. MIME -## is a protocol-independent data format for encoding text and files, along with -## corresponding metadata, for transmission. As Bro parses the data of an -## entity, it raises a sequence of these events, each coming as soon as a new -## chunk of data is available. In contrast, there is also -## :bro:id:`mime_entity_data`, which passes all of an entities data at once -## in a single block. While the latter is more convenient to handle, -## ``mime_segment_data`` is more efficient as Bro does not need to buffer -## the data. Thus, if possible, this event should be preferred. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## length: The length of *data*. -## -## data: The raw data of one segment of the current entity. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_event mime_one_header http_entity_data -## mime_segment_length mime_segment_overlap_length -## -## .. note:: Bro also extracts MIME data from HTTP sessions. For those, -## however, it raises :bro:id:`http_entity_data` (sic!) instead. -event mime_segment_data%(c: connection, length: count, data: string%); - -## Generated for data decoded from an email MIME entity. This event delivers -## the complete content of a single MIME entity. In contrast, there is also -## :bro:id:`mime_segment_data`, which passes on a sequence of data chunks as -## they come in. While ``mime_entity_data`` is more convenient to handle, -## ``mime_segment_data`` is more efficient as Bro does not need to buffer the -## data. Thus, if possible, the latter should be preferred. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## length: The length of *data*. -## -## data: The raw data of the complete entity. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_event mime_one_header mime_segment_data -## -## .. note:: While Bro also decodes MIME entities extracted from HTTP -## sessions, there's no corresponding event for that currently. -event mime_entity_data%(c: connection, length: count, data: string%); - -## Generated for passing on all data decoded from a single email MIME -## message. If an email message has more than one MIME entity, this event -## combines all their data into a single value for analysis. Note that because -## of the potentially significant buffering necessary, using this event can be -## expensive. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## length: The length of *data*. -## -## data: The raw data of all MIME entities concatenated. -## -## .. bro:see:: mime_all_headers mime_begin_entity mime_content_hash mime_end_entity -## mime_entity_data mime_event mime_one_header mime_segment_data -## -## .. note:: While Bro also decodes MIME entities extracted from HTTP -## sessions, there's no corresponding event for that currently. -event mime_all_data%(c: connection, length: count, data: string%); - -## Generated for errors found when decoding email MIME entities. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## event_type: A string describing the general category of the problem found -## (e.g., ``illegal format``). -## -## detail: Further more detailed description of the error. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_content_hash -## mime_end_entity mime_entity_data mime_one_header mime_segment_data http_event -## -## .. note:: Bro also extracts MIME headers from HTTP sessions. For those, -## however, it raises :bro:id:`http_event` instead. -event mime_event%(c: connection, event_type: string, detail: string%); - -## Generated for decoded MIME entities extracted from email messages, passing on -## their MD5 checksums. Bro computes the MD5 over the complete decoded data of -## each MIME entity. -## -## Bro's MIME analyzer for emails currently supports SMTP and POP3. See -## `Wikipedia `__ for more information -## about MIME. -## -## c: The connection. -## -## content_len: The length of the entity being hashed. -## -## hash_value: The MD5 hash. -## -## .. bro:see:: mime_all_data mime_all_headers mime_begin_entity mime_end_entity -## mime_entity_data mime_event mime_one_header mime_segment_data -## -## .. note:: While Bro also decodes MIME entities extracted from HTTP -## sessions, there's no corresponding event for that currently. -event mime_content_hash%(c: connection, content_len: count, hash_value: string%); - -## Generated for RPC request/reply *pairs*. The RPC analyzer associates request -## and reply by their transaction identifiers and raises this event once both -## have been seen. If there's not a reply, this event will still be generated -## eventually on timeout. In that case, *status* will be set to -## :bro:enum:`RPC_TIMEOUT`. -## -## See `Wikipedia `__ for more information -## about the ONC RPC protocol. -## -## c: The connection. -## -## prog: The remote program to call. -## -## ver: The version of the remote program to call. -## -## proc: The procedure of the remote program to call. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## start_time: The time when the *call* was seen. -## -## call_len: The size of the *call_body* PDU. -## -## reply_len: The size of the *reply_body* PDU. -## -## .. bro:see:: rpc_call rpc_reply dce_rpc_bind dce_rpc_message dce_rpc_request -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event rpc_dialogue%(c: connection, prog: count, ver: count, proc: count, status: rpc_status, start_time: time, call_len: count, reply_len: count%); - -## Generated for RPC *call* messages. -## -## See `Wikipedia `__ for more information -## about the ONC RPC protocol. -## -## c: The connection. -## -## xid: The transaction identifier allowing to match requests with replies. -## -## prog: The remote program to call. -## -## ver: The version of the remote program to call. -## -## proc: The procedure of the remote program to call. -## -## call_len: The size of the *call_body* PDU. -## -## .. bro:see:: rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message dce_rpc_request -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event rpc_call%(c: connection, xid: count, prog: count, ver: count, proc: count, call_len: count%); - -## Generated for RPC *reply* messages. -## -## See `Wikipedia `__ for more information -## about the ONC RPC protocol. -## -## c: The connection. -## -## xid: The transaction identifier allowing to match requests with replies. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## reply_len: The size of the *reply_body* PDU. -## -## .. bro:see:: rpc_call rpc_dialogue dce_rpc_bind dce_rpc_message dce_rpc_request -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event rpc_reply%(c: connection, xid: count, status: rpc_status, reply_len: count%); - -## Generated for Portmapper requests of type *null*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit -## pm_request_dump pm_request_getport pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_null%(r: connection%); - -## Generated for Portmapper request/reply dialogues of type *set*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## m: The argument to the request. -## -## success: True if the request was successful, according to the corresponding -## reply. If no reply was seen, this will be false once the request -## times out. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit -## pm_request_dump pm_request_getport pm_request_null pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_set%(r: connection, m: pm_mapping, success: bool%); - -## Generated for Portmapper request/reply dialogues of type *unset*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## m: The argument to the request. -## -## success: True if the request was successful, according to the corresponding -## reply. If no reply was seen, this will be false once the request -## times out. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit -## pm_request_dump pm_request_getport pm_request_null pm_request_set rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_unset%(r: connection, m: pm_mapping, success: bool%); - -## Generated for Portmapper request/reply dialogues of type *getport*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## pr: The argument to the request. -## -## p: The port returned by the server. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit -## pm_request_dump pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_getport%(r: connection, pr: pm_port_request, p: port%); - -## Generated for Portmapper request/reply dialogues of type *dump*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## m: The mappings returned by the server. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_dump%(r: connection, m: pm_mappings%); - -## Generated for Portmapper request/reply dialogues of type *callit*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## call: The argument to the request. -## -## p: The port value returned by the call. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_bad_port pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_request_callit%(r: connection, call: pm_callit_request, p: port%); - -## Generated for failed Portmapper requests of type *null*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_null%(r: connection, status: rpc_status%); - -## Generated for failed Portmapper requests of type *set*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## m: The argument to the original request. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_set%(r: connection, status: rpc_status, m: pm_mapping%); - -## Generated for failed Portmapper requests of type *unset*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## m: The argument to the original request. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_unset%(r: connection, status: rpc_status, m: pm_mapping%); - -## Generated for failed Portmapper requests of type *getport*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## pr: The argument to the original request. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_null -## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_getport%(r: connection, status: rpc_status, pr: pm_port_request%); - -## Generated for failed Portmapper requests of type *dump*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_getport pm_attempt_null -## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_dump%(r: connection, status: rpc_status%); - -## Generated for failed Portmapper requests of type *callit*. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## status: The status of the reply, which should be one of the index values of -## :bro:id:`RPC_status`. -## -## call: The argument to the original request. -## -## .. bro:see:: epm_map_response pm_attempt_dump pm_attempt_getport pm_attempt_null -## pm_attempt_set pm_attempt_unset pm_bad_port pm_request_callit pm_request_dump -## pm_request_getport pm_request_null pm_request_set pm_request_unset rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_attempt_callit%(r: connection, status: rpc_status, call: pm_callit_request%); - -## Generated for Portmapper requests or replies that include an invalid port -## number. Since ports are represented by unsigned 4-byte integers, they can -## stray outside the allowed range of 0--65535 by being >= 65536. If so, this -## event is generated. -## -## Portmapper is a service running on top of RPC. See `Wikipedia -## `__ for more information about the -## service. -## -## r: The RPC connection. -## -## bad_p: The invalid port value. -## -## .. bro:see:: epm_map_response pm_attempt_callit pm_attempt_dump pm_attempt_getport -## pm_attempt_null pm_attempt_set pm_attempt_unset pm_request_callit -## pm_request_dump pm_request_getport pm_request_null pm_request_set -## pm_request_unset rpc_call rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pm_bad_port%(r: connection, bad_p: count%); - -## Generated for NFSv3 request/reply dialogues of type *null*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_read nfs_proc_readdir nfs_proc_readlink -## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_null%(c: connection, info: NFS3::info_t%); - -## Generated for NFSv3 request/reply dialogues of type *getattr*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## fh: TODO. -## -## attrs: The attributes returned in the reply. The values may not be valid if -## the request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status -## rpc_call rpc_dialogue rpc_reply file_mode -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_getattr%(c: connection, info: NFS3::info_t, fh: string, attrs: NFS3::fattr_t%); - -## Generated for NFSv3 request/reply dialogues of type *lookup*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: The arguments passed in the request. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status -## rpc_call rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_lookup%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::lookup_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *read*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: The arguments passed in the request. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_remove nfs_proc_rmdir -## nfs_proc_write nfs_reply_status rpc_call rpc_dialogue rpc_reply -## NFS3::return_data NFS3::return_data_first_only NFS3::return_data_max -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_read%(c: connection, info: NFS3::info_t, req: NFS3::readargs_t, rep: NFS3::read_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *readlink*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## fh: The file handle passed in the request. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_readlink%(c: connection, info: NFS3::info_t, fh: string, rep: NFS3::readlink_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *write*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_reply_status rpc_call -## rpc_dialogue rpc_reply NFS3::return_data NFS3::return_data_first_only -## NFS3::return_data_max -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_write%(c: connection, info: NFS3::info_t, req: NFS3::writeargs_t, rep: NFS3::write_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *create*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status -## rpc_call rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_create%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::newobj_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *mkdir*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status -## rpc_call rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_mkdir%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::newobj_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *remove*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_remove%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::delobj_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *rmdir*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_write nfs_reply_status rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_rmdir%(c: connection, info: NFS3::info_t, req: NFS3::diropargs_t, rep: NFS3::delobj_reply_t%); - -## Generated for NFSv3 request/reply dialogues of type *readdir*. The event is -## generated once we have either seen both the request and its corresponding -## reply, or an unanswered request has timed out. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## req: TODO. -## -## rep: The response returned in the reply. The values may not be valid if the -## request was unsuccessful. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readlink -## nfs_proc_remove nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_readdir%(c: connection, info: NFS3::info_t, req: NFS3::readdirargs_t, rep: NFS3::readdir_reply_t%); - -## Generated for NFSv3 request/reply dialogues of a type that Bro's NFSv3 -## analyzer does not implement. -## -## NFS is a service running on top of RPC. See `Wikipedia -## `__ for more -## information about the service. -## -## c: The RPC connection. -## -## info: Reports the status of the dialogue, along with some meta information. -## -## proc: The procedure called that Bro does not implement. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_null nfs_proc_read nfs_proc_readdir nfs_proc_readlink nfs_proc_remove -## nfs_proc_rmdir nfs_proc_write nfs_reply_status rpc_call rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_proc_not_implemented%(c: connection, info: NFS3::info_t, proc: NFS3::proc_t%); - -## Generated for each NFSv3 reply message received, reporting just the -## status included. -## -## n: The connection. -## -## info: Reports the status included in the reply. -## -## .. bro:see:: nfs_proc_create nfs_proc_getattr nfs_proc_lookup nfs_proc_mkdir -## nfs_proc_not_implemented nfs_proc_null nfs_proc_read nfs_proc_readdir -## nfs_proc_readlink nfs_proc_remove nfs_proc_rmdir nfs_proc_write rpc_call -## rpc_dialogue rpc_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event nfs_reply_status%(n: connection, info: NFS3::info_t%); - -## Generated for all NTP messages. Different from many other of Bro's events, -## this one is generated for both client-side and server-side messages. -## -## See `Wikipedia `__ for -## more information about the NTP protocol. -## -## u: The connection record describing the corresponding UDP flow. -## -## msg: The parsed NTP message. -## -## excess: The raw bytes of any optional parts of the NTP packet. Bro does not -## further parse any optional fields. -## -## .. bro:see:: ntp_session_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ntp_message%(u: connection, msg: ntp_msg, excess: string%); - -## Generated for all NetBIOS SSN and DGM messages. Bro's NetBIOS analyzer -## processes the NetBIOS session service running on TCP port 139, and (despite -## its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## msg_type: The general type of message, as defined in Section 4.3.1 of -## `RFC 1002 `__. -## -## data_len: The length of the message's payload. -## -## .. bro:see:: netbios_session_accepted netbios_session_keepalive -## netbios_session_raw_message netbios_session_rejected netbios_session_request -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_message%(c: connection, is_orig: bool, msg_type: count, data_len: count%); - -## Generated for NetBIOS messages of type *session request*. Bro's NetBIOS -## analyzer processes the NetBIOS session service running on TCP port 139, and -## (despite its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header. -## -## .. bro:see:: netbios_session_accepted netbios_session_keepalive -## netbios_session_message netbios_session_raw_message netbios_session_rejected -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_request%(c: connection, msg: string%); - -## Generated for NetBIOS messages of type *positive session response*. Bro's -## NetBIOS analyzer processes the NetBIOS session service running on TCP port -## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header. -## -## .. bro:see:: netbios_session_keepalive netbios_session_message -## netbios_session_raw_message netbios_session_rejected netbios_session_request -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_accepted%(c: connection, msg: string%); - -## Generated for NetBIOS messages of type *negative session response*. Bro's -## NetBIOS analyzer processes the NetBIOS session service running on TCP port -## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header. -## -## .. bro:see:: netbios_session_accepted netbios_session_keepalive -## netbios_session_message netbios_session_raw_message netbios_session_request -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_rejected%(c: connection, msg: string%); - -## Generated for NetBIOS messages of type *session message* that are not -## carrying an SMB payload. -## -## NetBIOS analyzer processes the NetBIOS session service running on TCP port -## 139, and (despite its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header (i.e., the ``user_data``). -## -## .. bro:see:: netbios_session_accepted netbios_session_keepalive -## netbios_session_message netbios_session_rejected netbios_session_request -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: This is an oddly named event. In fact, it's probably an odd event -## to have to begin with. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_raw_message%(c: connection, is_orig: bool, msg: string%); - -## Generated for NetBIOS messages of type *retarget response*. Bro's NetBIOS -## analyzer processes the NetBIOS session service running on TCP port 139, and -## (despite its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header. -## -## .. bro:see:: netbios_session_accepted netbios_session_keepalive -## netbios_session_message netbios_session_raw_message netbios_session_rejected -## netbios_session_request decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: This is an oddly named event. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_ret_arg_resp%(c: connection, msg: string%); - -## Generated for NetBIOS messages of type *keep-alive*. Bro's NetBIOS analyzer -## processes the NetBIOS session service running on TCP port 139, and (despite -## its name!) the NetBIOS datagram service on UDP port 138. -## -## See `Wikipedia `__ for more information -## about NetBIOS. `RFC 1002 `__ describes -## the packet format for NetBIOS over TCP/IP, which Bro parses. -## -## c: The connection, which may be TCP or UDP, depending on the type of the -## NetBIOS session. -## -## msg: The raw payload of the message sent, excluding the common NetBIOS -## header. -## -## .. bro:see:: netbios_session_accepted netbios_session_message -## netbios_session_raw_message netbios_session_rejected netbios_session_request -## netbios_session_ret_arg_resp decode_netbios_name decode_netbios_name_type -## -## .. note:: These days, NetBIOS is primarily used as a transport mechanism for -## `SMB/CIFS `__. Bro's -## SMB analyzer parses both SMB-over-NetBIOS and SMB-over-TCP on port 445. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event netbios_session_keepalive%(c: connection, msg: string%); - -## Generated for all SMB/CIFS messages. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## is_orig: True if the message was sent by the originator of the underlying -## transport-level connection. -## -## cmd: A string mnemonic of the SMB command code. -## -## body_length: The length of the SMB message body, i.e. the data starting after -## the SMB header. -## -## body: The raw SMB message body, i.e., the data starting after the SMB header. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error -## smb_get_dfs_referral -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_message%(c: connection, hdr: smb_hdr, is_orig: bool, cmd: string, body_length: count, body: string%); - -## Generated for SMB/CIFS messages of type *tree connect andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## path: The ``path`` attribute specified in the message. -## -## service: The ``service`` attribute specified in the message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_tree_connect_andx%(c: connection, hdr: smb_hdr, path: string, service: string%); - -## Generated for SMB/CIFS messages of type *tree disconnect*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_tree_disconnect%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages of type *nt create andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## name: The ``name`` attribute specified in the message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_read_andx -## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_nt_create_andx%(c: connection, hdr: smb_hdr, name: string%); - -## Generated for SMB/CIFS messages of type *nt transaction*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## trans: The parsed transaction header. -## -## data: The raw transaction data. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe -## smb_com_trans_rap smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_transaction%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); - -## Generated for SMB/CIFS messages of type *nt transaction 2*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## trans: The parsed transaction header. -## -## data: The raw transaction data. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe -## smb_com_trans_rap smb_com_transaction smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_transaction2%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); - -## Generated for SMB/CIFS messages of type *transaction mailslot*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## trans: The parsed transaction header. -## -## data: The raw transaction data. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_trans_mailslot%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); - -## Generated for SMB/CIFS messages of type *transaction rap*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## trans: The parsed transaction header. -## -## data: The raw transaction data. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error -## smb_get_dfs_referral smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_trans_rap%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); - -## Generated for SMB/CIFS messages of type *transaction pipe*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## trans: The parsed transaction header. -## -## data: The raw transaction data. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_trans_pipe%(c: connection, hdr: smb_hdr, trans: smb_trans, data: smb_trans_data, is_orig: bool%); - -## Generated for SMB/CIFS messages of type *read andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## data: Always empty. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_read_andx%(c: connection, hdr: smb_hdr, data: string%); - -## Generated for SMB/CIFS messages of type *read andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## data: Always empty. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_tree_disconnect smb_error -## smb_get_dfs_referral smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_write_andx%(c: connection, hdr: smb_hdr, data: string%); - -## Generated for SMB/CIFS messages of type *get dfs referral*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## max_referral_level: The ``max_referral_level`` attribute specified in the -## message. -## -## file_name: The ``filene_name`` attribute specified in the message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx smb_error -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_get_dfs_referral%(c: connection, hdr: smb_hdr, max_referral_level: count, file_name: string%); - -## Generated for SMB/CIFS messages of type *negotiate*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx smb_com_setup_andx -## smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap smb_com_transaction -## smb_com_transaction2 smb_com_tree_connect_andx smb_com_tree_disconnect -## smb_com_write_andx smb_error smb_get_dfs_referral smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_negotiate%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages of type *negotiate response*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## dialect_index: The ``dialect`` indicated in the message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_nt_create_andx smb_com_read_andx smb_com_setup_andx -## smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap smb_com_transaction -## smb_com_transaction2 smb_com_tree_connect_andx smb_com_tree_disconnect -## smb_com_write_andx smb_error smb_get_dfs_referral smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_negotiate_response%(c: connection, hdr: smb_hdr, dialect_index: count%); - -## Generated for SMB/CIFS messages of type *setup andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_setup_andx%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages of type *generic andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_close smb_com_logoff_andx smb_com_negotiate -## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx -## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_generic_andx%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages of type *close*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_generic_andx smb_com_logoff_andx smb_com_negotiate -## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx -## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_close%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages of type *logoff andx*. -## -## See `Wikipedia `__ for -## more information about the SMB/CIFS protocol. Bro's SMB/CIFS analyzer parses -## both SMB-over-NetBIOS on ports 138/139 and SMB-over-TCP on port 445. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_negotiate -## smb_com_negotiate_response smb_com_nt_create_andx smb_com_read_andx -## smb_com_setup_andx smb_com_trans_mailslot smb_com_trans_pipe smb_com_trans_rap -## smb_com_transaction smb_com_transaction2 smb_com_tree_connect_andx -## smb_com_tree_disconnect smb_com_write_andx smb_error smb_get_dfs_referral -## smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_com_logoff_andx%(c: connection, hdr: smb_hdr%); - -## Generated for SMB/CIFS messages that indicate an error. This event is -## triggered by an SMB header including a status that signals an error. -## -## c: The connection. -## -## hdr: The parsed header of the SMB message. -## -## cmd: The SMB command code. -## -## cmd_str: A string mnemonic of the SMB command code. -## -## data: The raw SMB message body, i.e., the data starting after the SMB header. -## -## .. bro:see:: smb_com_close smb_com_generic_andx smb_com_logoff_andx -## smb_com_negotiate smb_com_negotiate_response smb_com_nt_create_andx -## smb_com_read_andx smb_com_setup_andx smb_com_trans_mailslot -## smb_com_trans_pipe smb_com_trans_rap smb_com_transaction smb_com_transaction2 -## smb_com_tree_connect_andx smb_com_tree_disconnect smb_com_write_andx -## smb_get_dfs_referral smb_message -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event smb_error%(c: connection, hdr: smb_hdr, cmd: count, cmd_str: string, data: string%); - -## Generated for all DNS messages. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## is_orig: True if the message was sent by the originator of the connection. -## -## msg: The parsed DNS message header. -## -## len: The length of the message's raw representation (i.e., the DNS payload). -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_query_reply dns_rejected -## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%) &group="dns"; - -## Generated for DNS requests. For requests with multiple queries, this event -## is raised once for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## query: The queried name. -## -## qtype: The queried resource record type. -## -## qclass: The queried resource record class. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%) &group="dns"; - -## Generated for DNS replies that reject a query. This event is raised if a DNS -## reply either indicates failure via its status code or does not pass on any -## answers to a query. Note that all of the event's parameters are parsed out of -## the reply; there's no stateful correlation with the query. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## query: The queried name. -## -## qtype: The queried resource record type. -## -## qclass: The queried resource record class. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%) &group="dns"; - -## Generated for DNS replies with an *ok* status code but no question section. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## query: The queried name. -## -## qtype: The queried resource record type. -## -## qclass: The queried resource record class. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_rejected -## dns_request non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_query_reply%(c: connection, msg: dns_msg, query: string, - qtype: count, qclass: count%) &group="dns"; - -## Generated when the DNS analyzer processes what seems to be a non-DNS packet. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The raw DNS payload. -## -## .. note:: This event is deprecated and superseded by Bro's dynamic protocol -## detection framework. -event non_dns_request%(c: connection, msg: string%) &group="dns"; - -## Generated for DNS replies of type *A*. For replies with multiple answers, an -## individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## a: The address returned by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply -## dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_A_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; - -## Generated for DNS replies of type *AAAA*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## a: The address returned by the reply. -## -## .. bro:see:: dns_A_reply dns_A6_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply -## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl -## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered -## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request -## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_AAAA_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; - -## Generated for DNS replies of type *A6*. For replies with multiple answers, an -## individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## a: The address returned by the reply. -## -## .. bro:see:: dns_A_reply dns_AAAA_reply dns_CNAME_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply -## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl -## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered -## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request -## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_A6_reply%(c: connection, msg: dns_msg, ans: dns_answer, a: addr%) &group="dns"; - -## Generated for DNS replies of type *NS*. For replies with multiple answers, an -## individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## name: The name returned by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_NS_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%) &group="dns"; - -## Generated for DNS replies of type *CNAME*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## name: The name returned by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_EDNS_addl dns_HINFO_reply dns_MX_reply -## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl -## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered -## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request -## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_CNAME_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%) &group="dns"; - -## Generated for DNS replies of type *PTR*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## name: The name returned by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_SOA_reply dns_SRV_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_PTR_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string%) &group="dns"; - -## Generated for DNS replies of type *CNAME*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## soa: The parsed SOA value. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SRV_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_SOA_reply%(c: connection, msg: dns_msg, ans: dns_answer, soa: dns_soa%) &group="dns"; - -## Generated for DNS replies of type *WKS*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_WKS_reply%(c: connection, msg: dns_msg, ans: dns_answer%) &group="dns"; - -## Generated for DNS replies of type *HINFO*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl dns_MX_reply -## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl -## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered -## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request -## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_HINFO_reply%(c: connection, msg: dns_msg, ans: dns_answer%) &group="dns"; - -## Generated for DNS replies of type *MX*. For replies with multiple answers, an -## individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## name: The name returned by the reply. -## -## preference: The preference for *name* specified by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, preference: count%) &group="dns"; - -## Generated for DNS replies of type *TXT*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## str: The textual information returned by the reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%) &group="dns"; - -## Generated for DNS replies of type *SRV*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The type-independent part of the parsed answer record. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_SRV_reply%(c: connection, msg: dns_msg, ans: dns_answer%) &group="dns"; - -## Generated for DNS replies of type *EDNS*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The parsed EDNS reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_HINFO_reply dns_MX_reply -## dns_NS_reply dns_PTR_reply dns_SOA_reply dns_SRV_reply dns_TSIG_addl -## dns_TXT_reply dns_WKS_reply dns_end dns_full_request dns_mapping_altered -## dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified -## dns_mapping_valid dns_message dns_query_reply dns_rejected dns_request -## non_dns_request dns_max_queries dns_session_timeout dns_skip_addl -## dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_EDNS_addl%(c: connection, msg: dns_msg, ans: dns_edns_additional%) &group="dns"; - -## Generated for DNS replies of type *TSIG*. For replies with multiple answers, -## an individual event of the corresponding type is raised for each. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## ans: The parsed TSIG reply. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TXT_reply dns_WKS_reply dns_end dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_TSIG_addl%(c: connection, msg: dns_msg, ans: dns_tsig_additional%) &group="dns"; - -## Generated at the end of processing a DNS packet. This event is the last -## ``dns_*`` event that will be raised for a DNS query/reply and signals that -## all resource records have been passed on. -## -## See `Wikipedia `__ for more -## information about the DNS protocol. Bro analyzes both UDP and TCP DNS -## sessions. -## -## c: The connection, which may be UDP or TCP depending on the type of the -## transport-layer session being analyzed. -## -## msg: The parsed DNS message header. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_full_request -## dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_end%(c: connection, msg: dns_msg%) &group="dns"; - -## Generated for DHCP messages of type *discover*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## req_addr: The specific address requested by the client. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout -## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_discover%(c: connection, msg: dhcp_msg, req_addr: addr%); - -## Generated for DHCP messages of type *offer*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: TODO. -## -## mask: The subnet mask specified by the message. -## -## router: The list of routers specified by the message. -## -## lease: The least interval specified by the message. -## -## serv_addr: The server address specified by the message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_offer%(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr%); - -## Generated for DHCP messages of type *request*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## req_addr: The client address specified by the message. -## -## serv_addr: The server address specified by the message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_request%(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr%); - -## Generated for DHCP messages of type *decline*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_decline%(c: connection, msg: dhcp_msg%); - -## Generated for DHCP messages of type *acknowledgment*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## mask: The subnet mask specified by the message. -## -## router: The list of routers specified by the message. -## -## lease: The least interval specified by the message. -## -## serv_addr: The server address specified by the message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_ack%(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr%); - -## Generated for DHCP messages of type *negative acknowledgment*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_nak%(c: connection, msg: dhcp_msg%); - -## Generated for DHCP messages of type *release*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_release%(c: connection, msg: dhcp_msg%); - -## Generated for DHCP messages of type *inform*. -## -## See `Wikipedia -## `__ for -## more information about the DHCP protocol. -## -## c: The connection record describing the underlying UDP flow. -## -## msg: The parsed type-independent part of the DHCP message. -## -## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl -## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply -## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end -## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name -## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply -## dns_rejected dns_request non_dns_request -## -## .. note:: Bro does not support broadcast packets (as used by the DHCP -## protocol). It treats broadcast addresses just like any other and -## associates packets into transport-level flows in the same way as usual. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dhcp_inform%(c: connection, msg: dhcp_msg%); - -## Generated for HTTP requests. Bro supports persistent and pipelined HTTP -## sessions and raises corresponding events as it parses client/server -## dialogues. This event is generated as soon as a request's initial line has -## been parsed, and before any :bro:id:`http_header` events are raised. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## method: The HTTP method extracted from the request (e.g., ``GET``, ``POST``). -## -## original_URI: The unprocessed URI as specified in the request. -## -## unescaped_URI: The URI with all percent-encodings decoded. -## -## version: The version number specified in the request (e.g., ``1.1``). -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_event http_header http_message_done http_reply http_stats -## truncate_http_URI -event http_request%(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string%) &group="http-request"; - -## Generated for HTTP replies. Bro supports persistent and pipelined HTTP -## sessions and raises corresponding events as it parses client/server -## dialogues. This event is generated as soon as a reply's initial line has -## been parsed, and before any :bro:id:`http_header` events are raised. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## version: The version number specified in the reply (e.g., ``1.1``). -## -## code: The numerical response code returned by the server. -## -## reason: The textual description returned by the server along with *code*. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_event http_header http_message_done http_request -## http_stats -event http_reply%(c: connection, version: string, code: count, reason: string%) &group="http-reply"; - -## Generated for HTTP headers. Bro supports persistent and pipelined HTTP -## sessions and raises corresponding events as it parses client/server -## dialogues. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the header was sent by the originator of the TCP connection. -## -## name: The name of the header. -## -## value: The value of the header. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_event http_message_done http_reply http_request -## http_stats -## -## .. note:: This event is also raised for headers found in nested body -## entities. -event http_header%(c: connection, is_orig: bool, name: string, value: string%) &group="http-header"; - -## Generated for HTTP headers, passing on all headers of an HTTP message at -## once. Bro supports persistent and pipelined HTTP sessions and raises -## corresponding events as it parses client/server dialogues. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the header was sent by the originator of the TCP connection. -## -## hlist: A *table* containing all headers extracted from the current entity. -## The table is indexed by the position of the header (1 for the first, -## 2 for the second, etc.). -## -## .. bro:see:: http_begin_entity http_content_type http_end_entity http_entity_data -## http_event http_header http_message_done http_reply http_request http_stats -## -## .. note:: This event is also raised for headers found in nested body -## entities. -event http_all_headers%(c: connection, is_orig: bool, hlist: mime_header_list%) &group="http-header"; - -## Generated when starting to parse an HTTP body entity. This event is generated -## at least once for each non-empty (client or server) HTTP body; and -## potentially more than once if the body contains further nested MIME -## entities. Bro raises this event just before it starts parsing each entity's -## content. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the entity was sent by the originator of the TCP -## connection. -## -## .. bro:see:: http_all_headers http_content_type http_end_entity http_entity_data -## http_event http_header http_message_done http_reply http_request http_stats -## mime_begin_entity -event http_begin_entity%(c: connection, is_orig: bool%) &group="http-body"; - -## Generated when finishing parsing an HTTP body entity. This event is generated -## at least once for each non-empty (client or server) HTTP body; and -## potentially more than once if the body contains further nested MIME -## entities. Bro raises this event at the point when it has finished parsing an -## entity's content. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the entity was sent by the originator of the TCP -## connection. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_entity_data -## http_event http_header http_message_done http_reply http_request -## http_stats mime_end_entity -event http_end_entity%(c: connection, is_orig: bool%) &group="http-body"; - -## Generated when parsing an HTTP body entity, passing on the data. This event -## can potentially be raised many times for each entity, each time passing a -## chunk of the data of not further defined size. -## -## A common idiom for using this event is to first *reassemble* the data -## at the scripting layer by concatenating it to a successively growing -## string; and only perform further content analysis once the corresponding -## :bro:id:`http_end_entity` event has been raised. Note, however, that doing so -## can be quite expensive for HTTP tranders. At the very least, one should -## impose an upper size limit on how much data is being buffered. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the entity was sent by the originator of the TCP -## connection. -## -## length: The length of *data*. -## -## data: One chunk of raw entity data. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_event http_header http_message_done http_reply http_request http_stats -## mime_entity_data http_entity_data_delivery_size skip_http_data -event http_entity_data%(c: connection, is_orig: bool, length: count, data: string%) &group="http-body"; - -## Generated for reporting an HTTP body's content type. This event is -## generated at the end of parsing an HTTP header, passing on the MIME -## type as specified by the ``Content-Type`` header. If that header is -## missing, this event is still raised with a default value of ``text/plain``. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the entity was sent by the originator of the TCP -## connection. -## -## ty: The main type. -## -## subty: The subtype. -## -## .. bro:see:: http_all_headers http_begin_entity http_end_entity http_entity_data -## http_event http_header http_message_done http_reply http_request http_stats -## -## .. note:: This event is also raised for headers found in nested body -## entities. -event http_content_type%(c: connection, is_orig: bool, ty: string, subty: string%) &group="http-body"; - -## Generated once at the end of parsing an HTTP message. Bro supports persistent -## and pipelined HTTP sessions and raises corresponding events as it parses -## client/server dialogues. A "message" is one top-level HTTP entity, such as a -## complete request or reply. Each message can have further nested sub-entities -## inside. This event is raised once all sub-entities belonging to a top-level -## message have been processed (and their corresponding ``http_entity_*`` events -## generated). -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## is_orig: True if the entity was sent by the originator of the TCP -## connection. -## -## stat: Further meta information about the message. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_event http_header http_reply http_request http_stats -event http_message_done%(c: connection, is_orig: bool, stat: http_message_stat%) &group="http-body"; - -## Generated for errors found when decoding HTTP requests or replies. -## -## See `Wikipedia `__ -## for more information about the HTTP protocol. -## -## c: The connection. -## -## event_type: A string describing the general category of the problem found -## (e.g., ``illegal format``). -## -## detail: Further more detailed description of the error. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_header http_message_done http_reply http_request -## http_stats mime_event -event http_event%(c: connection, event_type: string, detail: string%); - -## Generated at the end of an HTTP session to report statistics about it. This -## event is raised after all of an HTTP session's requests and replies have been -## fully processed. -## -## c: The connection. -## -## stats: Statistics summarizing HTTP-level properties of the finished -## connection. -## -## .. bro:see:: http_all_headers http_begin_entity http_content_type http_end_entity -## http_entity_data http_event http_header http_message_done http_reply -## http_request -event http_stats%(c: connection, stats: http_stats_rec%); - -## Generated when seeing an SSH client's version identification. The SSH -## protocol starts with a clear-text handshake message that reports client and -## server protocol/software versions. This event provides access to what the -## client sent. -## -## -## See `Wikipedia `__ for more -## information about the SSH protocol. -## -## c: The connection. -## -## version: The version string the client sent (e.g., `SSH-2.0-libssh-0.11`). -## -## .. bro:see:: ssh_server_version -## -## .. note:: As everything after the initial version handshake proceeds -## encrypted, Bro cannot further analyze SSH sessions. -event ssh_client_version%(c: connection, version: string%); - -## Generated when seeing an SSH server's version identification. The SSH -## protocol starts with a clear-text handshake message that reports client and -## server protocol/software versions. This event provides access to what the -## server sent. -## -## See `Wikipedia `__ for more -## information about the SSH protocol. -## -## c: The connection. -## -## version: The version string the server sent (e.g., -## ``SSH-1.99-OpenSSH_3.9p1``). -## -## .. bro:see:: ssh_client_version -## -## .. note:: As everything coming after the initial version handshake proceeds -## encrypted, Bro cannot further analyze SSH sessions. -event ssh_server_version%(c: connection, version: string%); - -## Generated for an SSL/TLS client's initial *hello* message. SSL/TLS sessions -## start with an unencrypted handshake, and Bro extracts as much information out -## of that as it can. This event provides access to the initial information -## sent by the client. -## -## See `Wikipedia `__ for -## more information about the SSL/TLS protocol. -## -## c: The connection. -## -## version: The protocol version as extracted from the client's message. The -## values are standardized as part of the SSL/TLS protocol. The -## :bro:id:`SSL::version_strings` table maps them to descriptive names. -## -## possible_ts: The current time as sent by the client. Note that SSL/TLS does -## not require clocks to be set correctly, so treat with care. -## -## session_id: The session ID sent by the client (if any). -## -## ciphers: The list of ciphers the client offered to use. The values are -## standardized as part of the SSL/TLS protocol. The -## :bro:id:`SSL::cipher_desc` table maps them to descriptive names. -## -## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello -## ssl_session_ticket_handshake x509_certificate x509_error x509_extension -event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%); - -## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions -## start with an unencrypted handshake, and Bro extracts as much information out -## of that as it can. This event provides access to the initial information -## sent by the client. -## -## See `Wikipedia `__ for -## more information about the SSL/TLS protocol. -## -## c: The connection. -## -## version: The protocol version as extracted from the server's message. -## The values are standardized as part of the SSL/TLS protocol. The -## :bro:id:`SSL::version_strings` table maps them to descriptive names. -## -## possible_ts: The current time as sent by the server. Note that SSL/TLS does -## not require clocks to be set correctly, so treat with care. -## -## session_id: The session ID as sent back by the server (if any). -## -## cipher: The cipher chosen by the server. The values are standardized as part -## of the SSL/TLS protocol. The :bro:id:`SSL::cipher_desc` table maps -## them to descriptive names. -## -## comp_method: The compression method chosen by the client. The values are -## standardized as part of the SSL/TLS protocol. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_session_ticket_handshake x509_certificate x509_error x509_extension -event ssl_server_hello%(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count%); - -## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS -## sessions start with an unencrypted handshake, and Bro extracts as much -## information out of that as it can. This event provides access to any -## extensions either side sends as part of an extended *hello* message. -## -## c: The connection. -## -## is_orig: True if event is raised for originator side of the connection. -## -## code: The numerical code of the extension. The values are standardized as -## part of the SSL/TLS protocol. The :bro:id:`SSL::extensions` table maps -## them to descriptive names. -## -## val: The raw extension value that was sent in the message. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake x509_certificate x509_error x509_extension -event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); - -## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with -## an unencrypted handshake, and Bro extracts as much information out of that -## as it can. This event signals the time when an SSL/TLS has finished the -## handshake and its endpoints consider it as fully established. Typically, -## everything from now on will be encrypted. -## -## See `Wikipedia `__ for -## more information about the SSL/TLS protocol. -## -## c: The connection. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_extension ssl_server_hello -## ssl_session_ticket_handshake x509_certificate x509_error x509_extension -event ssl_established%(c: connection%); - -## Generated for SSL/TLS alert records. SSL/TLS sessions start with an -## unencrypted handshake, and Bro extracts as much information out of that as -## it can. If during that handshake, an endpoint encounters a fatal error, it -## sends an *alert* record, that in turn triggers this event. After an *alert*, -## any endpoint may close the connection immediately. -## -## See `Wikipedia `__ for -## more information about the SSL/TLS protocol. -## -## c: The connection. -## -## is_orig: True if event is raised for originator side of the connection. -## -## level: The severity level, as sent in the *alert*. The values are defined as -## part of the SSL/TLS protocol. -## -## desc: A numerical value identifying the cause of the *alert*. The values are -## defined as part of the SSL/TLS protocol. -## -## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello -## ssl_session_ticket_handshake x509_certificate x509_error x509_extension -event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); - -## Generated for SSL/TLS handshake messages that are a part of the -## stateless-server session resumption mechanism. SSL/TLS sessions start with -## an unencrypted handshake, and Bro extracts as much information out of that -## as it can. This event is raised when an SSL/TLS server passes a session -## ticket to the client that can later be used for resuming the session. The -## mechanism is described in :rfc:`4507` -## -## See `Wikipedia `__ for -## more information about the SSL/TLS protocol. -## -## c: The connection. -## -## ticket_lifetime_hint: A hint from the server about how long the ticket -## should be stored by the client. -## -## ticket: The raw ticket data. -## -## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello -## x509_certificate x509_error x509_extension ssl_alert -event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); - -## Generated for X509 certificates seen in SSL/TLS connections. During the -## initial SSL/TLS handshake, certificates are exchanged in the clear. Bro -## raises this event for each certificate seen (including both a site's primary -## cert, and further certs sent as part of the validation chain). -## -## See `Wikipedia `__ for more information -## about the X.509 format. -## -## c: The connection. -## -## is_orig: True if event is raised for originator side of the connection. -## -## cert: The parsed certificate. -## -## chain_idx: The index in the validation chain that this cert has. Index zero -## indicates an endpoint's primary cert, while higher indices -## indicate the place in the validation chain (which has length -## *chain_len*). -## -## chain_len: The total length of the validation chain that this cert is part -## of. -## -## der_cert: The complete cert encoded in `DER -## `__ -## format. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_server_hello x509_error x509_extension x509_verify -event x509_certificate%(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string%); - -## Generated for X509 extensions seen in a certificate. -## -## See `Wikipedia `__ for more information -## about the X.509 format. -## -## c: The connection. -## -## is_orig: True if event is raised for originator side of the connection. -## -## data: The raw data associated with the extension. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_server_hello x509_certificate x509_error x509_verify -event x509_extension%(c: connection, is_orig: bool, data: string%); - -## Generated when errors occur during parsing an X509 certificate. -## -## See `Wikipedia `__ for more information -## about the X.509 format. -## -## c: The connection. -## -## is_orig: True if event is raised for originator side of the connection. -## -## err: An error code describing what went wrong. :bro:id:`SSL::x509_errors` -## maps error codes to a textual description. -## -## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_server_hello x509_certificate x509_extension x509_err2str x509_verify -event x509_error%(c: connection, is_orig: bool, err: count%); - -## TODO. -## -## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_request -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dce_rpc_message%(c: connection, is_orig: bool, ptype: dce_rpc_ptype, msg: string%); - -## TODO. -## -## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_message dce_rpc_request -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dce_rpc_bind%(c: connection, uuid: string%); - -## TODO. -## -## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message -## dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dce_rpc_request%(c: connection, opnum: count, stub: string%); - -## TODO. -## -## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message -## dce_rpc_request rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event dce_rpc_response%(c: connection, opnum: count, stub: string%); - -## TODO. -## -## .. bro:see:: rpc_call rpc_dialogue rpc_reply dce_rpc_bind dce_rpc_message -## dce_rpc_request dce_rpc_response rpc_timeout -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event epm_map_response%(c: connection, uuid: string, p: port, h: addr%); - -## Generated for NCP requests (Netware Core Protocol). -## -## See `Wikipedia `__ for -## more information about the NCP protocol. -## -## c: The connection. -## -## frame_type: The frame type, as specified by the protocol. -## -## length: The length of the request body, excluding the frame header. -## -## func: The requested function, as specified by the protocol. -## -## .. bro:see:: ncp_reply -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ncp_request%(c: connection, frame_type: count, length: count, func: count%); - -## Generated for NCP replies (Netware Core Protocol). -## -## See `Wikipedia `__ for -## more information about the NCP protocol. -## -## c: The connection. -## -## frame_type: The frame type, as specified by the protocol. -## -## length: The length of the request body, excluding the frame header. -## -## req_frame: The frame type from the corresponding request. -## -## req_func: The function code from the corresponding request. -## -## completion_code: The reply's completion code, as specified by the protocol. -## -## .. bro:see:: ncp_request -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event ncp_reply%(c: connection, frame_type: count, length: count, req_frame: count, req_func: count, completion_code: count%); - -## Generated for client-side commands on POP3 connections. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## command: The command sent. -## -## arg: The argument to the command. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply -## pop3_terminate pop3_unexpected -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_request%(c: connection, is_orig: bool, - command: string, arg: string%); - -## Generated for server-side replies to commands on POP3 connections. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## cmd: The success indicator sent by the server. This corresponds to the -## first token on the line sent, and should be either ``OK`` or ``ERR``. -## -## msg: The textual description the server sent along with *cmd*. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_request -## pop3_terminate pop3_unexpected -## -## .. todo:: This event is receiving odd parameters, should unify. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_reply%(c: connection, is_orig: bool, cmd: string, msg: string%); - -## Generated for server-side multi-line responses on POP3 connections. POP3 -## connections use multi-line responses to send bulk data, such as the actual -## mails. This event is generated once for each line that's part of such a -## response. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: True if the data was sent by the originator of the TCP connection. -## -## data: The data sent. -## -## .. bro:see:: pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_terminate pop3_unexpected -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_data%(c: connection, is_orig: bool, data: string%); - -## Generated for errors encountered on POP3 sessions. If the POP3 analyzer -## finds state transitions that do not conform to the protocol specification, -## or other situations it can't handle, it raises this event. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: True if the data was sent by the originator of the TCP connection. -## -## msg: A textual description of the situation. -## -## detail: The input that triggered the event. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_terminate -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_unexpected%(c: connection, is_orig: bool, - msg: string, detail: string%); - -## Generated when a POP3 connection goes encrypted. While POP3 is by default a -## clear-text protocol, extensions exist to switch to encryption. This event is -## generated if that happens and the analyzer then stops processing the -## connection. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: Always false. -## -## msg: A descriptive message why processing was stopped. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_login_success pop3_reply pop3_request -## pop3_unexpected -## -## .. note:: Currently, only the ``STARTLS`` command is recognized and -## triggers this. -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_terminate%(c: connection, is_orig: bool, msg: string%); - -## Generated for successful authentications on POP3 connections. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: Always false. -## -## user: The user name used for authentication. The event is only generated if -## a non-empty user name was used. -## -## password: The password used for authentication. -## -## .. bro:see:: pop3_data pop3_login_failure pop3_reply pop3_request pop3_terminate -## pop3_unexpected -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_login_success%(c: connection, is_orig: bool, - user: string, password: string%); - -## Generated for unsuccessful authentications on POP3 connections. -## -## See `Wikipedia `__ for more information -## about the POP3 protocol. -## -## c: The connection. -## -## is_orig: Always false. -## -## user: The user name attempted for authentication. The event is only -## generated if a non-empty user name was used. -## -## password: The password attempted for authentication. -## -## .. bro:see:: pop3_data pop3_login_success pop3_reply pop3_request pop3_terminate -## pop3_unexpected -## -## .. todo:: Bro's current default configuration does not activate the protocol -## analyzer that generates this event; the corresponding script has not yet -## been ported to Bro 2.x. To still enable this event, one needs to add a -## corresponding entry to :bro:see:`dpd_config` or a DPD payload signature. -event pop3_login_failure%(c: connection, is_orig: bool, - user: string, password: string%); - - -## Generated for all client-side IRC commands. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: Always true. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## command: The command. -## -## arguments: The arguments for the command. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -## -## .. note:: This event is generated only for messages that originate -## at the client-side. Commands coming in from remote trigger -## the :bro:id:`irc_message` event instead. -event irc_request%(c: connection, is_orig: bool, prefix: string, - command: string, arguments: string%); - -## Generated for all IRC replies. IRC replies are sent in response to a -## request and come with a reply code. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the reply. IRC uses the prefix to -## indicate the true origin of a message. -## -## code: The reply code, as specified by the protocol. -## -## params: The reply's parameters. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_reply%(c: connection, is_orig: bool, prefix: string, - code: count, params: string%); - -## Generated for IRC commands forwarded from the server to the client. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: Always false. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## command: The command. -## -## message: TODO. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -## -## .. note:: -## -## This event is generated only for messages that are forwarded by the server -## to the client. Commands coming from client trigger the -## :bro:id:`irc_request` event instead. -event irc_message%(c: connection, is_orig: bool, prefix: string, - command: string, message: string%); - -## Generated for IRC messages of type *quit*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## nick: The nickname coming with the message. -## -## message: The text included with the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_quit_message%(c: connection, is_orig: bool, nick: string, message: string%); - -## Generated for IRC messages of type *privmsg*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## source: The source of the private communication. -## -## target: The target of the private communication. -## -## message: The text of communication. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_privmsg_message%(c: connection, is_orig: bool, source: string, - target: string, message: string%); - -## Generated for IRC messages of type *notice*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## source: The source of the private communication. -## -## target: The target of the private communication. -## -## message: The text of communication. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_notice_message%(c: connection, is_orig: bool, source: string, - target: string, message: string%); - -## Generated for IRC messages of type *squery*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## source: The source of the private communication. -## -## target: The target of the private communication. -## -## message: The text of communication. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_squery_message%(c: connection, is_orig: bool, source: string, - target: string, message: string%); - -## Generated for IRC messages of type *join*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## info_list: The user information coming with the command. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_join_message%(c: connection, is_orig: bool, info_list: irc_join_list%); - -## Generated for IRC messages of type *part*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## nick: The nickname coming with the message. -## -## chans: The set of channels affected. -## -## message: The text coming with the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_password_message -event irc_part_message%(c: connection, is_orig: bool, nick: string, - chans: string_set, message: string%); - -## Generated for IRC messages of type *nick*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## who: The user changing its nickname. -## -## newnick: The new nickname. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_nick_message%(c: connection, is_orig: bool, who: string, newnick: string%); - -## Generated when a server rejects an IRC nickname. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_invalid_nick%(c: connection, is_orig: bool%); - -## Generated for an IRC reply of type *luserclient*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## users: The number of users as returned in the reply. -## -## services: The number of services as returned in the reply. -## -## servers: The number of servers as returned in the reply. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_network_info%(c: connection, is_orig: bool, users: count, - services: count, servers: count%); - -## Generated for an IRC reply of type *luserme*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## users: The number of users as returned in the reply. -## -## services: The number of services as returned in the reply. -## -## servers: The number of servers as returned in the reply. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_server_info%(c: connection, is_orig: bool, users: count, - services: count, servers: count%); - -## Generated for an IRC reply of type *luserchannels*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## chans: The number of channels as returned in the reply. -## -## .. bro:see:: irc_channel_topic irc_dcc_message irc_error_message irc_global_users -## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_channel_info%(c: connection, is_orig: bool, chans: count%); - -## Generated for an IRC reply of type *whoreply*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## target_nick: The target nickname. -## -## channel: The channel. -## -## user: The user. -## -## host: The host. -## -## server: The server. -## -## nick: The nickname. -## -## params: The parameters. -## -## hops: The hop count. -## -## real_name: The real name. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_who_line%(c: connection, is_orig: bool, target_nick: string, - channel: string, user: string, host: string, - server: string, nick: string, params: string, - hops: count, real_name: string%); - - -## Generated for an IRC reply of type *namereply*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## c_type: The channel type. -## -## channel: The channel. -## -## users: The set of users. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_names_info%(c: connection, is_orig: bool, c_type: string, - channel: string, users: string_set%); - -## Generated for an IRC reply of type *whoisoperator*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## nick: The nickname specified in the reply. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_whois_operator_line%(c: connection, is_orig: bool, nick: string%); - -## Generated for an IRC reply of type *whoischannels*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## nick: The nickname specified in the reply. -## -## chans: The set of channels returned. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_whois_channel_line%(c: connection, is_orig: bool, nick: string, - chans: string_set%); - -## Generated for an IRC reply of type *whoisuser*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## nick: The nickname specified in the reply. -## -## user: The user name specified in the reply. -## -## host: The host name specified in the reply. -## -## real_name: The real name specified in the reply. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_whois_user_line%(c: connection, is_orig: bool, nick: string, - user: string, host: string, real_name: string%); - -## Generated for IRC replies of type *youreoper* and *nooperhost*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## got_oper: True if the *oper* command was executed successfully -## (*youreport*) and false otherwise (*nooperhost*). -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_part_message -## irc_password_message -event irc_oper_response%(c: connection, is_orig: bool, got_oper: bool%); - -## Generated for an IRC reply of type *globalusers*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## msg: The message coming with the reply. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_global_users%(c: connection, is_orig: bool, prefix: string, msg: string%); - -## Generated for an IRC reply of type *topic*. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## channel: The channel name specified in the reply. -## -## topic: The topic specified in the reply. -## -## .. bro:see:: irc_channel_info irc_dcc_message irc_error_message irc_global_users -## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_channel_topic%(c: connection, is_orig: bool, channel: string, topic: string%); - -## Generated for IRC messages of type *who*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## mask: The mask specified in the message. -## -## oper: True if the operator flag was set. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_who_message%(c: connection, is_orig: bool, mask: string, oper: bool%); - -## Generated for IRC messages of type *whois*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## server: TODO. -## -## users: TODO. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_whois_message%(c: connection, is_orig: bool, server: string, users: string%); - -## Generated for IRC messages of type *oper*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## user: The user specified in the message. -## -## password: The password specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_response irc_part_message -## irc_password_message -event irc_oper_message%(c: connection, is_orig: bool, user: string, password: string%); - -## Generated for IRC messages of type *kick*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## chans: The channels specified in the message. -## -## users: The users specified in the message. -## -## comment: The comment specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_kick_message%(c: connection, is_orig: bool, prefix: string, - chans: string, users: string, comment: string%); - -## Generated for IRC messages of type *error*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## message: The textual description specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_global_users -## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_error_message%(c: connection, is_orig: bool, prefix: string, message: string%); - -## Generated for IRC messages of type *invite*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## nickname: The nickname specified in the message. -## -## channel: The channel specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_invite_message%(c: connection, is_orig: bool, prefix: string, - nickname: string, channel: string%); - -## Generated for IRC messages of type *mode*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## params: The parameters coming with the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_mode_message%(c: connection, is_orig: bool, prefix: string, params: string%); - -## Generated for IRC messages of type *squit*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## server: The server specified in the message. -## -## message: The textual description specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_squit_message%(c: connection, is_orig: bool, prefix: string, - server: string, message: string%); - -## Generated for IRC messages of type *dcc*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## prefix: The optional prefix coming with the command. IRC uses the prefix to -## indicate the true origin of a message. -## -## target: The target specified in the message. -## -## dcc_type: The DCC type specified in the message. -## -## argument: The argument specified in the message. -## -## address: The address specified in the message. -## -## dest_port: The destination port specified in the message. -## -## size: The size specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_error_message irc_global_users -## irc_invalid_nick irc_invite_message irc_join_message irc_kick_message -## irc_message irc_mode_message irc_names_info irc_network_info irc_nick_message -## irc_notice_message irc_oper_message irc_oper_response irc_part_message -## irc_password_message -event irc_dcc_message%(c: connection, is_orig: bool, - prefix: string, target: string, - dcc_type: string, argument: string, - address: addr, dest_port: count, size: count%); - -## Generated for IRC messages of type *user*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## user: The user specified in the message. -## -## host: The host name specified in the message. -## -## server: The server name specified in the message. -## -## real_name: The real name specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message irc_password_message -event irc_user_message%(c: connection, is_orig: bool, user: string, host: string, server: string, real_name: string%); - -## Generated for IRC messages of type *password*. This event is generated for -## messages coming from both the client and the server. -## -## See `Wikipedia `__ for more -## information about the IRC protocol. -## -## c: The connection. -## -## is_orig: True if the command was sent by the originator of the TCP -## connection. -## -## password: The password specified in the message. -## -## .. bro:see:: irc_channel_info irc_channel_topic irc_dcc_message irc_error_message -## irc_global_users irc_invalid_nick irc_invite_message irc_join_message -## irc_kick_message irc_message irc_mode_message irc_names_info irc_network_info -## irc_nick_message irc_notice_message irc_oper_message irc_oper_response -## irc_part_message -event irc_password_message%(c: connection, is_orig: bool, password: string%); - -## TODO. -## -event file_transferred%(c: connection, prefix: string, descr: string, mime_type: string%); - -## Generated for monitored Syslog messages. -## -## See `Wikipedia `__ for more -## information about the Syslog protocol. -## -## c: The connection record for the underlying transport-layer session/flow. -## -## facility: The "facility" included in the message. -## -## severity: The "severity" included in the message. -## -## msg: The message logged. -## -## .. note:: Bro currently parses only UDP syslog traffic. Support for TCP -## syslog will be added soon. -event syslog_message%(c: connection, facility: count, severity: count, msg: string%); - ## Generated when a signature matches. Bro's signature engine provides ## high-performance pattern matching separately from the normal script ## processing. If a signature with an ``event`` action matches, this event is @@ -6292,35 +532,6 @@ event syslog_message%(c: connection, facility: count, severity: count, msg: stri ## triggering the match will be passed on to the event. event signature_match%(state: signature_state, msg: string, data: string%); -## Generated when a SOCKS request is analyzed. -## -## c: The parent connection of the proxy. -## -## version: The version of SOCKS this message used. -## -## request_type: The type of the request. -## -## sa: Address that the tunneled traffic should be sent to. -## -## p: The destination port for the proxied traffic. -## -## user: Username given for the SOCKS connection. This is not yet implemented -## for SOCKSv5. -event socks_request%(c: connection, version: count, request_type: count, sa: SOCKS::Address, p: port, user: string%); - -## Generated when a SOCKS reply is analyzed. -## -## c: The parent connection of the proxy. -## -## version: The version of SOCKS this message used. -## -## reply: The status reply from the server. -## -## sa: The address that the server sent the traffic to. -## -## p: The destination port for the proxied traffic. -event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Address, p: port%); - ## Generated when a protocol analyzer finds an identification of a software ## used on a system. This is a protocol-independent event that is fed by ## different analyzers. For example, the HTTP analyzer reports user-agent and @@ -6338,7 +549,7 @@ event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Addre ## ## .. bro:see:: software_parse_error software_unparsed_version_found OS_version_found event software_version_found%(c: connection, host: addr, - s: software, descr: string%); + s: software, descr: string%); ## Generated when a protocol analyzer finds an identification of a software ## used on a system but cannot parse it. This is a protocol-independent event @@ -6449,8 +660,6 @@ event remote_event_registered%(p: event_peer, name: string%); ## remote_state_inconsistency print_hook event remote_connection_error%(p: event_peer, reason: string%); - - ## Generated when a remote peer sent us a capture filter. While this event is ## intended primarily for use by Bro's communication framework, it can also ## trigger additional code if helpful. @@ -6569,7 +778,7 @@ event remote_log_peer%(p: event_peer, level: count, src: count, msg: string%); ## remote_event_registered remote_log remote_state_access_performed ## remote_state_inconsistency print_hook event remote_pong%(p: event_peer, seq: count, - d1: interval, d2: interval, d3: interval%); + d1: interval, d2: interval, d3: interval%); ## Generated each time a remote state access has been replayed locally. This ## event is primarily intended for debugging. @@ -6596,326 +805,6 @@ event remote_state_access_performed%(id: string, v: any%); ## .. bro:see:: profiling_interval expensive_profiling_multiple event profiling_update%(f: file, expensive: bool%); -## Generated each time Bro's script interpreter opens a file. This event is -## triggered only for files opened via :bro:id:`open`, and in particular not for -## normal log files as created by log writers. -## -## f: The opened file. -event file_opened%(f: file%); - -## Generated for a received NetFlow v5 header. Bro's NetFlow processor raises -## this event whenever it either receives a NetFlow header on the port it's -## listening on, or reads one from a trace file. -## -## h: The parsed NetFlow header. -## -## .. bro:see:: netflow_v5_record -event netflow_v5_header%(h: nf_v5_header%); - -## Generated for a received NetFlow v5 record. Bro's NetFlow processor raises -## this event whenever it either receives a NetFlow record on the port it's -## listening on, or reads one from a trace file. -## -## r: The parsed NetFlow record. -## -## .. bro:see:: netflow_v5_record -event netflow_v5_record%(r: nf_v5_record%); - -## Generated for any modbus message regardless if the particular function -## is further supported or not. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## is_orig: True if the event is raised for the originator side. -event modbus_message%(c: connection, headers: ModbusHeaders, is_orig: bool%); - -## Generated for any modbus exception message. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## code: The exception code. -event modbus_exception%(c: connection, headers: ModbusHeaders, code: count%); - -## Generated for a Modbus read coils request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address where of the first coil to be read. -## -## quantity: The number of coils to be read. -event modbus_read_coils_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus read coils response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## coils: The coil values returned from the device. -event modbus_read_coils_response%(c: connection, headers: ModbusHeaders, coils: ModbusCoils%); - -## Generated for a Modbus read discrete inputs request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first coil to be read. -## -## quantity: The number of coils to be read. -event modbus_read_discrete_inputs_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus read discrete inputs response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## coils: The coil values returned from the device. -event modbus_read_discrete_inputs_response%(c: connection, headers: ModbusHeaders, coils: ModbusCoils%); - -## Generated for a Modbus read holding registers request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first register to be read. -## -## quantity: The number of registers to be read. -event modbus_read_holding_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus read holding registers response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## registers: The register values returned from the device. -event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%); - -## Generated for a Modbus read input registers request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first register to be read. -## -## quantity: The number of registers to be read. -event modbus_read_input_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus read input registers response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## registers: The register values returned from the device. -event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%); - -## Generated for a Modbus write single coil request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the coil to be written. -## -## value: The value to be written to the coil. -event modbus_write_single_coil_request%(c: connection, headers: ModbusHeaders, address: count, value: bool%); - -## Generated for a Modbus write single coil response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the coil that was written. -## -## value: The value that was written to the coil. -event modbus_write_single_coil_response%(c: connection, headers: ModbusHeaders, address: count, value: bool%); - -## Generated for a Modbus write single register request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the register to be written. -## -## value: The value to be written to the register. -event modbus_write_single_register_request%(c: connection, headers: ModbusHeaders, address: count, value: count%); - -## Generated for a Modbus write single register response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the register that was written. -## -## value: The value that was written to the register. -event modbus_write_single_register_response%(c: connection, headers: ModbusHeaders, address: count, value: count%); - -## Generated for a Modbus write multiple coils request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first coil to be written. -## -## value: The values to be written to the coils. -event modbus_write_multiple_coils_request%(c: connection, headers: ModbusHeaders, start_address: count, coils: ModbusCoils%); - -## Generated for a Modbus write multiple coils response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first coil that was written. -## -## quantity: The quantity of coils that were written. -event modbus_write_multiple_coils_response%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus write multiple registers request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first register to be written. -## -## registers: The values to be written to the registers. -event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters%); - -## Generated for a Modbus write multiple registers response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The memory address of the first register that was written. -## -## quantity: The quantity of registers that were written. -event modbus_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, start_address: count, quantity: count%); - -## Generated for a Modbus read file record request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## .. note: This event is incomplete. The information from the data structure is not -## yet passed through to the event. -event modbus_read_file_record_request%(c: connection, headers: ModbusHeaders%); - -## Generated for a Modbus read file record response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## .. note: This event is incomplete. The information from the data structure is not -## yet passed through to the event. -event modbus_read_file_record_response%(c: connection, headers: ModbusHeaders%); - -## Generated for a Modbus write file record request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## .. note: This event is incomplete. The information from the data structure is not -## yet passed through to the event. -event modbus_write_file_record_request%(c: connection, headers: ModbusHeaders%); - -## Generated for a Modbus write file record response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## .. note: This event is incomplete. The information from the data structure is not -## yet passed through to the event. -event modbus_write_file_record_response%(c: connection, headers: ModbusHeaders%); - -## Generated for a Modbus mask write register request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the register where the masks should be applied. -## -## and_mask: The value of the logical AND mask to apply to the register. -## -## or_mask: The value of the logical OR mask to apply to the register. -event modbus_mask_write_register_request%(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count%); - -## Generated for a Modbus mask write register request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## address: The memory address of the register where the masks were applied. -## -## and_mask: The value of the logical AND mask applied register. -## -## or_mask: The value of the logical OR mask applied to the register. -event modbus_mask_write_register_response%(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count%); - -## Generated for a Modbus read/write multiple registers request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## read_start_address: The memory address of the first register to be read. -## -## read_quantity: The number of registers to read. -## -## write_start_address: The memory address of the first register to be written. -## -## write_registers: The values to be written to the registers. -event modbus_read_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_registers: ModbusRegisters%); - -## Generated for a Modbus read/write multiple registers response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## written_registers: The register values read from the registers specified in the request. -event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters%); - -## Generated for a Modbus read FIFO queue request. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## start_address: The address of the FIFO queue to read. -event modbus_read_fifo_queue_request%(c: connection, headers: ModbusHeaders, start_address: count%); - -## Generated for a Modbus read FIFO queue response. -## -## c: The connection. -## -## headers: The headers for the modbus function. -## -## fifos: The register values read from the FIFO queue on the device. -event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters%); - ## Raised for informational messages reported via Bro's reporter framework. Such ## messages may be generated internally by the event engine and also by other ## scripts calling :bro:id:`Reporter::info`. @@ -6981,6 +870,13 @@ event reporter_error%(t: time, msg: string, location: string%) &error_handler; ## recursively for each ``@load``. event bro_script_loaded%(path: string, level: count%); +## Generated each time Bro's script interpreter opens a file. This event is +## triggered only for files opened via :bro:id:`open`, and in particular not for +## normal log files as created by log writers. +## +## f: The opened file. +event file_opened%(f: file%); + ## Marks a point in the event stream at which the event queue started flushing. event event_queue_flush_point%(%); @@ -6998,7 +894,7 @@ event event_queue_flush_point%(%); ## is_orig: The direction the file data is flowing over the connection. ## ## .. bro:see:: set_file_handle -event get_file_handle%(tag: count, c: connection, is_orig: bool%); +event get_file_handle%(tag: Analyzer::Tag, c: connection, is_orig: bool%); ## Indicates that an analysis of a new file has begun. The analysis can be ## augmented at this time via :bro:see:`Files::add_analyzer`. @@ -7046,95 +942,81 @@ event file_gap%(f: fa_file, offset: count, len: count%); ## .. bro:see:: file_new file_over_new_connection file_timeout file_gap event file_state_remove%(f: fa_file%); -## This event is generated each time file analysis generates a digest of the -## file contents. +## Generated when an internal DNS lookup produces the same result as last time. +## Bro keeps an internal DNS cache for host names and IP addresses it has +## already resolved. This event is generated when a subsequent lookup returns +## the same result as stored in the cache. ## -## f: The file. +## dm: A record describing the new resolver result (which matches the old one). ## -## kind: The type of digest algorithm. +## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_unverified +event dns_mapping_valid%(dm: dns_mapping%); + +## Generated when an internal DNS lookup got no answer even though it had +## succeeded in the past. Bro keeps an internal DNS cache for host names and IP +## addresses it has already resolved. This event is generated when a +## subsequent lookup does not produce an answer even though we have +## already stored a result in the cache. ## -## hash: The result of the hashing. +## dm: A record describing the old resolver result. ## -## .. bro:see:: Files::add_analyzer Files::ANALYZER_MD5 -## Files::ANALYZER_SHA1 Files::ANALYZER_SHA256 -event file_hash%(f: fa_file, kind: string, hash: string%); +## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name +## dns_mapping_valid +event dns_mapping_unverified%(dm: dns_mapping%); -## Deprecated. Will be removed. -event stp_create_endp%(c: connection, e: int, is_orig: bool%); +## Generated when an internal DNS lookup succeeded but an earlier attempt +## did not. Bro keeps an internal DNS cache for host names and IP +## addresses it has already resolved. This event is generated when a subsequent +## lookup produces an answer for a query that was marked as failed in the cache. +## +## dm: A record describing the new resolver result. +## +## .. bro:see:: dns_mapping_altered dns_mapping_lost_name dns_mapping_unverified +## dns_mapping_valid +event dns_mapping_new_name%(dm: dns_mapping%); -# ##### Internal events. Not further documented. +## Generated when an internal DNS lookup returned zero answers even though it +## had succeeded in the past. Bro keeps an internal DNS cache for host names +## and IP addresses it has already resolved. This event is generated when +## on a subsequent lookup we receive an answer that is empty even +## though we have already stored a result in the cache. +## +## dm: A record describing the old resolver result. +## +## .. bro:see:: dns_mapping_altered dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid +event dns_mapping_lost_name%(dm: dns_mapping%); -## Event internal to the stepping stone detector. -event stp_resume_endp%(e: int%); - -## Event internal to the stepping stone detector. -event stp_correlate_pair%(e1: int, e2: int%); - -## Event internal to the stepping stone detector. -event stp_remove_pair%(e1: int, e2: int%); - -## Event internal to the stepping stone detector. -event stp_remove_endp%(e: int%); - -# ##### Deprecated events. Proposed for removal. - -## Deprecated. Will be removed. -event interconn_stats%(c: connection, os: interconn_endp_stats, rs: interconn_endp_stats%); - -## Deprecated. Will be removed. -event interconn_remove_conn%(c: connection%); - -## Deprecated. Will be removed. -event backdoor_stats%(c: connection, os: backdoor_endp_stats, rs: backdoor_endp_stats%); - -## Deprecated. Will be removed. -event backdoor_remove_conn%(c: connection%); - -## Deprecated. Will be removed. -event ssh_signature_found%(c: connection, is_orig: bool%); - -## Deprecated. Will be removed. -event telnet_signature_found%(c: connection, is_orig: bool, len: count%); - -## Deprecated. Will be removed. -event rlogin_signature_found%(c: connection, is_orig: bool, num_null: count, len: count%); +## Generated when an internal DNS lookup produced a different result than in +## the past. Bro keeps an internal DNS cache for host names and IP addresses +## it has already resolved. This event is generated when a subsequent lookup +## returns a different answer than we have stored in the cache. +## +## dm: A record describing the new resolver result. +## +## old_addrs: Addresses that used to be part of the returned set for the query +## described by *dm*, but are not anymore. +## +## new_addrs: Addresses that were not part of the returned set for the query +## described by *dm*, but now are. +## +## .. bro:see:: dns_mapping_lost_name dns_mapping_new_name dns_mapping_unverified +## dns_mapping_valid +event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr_set%); ## Deprecated. Will be removed. event root_backdoor_signature_found%(c: connection%); -## Deprecated. Will be removed. -event ftp_signature_found%(c: connection%); - ## Deprecated. Will be removed. event napster_signature_found%(c: connection%); -## Deprecated. Will be removed. -event gnutella_signature_found%(c: connection%); - ## Deprecated. Will be removed. event kazaa_signature_found%(c: connection%); -## Deprecated. Will be removed. -event http_signature_found%(c: connection%); - -## Deprecated. Will be removed. -event http_proxy_signature_found%(c: connection%); - -## Deprecated. Will be removed. -event smtp_signature_found%(c: connection%); - -## Deprecated. Will be removed. -event irc_signature_found%(c: connection%); - ## Deprecated. Will be removed. event gaobot_signature_found%(c: connection%); -## Deprecated. Will be removed. -## -## .. todo:: Unclear what this event is for; it's never raised. We should just -## remove it. -event dns_full_request%(%) &group="dns"; - ## Deprecated. Will be removed. event anonymization_mapping%(orig: addr, mapped: addr%); diff --git a/src/file_analysis/Analyzer.h b/src/file_analysis/Analyzer.h index c348ab358b..0a5aa9e25c 100644 --- a/src/file_analysis/Analyzer.h +++ b/src/file_analysis/Analyzer.h @@ -5,10 +5,13 @@ #include "Val.h" #include "NetVar.h" +#include "analyzer/Tag.h" + +#include "file_analysis/file_analysis.bif.h" namespace file_analysis { -typedef BifEnum::Files::Analyzer FA_Tag; +typedef int FA_Tag; class File; @@ -94,8 +97,7 @@ public: static FA_Tag ArgsTag(const RecordVal* args) { using BifType::Record::Files::AnalyzerArgs; - return static_cast( - args->Lookup(AnalyzerArgs->FieldOffset("tag"))->AsEnum()); + return args->Lookup(AnalyzerArgs->FieldOffset("tag"))->AsEnum(); } protected: @@ -114,14 +116,11 @@ protected: private: - FA_Tag tag; /**< The particular analyzer type of the analyzer instance. */ - RecordVal* args; /**< \c AnalyzerArgs val gives tunable analyzer params. */ - File* file; /**< The file to which the analyzer is attached. */ + FA_Tag tag; /**< The particular analyzer type of the analyzer instance. */ + RecordVal* args; /**< \c AnalyzerArgs val gives tunable analyzer params. */ + File* file; /**< The file to which the analyzer is attached. */ }; -typedef file_analysis::Analyzer* (*AnalyzerInstantiator)(RecordVal* args, - File* file); - } // namespace file_analysis #endif diff --git a/src/file_analysis/AnalyzerSet.cc b/src/file_analysis/AnalyzerSet.cc index d10e78d338..c710d8b085 100644 --- a/src/file_analysis/AnalyzerSet.cc +++ b/src/file_analysis/AnalyzerSet.cc @@ -3,21 +3,10 @@ #include "AnalyzerSet.h" #include "File.h" #include "Analyzer.h" -#include "Extract.h" -#include "DataEvent.h" -#include "Hash.h" +#include "Manager.h" using namespace file_analysis; -// keep in order w/ declared enum values in file_analysis.bif -static AnalyzerInstantiator analyzer_factory[] = { - file_analysis::Extract::Instantiate, - file_analysis::MD5::Instantiate, - file_analysis::SHA1::Instantiate, - file_analysis::SHA256::Instantiate, - file_analysis::DataEvent::Instantiate, -}; - static void analyzer_del_func(void* v) { delete (file_analysis::Analyzer*) v; @@ -154,14 +143,13 @@ HashKey* AnalyzerSet::GetKey(const RecordVal* args) const file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(RecordVal* args) const { - file_analysis::Analyzer* a = - analyzer_factory[file_analysis::Analyzer::ArgsTag(args)](args, file); + FA_Tag tag = file_analysis::Analyzer::ArgsTag(args); + file_analysis::Analyzer* a = file_mgr->InstantiateAnalyzer(tag, args, file); if ( ! a ) { - DBG_LOG(DBG_FILE_ANALYSIS, "Instantiate analyzer %d failed for file id", - " %s", file_analysis::Analyzer::ArgsTag(args), - file->GetID().c_str()); + reporter->Error("Failed file analyzer %s instantiation for file id %s", + file_mgr->GetAnalyzerName(tag), file->GetID().c_str()); return 0; } diff --git a/src/file_analysis/AnalyzerSet.h b/src/file_analysis/AnalyzerSet.h index 7481e9020e..6f14149e30 100644 --- a/src/file_analysis/AnalyzerSet.h +++ b/src/file_analysis/AnalyzerSet.h @@ -187,7 +187,7 @@ private: }; typedef queue ModQueue; - ModQueue mod_queue; /**< A queue of analyzer additions/removals requests. */ + ModQueue mod_queue; /**< A queue of analyzer additions/removals requests. */ }; } // namespace file_analysiss diff --git a/src/file_analysis/CMakeLists.txt b/src/file_analysis/CMakeLists.txt new file mode 100644 index 0000000000..f22c293cc4 --- /dev/null +++ b/src/file_analysis/CMakeLists.txt @@ -0,0 +1,22 @@ +include(BroSubdir) + +include_directories(BEFORE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_subdirectory(analyzer) + +set(file_analysis_SRCS + Manager.cc + File.cc + FileTimer.cc + Analyzer.h + AnalyzerSet.cc + Component.cc +) + +bif_target(file_analysis.bif) + +bro_add_subdir_library(file_analysis ${file_analysis_SRCS} ${BIF_OUTPUT_CC}) +add_dependencies(bro_file_analysis generate_outputs) diff --git a/src/file_analysis/Component.cc b/src/file_analysis/Component.cc new file mode 100644 index 0000000000..d686918130 --- /dev/null +++ b/src/file_analysis/Component.cc @@ -0,0 +1,69 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Component.h" +#include "Manager.h" + +#include "../Desc.h" +#include "../util.h" + +using namespace file_analysis; + +analyzer::Tag::type_t Component::type_counter = 0; + +Component::Component(const char* arg_name, factory_callback arg_factory, + analyzer::Tag::subtype_t arg_subtype) + : plugin::Component(plugin::component::FILE_ANALYZER) + { + name = copy_string(arg_name); + canon_name = canonify_name(arg_name); + factory = arg_factory; + + tag = analyzer::Tag(++type_counter, arg_subtype); + } + +Component::Component(const Component& other) + : plugin::Component(Type()) + { + name = copy_string(other.name); + canon_name = copy_string(other.canon_name); + factory = other.factory; + tag = other.tag; + } + +Component::~Component() + { + delete [] name; + delete [] canon_name; + } + +analyzer::Tag Component::Tag() const + { + return tag; + } + +void Component::Describe(ODesc* d) + { + plugin::Component::Describe(d); + d->Add(name); + d->Add(" ("); + + if ( factory ) + { + d->Add("ANALYZER_"); + d->Add(canon_name); + } + + d->Add(")"); + } + +Component& Component::operator=(const Component& other) + { + if ( &other != this ) + { + name = copy_string(other.name); + factory = other.factory; + tag = other.tag; + } + + return *this; + } diff --git a/src/file_analysis/Component.h b/src/file_analysis/Component.h new file mode 100644 index 0000000000..5ec97f2e0c --- /dev/null +++ b/src/file_analysis/Component.h @@ -0,0 +1,109 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef FILE_ANALYZER_PLUGIN_COMPONENT_H +#define FILE_ANALYZER_PLUGIN_COMPONENT_H + +#include "analyzer/Tag.h" +#include "plugin/Component.h" + +#include "Val.h" + +#include "../config.h" +#include "../util.h" + +namespace file_analysis { + +class File; +class Analyzer; + +/** + * Component description for plugins providing file analyzers. + * + * A plugin can provide a specific file analyzer by registering this + * analyzer component, describing the analyzer. + */ +class Component : public plugin::Component { +public: + typedef Analyzer* (*factory_callback)(RecordVal* args, File* file); + + /** + * Constructor. + * + * @param name The name of the provided analyzer. This name is used + * across the system to identify the analyzer, e.g., when calling + * file_analysis::Manager::InstantiateAnalyzer with a name. + * + * @param factory A factory function to instantiate instances of the + * analyzer's class, which must be derived directly or indirectly + * from file_analysis::Analyzer. This is typically a static \c + * Instatiate() method inside the class that just allocates and + * returns a new instance. + * + * @param subtype A subtype associated with this component that + * further distinguishes it. The subtype will be integrated into + * the analyzer::Tag that the manager associates with this analyzer, + * and analyzer instances can accordingly access it via analyzer::Tag(). + * If not used, leave at zero. + */ + Component(const char* name, factory_callback factory, + analyzer::Tag::subtype_t subtype = 0); + + /** + * Copy constructor. + */ + Component(const Component& other); + + /** + * Destructor. + */ + ~Component(); + + /** + * Returns the name of the analyzer. This name is unique across all + * analyzers and used to identify it. The returned name is derived + * from what's passed to the constructor but upper-cased and + * canonified to allow being part of a script-level ID. + */ + const char* Name() const { return name; } + + /** + * Returns a canonocalized version of the analyzer's name. The + * returned name is derived from what's passed to the constructor but + * upper-cased and transformed to allow being part of a script-level + * ID. + */ + const char* CanonicalName() const { return canon_name; } + + /** + * Returns the analyzer's factory function. + */ + factory_callback Factory() const { return factory; } + + /** + * Returns the analyzer's tag. Note that this is automatically + * generated for each new Components, and hence unique across all of + * them. + */ + analyzer::Tag Tag() const; + + /** + * Generates a human-readable description of the component's main + * parameters. This goes into the output of \c "bro -NN". + */ + virtual void Describe(ODesc* d); + + Component& operator=(const Component& other); + +private: + const char* name; // The analyzer's name. + const char* canon_name; // The analyzer's canonical name. + factory_callback factory; // The analyzer's factory callback. + analyzer::Tag tag; // The automatically assigned analyzer tag. + + // Global counter used to generate unique tags. + static analyzer::Tag::type_t type_counter; +}; + +} + +#endif diff --git a/src/file_analysis/File.cc b/src/file_analysis/File.cc index c1ad92c0ed..b5edfaedc9 100644 --- a/src/file_analysis/File.cc +++ b/src/file_analysis/File.cc @@ -9,9 +9,11 @@ #include "Reporter.h" #include "Val.h" #include "Type.h" -#include "../Analyzer.h" #include "Event.h" +#include "analyzer/Analyzer.h" +#include "analyzer/Manager.h" + using namespace file_analysis; static Val* empty_connection_table() @@ -70,7 +72,7 @@ void File::StaticInit() mime_type_idx = Idx("mime_type"); } -File::File(const string& file_id, Connection* conn, AnalyzerTag::Tag tag, +File::File(const string& file_id, Connection* conn, analyzer::Tag tag, bool is_orig) : id(file_id), val(0), postpone_timeout(false), first_chunk(true), missed_bof(false), need_reassembly(false), done(false), analyzers(this) @@ -85,7 +87,7 @@ File::File(const string& file_id, Connection* conn, AnalyzerTag::Tag tag, if ( conn ) { // add source, connection, is_orig fields - SetSource(::Analyzer::GetTagName(tag)); + SetSource(analyzer_mgr->GetAnalyzerName(tag)); val->Assign(is_orig_idx, new Val(is_orig, TYPE_BOOL)); UpdateConnectionFields(conn); } diff --git a/src/file_analysis/File.h b/src/file_analysis/File.h index e889af3ea4..ac54c75bc5 100644 --- a/src/file_analysis/File.h +++ b/src/file_analysis/File.h @@ -6,7 +6,6 @@ #include #include -#include "AnalyzerTags.h" #include "Conn.h" #include "Val.h" #include "AnalyzerSet.h" @@ -166,7 +165,7 @@ protected: * direction. */ File(const string& file_id, Connection* conn = 0, - AnalyzerTag::Tag tag = AnalyzerTag::Error, bool is_orig = false); + analyzer::Tag tag = analyzer::Tag::Error, bool is_orig = false); /** * Updates the "conn_ids" and "conn_uids" fields in #val record with the diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 61f9f7a10d..02af4aa9f1 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -10,12 +10,18 @@ #include "Var.h" #include "Event.h" +#include "plugin/Manager.h" + using namespace file_analysis; TableVal* Manager::disabled = 0; +string Manager::salt; Manager::Manager() { + tag_enum_type = new EnumType("FileAnalysis::Tag"); + ::ID* id = install_ID("Tag", "FileAnalysis", true, true); + add_type(id, tag_enum_type, 0, 0); } Manager::~Manager() @@ -23,9 +29,44 @@ Manager::~Manager() Terminate(); } +void Manager::InitPreScript() + { + std::list analyzers = plugin_mgr->Components(); + + for ( std::list::const_iterator i = analyzers.begin(); + i != analyzers.end(); ++i ) + RegisterAnalyzerComponent(*i); + } + +void Manager::RegisterAnalyzerComponent(Component* component) + { + const char* cname = component->CanonicalName(); + + if ( tag_enum_type->Lookup("FileAnalysis", cname) != -1 ) + reporter->FatalError("File Analyzer %s defined more than once", cname); + + DBG_LOG(DBG_FILE_ANALYSIS, "Registering analyzer %s (tag %s)", + component->Name(), component->Tag().AsString().c_str()); + + analyzers_by_name.insert(std::make_pair(cname, component)); + analyzers_by_tag.insert(std::make_pair(component->Tag(), component)); + analyzers_by_val.insert(std::make_pair( + component->Tag().AsEnumVal()->InternalInt(), component)); + + string id = fmt("ANALYZER_%s", cname); + tag_enum_type->AddName("FileAnalysis", id.c_str(), + component->Tag().AsEnumVal()->InternalInt(), true); + } + +void Manager::InitPostScript() + { + #include "file_analysis.bif.init.cc" + } + void Manager::Terminate() { vector keys; + for ( IDMap::iterator it = id_map.begin(); it != id_map.end(); ++it ) keys.push_back(it->first); @@ -35,8 +76,6 @@ void Manager::Terminate() string Manager::HashHandle(const string& handle) const { - static string salt; - if ( salt.empty() ) salt = BifConst::Files::salt->CheckString(); @@ -60,7 +99,7 @@ void Manager::SetHandle(const string& handle) } void Manager::DataIn(const u_char* data, uint64 len, uint64 offset, - AnalyzerTag::Tag tag, Connection* conn, bool is_orig) + analyzer::Tag tag, Connection* conn, bool is_orig) { GetFileHandle(tag, conn, is_orig); File* file = GetFile(current_file_id, conn, tag, is_orig); @@ -74,7 +113,7 @@ void Manager::DataIn(const u_char* data, uint64 len, uint64 offset, RemoveFile(file->GetID()); } -void Manager::DataIn(const u_char* data, uint64 len, AnalyzerTag::Tag tag, +void Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag, Connection* conn, bool is_orig) { GetFileHandle(tag, conn, is_orig); @@ -108,13 +147,13 @@ void Manager::DataIn(const u_char* data, uint64 len, const string& file_id, RemoveFile(file->GetID()); } -void Manager::EndOfFile(AnalyzerTag::Tag tag, Connection* conn) +void Manager::EndOfFile(analyzer::Tag tag, Connection* conn) { EndOfFile(tag, conn, true); EndOfFile(tag, conn, false); } -void Manager::EndOfFile(AnalyzerTag::Tag tag, Connection* conn, bool is_orig) +void Manager::EndOfFile(analyzer::Tag tag, Connection* conn, bool is_orig) { // Don't need to create a file if we're just going to remove it right away. GetFileHandle(tag, conn, is_orig); @@ -126,7 +165,7 @@ void Manager::EndOfFile(const string& file_id) RemoveFile(file_id); } -void Manager::Gap(uint64 offset, uint64 len, AnalyzerTag::Tag tag, +void Manager::Gap(uint64 offset, uint64 len, analyzer::Tag tag, Connection* conn, bool is_orig) { GetFileHandle(tag, conn, is_orig); @@ -138,7 +177,7 @@ void Manager::Gap(uint64 offset, uint64 len, AnalyzerTag::Tag tag, file->Gap(offset, len); } -void Manager::SetSize(uint64 size, AnalyzerTag::Tag tag, Connection* conn, +void Manager::SetSize(uint64 size, analyzer::Tag tag, Connection* conn, bool is_orig) { GetFileHandle(tag, conn, is_orig); @@ -188,7 +227,7 @@ bool Manager::RemoveAnalyzer(const string& file_id, const RecordVal* args) const } File* Manager::GetFile(const string& file_id, Connection* conn, - AnalyzerTag::Tag tag, bool is_orig, bool update_conn) + analyzer::Tag tag, bool is_orig, bool update_conn) { if ( file_id.empty() ) return 0; @@ -288,7 +327,7 @@ bool Manager::IsIgnored(const string& file_id) return ignored.find(file_id) != ignored.end(); } -void Manager::GetFileHandle(AnalyzerTag::Tag tag, Connection* c, bool is_orig) +void Manager::GetFileHandle(analyzer::Tag tag, Connection* c, bool is_orig) { current_file_id.clear(); @@ -298,8 +337,11 @@ void Manager::GetFileHandle(AnalyzerTag::Tag tag, Connection* c, bool is_orig) if ( ! get_file_handle ) return; + EnumVal* tagval = tag.AsEnumVal(); + Ref(tagval); + val_list* vl = new val_list(); - vl->append(new Val(tag, TYPE_COUNT)); + vl->append(tagval); vl->append(c->BuildConnVal()); vl->append(new Val(is_orig, TYPE_BOOL)); @@ -307,7 +349,7 @@ void Manager::GetFileHandle(AnalyzerTag::Tag tag, Connection* c, bool is_orig) mgr.Drain(); // need file handle immediately so we don't have to buffer data } -bool Manager::IsDisabled(AnalyzerTag::Tag tag) +bool Manager::IsDisabled(analyzer::Tag tag) { if ( ! disabled ) disabled = internal_const_val("Files::disable")->AsTableVal(); @@ -324,3 +366,31 @@ bool Manager::IsDisabled(AnalyzerTag::Tag tag) return rval; } + +Analyzer* Manager::InstantiateAnalyzer(int tag, RecordVal* args, File* f) const + { + analyzer_map_by_val::const_iterator it = analyzers_by_val.find(tag); + + if ( it == analyzers_by_val.end() ) + reporter->InternalError("cannot instantiate unknown file analyzer: %d", + tag); + + Component* c = it->second; + + if ( ! c->Factory() ) + reporter->InternalError("file analyzer %s cannot be instantiated " + "dynamically", c->CanonicalName()); + + return c->Factory()(args, f); + } + +const char* Manager::GetAnalyzerName(int tag) const + { + analyzer_map_by_val::const_iterator it = analyzers_by_val.find(tag); + + if ( it == analyzers_by_val.end() ) + reporter->InternalError("cannot get name of unknown file analyzer: %d", + tag); + + return it->second->CanonicalName(); + } diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index 7a5edd0783..84b606173d 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -9,7 +9,6 @@ #include #include "Net.h" -#include "AnalyzerTags.h" #include "Conn.h" #include "Val.h" #include "Analyzer.h" @@ -18,6 +17,11 @@ #include "File.h" #include "FileTimer.h" +#include "Component.h" + +#include "analyzer/Tag.h" + +#include "file_analysis/file_analysis.bif.h" namespace file_analysis { @@ -37,6 +41,18 @@ public: */ ~Manager(); + /** + * First-stage initializion of the manager. This is called early on + * during Bro's initialization, before any scripts are processed. + */ + void InitPreScript(); + + /** + * Second-stage initialization of the manager. This is called late + * during Bro's initialization after any scripts are processed. + */ + void InitPostScript(); + /** * Times out any active file analysis to prepare for shutdown. */ @@ -67,7 +83,7 @@ public: * or false if is being sent in the opposite direction. */ void DataIn(const u_char* data, uint64 len, uint64 offset, - AnalyzerTag::Tag tag, Connection* conn, bool is_orig); + analyzer::Tag tag, Connection* conn, bool is_orig); /** * Pass in sequential file data. @@ -78,7 +94,7 @@ public: * @param is_orig true if the file is being sent from connection originator * or false if is being sent in the opposite direction. */ - void DataIn(const u_char* data, uint64 len, AnalyzerTag::Tag tag, + void DataIn(const u_char* data, uint64 len, analyzer::Tag tag, Connection* conn, bool is_orig); /** @@ -99,7 +115,7 @@ public: * @param tag network protocol over which the file data is transferred. * @param conn network connection over which the file data is transferred. */ - void EndOfFile(AnalyzerTag::Tag tag, Connection* conn); + void EndOfFile(analyzer::Tag tag, Connection* conn); /** * Signal the end of file data being transferred over a connection in @@ -107,7 +123,7 @@ public: * @param tag network protocol over which the file data is transferred. * @param conn network connection over which the file data is transferred. */ - void EndOfFile(AnalyzerTag::Tag tag, Connection* conn, bool is_orig); + void EndOfFile(analyzer::Tag tag, Connection* conn, bool is_orig); /** * Signal the end of file data being transferred using the file identifier. @@ -124,7 +140,7 @@ public: * @param is_orig true if the file is being sent from connection originator * or false if is being sent in the opposite direction. */ - void Gap(uint64 offset, uint64 len, AnalyzerTag::Tag tag, Connection* conn, + void Gap(uint64 offset, uint64 len, analyzer::Tag tag, Connection* conn, bool is_orig); /** @@ -135,7 +151,7 @@ public: * @param is_orig true if the file is being sent from connection originator * or false if is being sent in the opposite direction. */ - void SetSize(uint64 size, AnalyzerTag::Tag tag, Connection* conn, + void SetSize(uint64 size, analyzer::Tag tag, Connection* conn, bool is_orig); /** @@ -181,6 +197,23 @@ public: */ bool IsIgnored(const string& file_id); + /** + * Instantiates a new file analyzer instance for the file. + * @param tag The file analyzer's tag. + * @param args The file analzer argument/option values. + * @param f The file analzer is to be associated with. + * @return The new analyzer instance or null if tag is invalid. + */ + Analyzer* InstantiateAnalyzer(int tag, RecordVal* args, File* f) const; + + /** + * Translates a script-level file analyzer tag in to corresponding file + * analyzer name. + * @param tag The enum val of a file analyzer. + * @return The human-readable name of the file analyzer. + */ + const char* GetAnalyzerName(int tag) const; + protected: friend class FileTimer; @@ -205,7 +238,7 @@ protected: * connection-related fields. */ File* GetFile(const string& file_id, Connection* conn = 0, - AnalyzerTag::Tag tag = AnalyzerTag::Error, + analyzer::Tag tag = analyzer::Tag::Error, bool is_orig = false, bool update_conn = true); /** @@ -241,7 +274,7 @@ protected: * @param is_orig true if the file is being sent from connection originator * or false if is being sent in the opposite direction. */ - void GetFileHandle(AnalyzerTag::Tag tag, Connection* c, bool is_orig); + void GetFileHandle(analyzer::Tag tag, Connection* c, bool is_orig); /** * Check if analysis is available for files transferred over a given @@ -251,14 +284,26 @@ protected: * @return whether file analysis is disabled for the analyzer given by * \a tag. */ - static bool IsDisabled(AnalyzerTag::Tag tag); + static bool IsDisabled(analyzer::Tag tag); private: + typedef map analyzer_map_by_name; + typedef map analyzer_map_by_tag; + typedef map analyzer_map_by_val; + + void RegisterAnalyzerComponent(Component* component); + IDMap id_map; /**< Map file ID to file_analysis::File records. */ IDSet ignored; /**< Ignored files. Will be finally removed on EOF. */ - string current_file_id; /**< Hash of what get_file_handle event sets.*/ + string current_file_id; /**< Hash of what get_file_handle event sets. */ + EnumType* tag_enum_type; /**< File analyzer tag type. */ + + analyzer_map_by_name analyzers_by_name; + analyzer_map_by_tag analyzers_by_tag; + analyzer_map_by_val analyzers_by_val; static TableVal* disabled; /**< Table of disabled analyzers. */ + static string salt; /**< A salt added to file handles before hashing. */ }; } // namespace file_analysis diff --git a/src/file_analysis/analyzer/CMakeLists.txt b/src/file_analysis/analyzer/CMakeLists.txt new file mode 100644 index 0000000000..bfafcd2894 --- /dev/null +++ b/src/file_analysis/analyzer/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(data_event) +add_subdirectory(extract) +add_subdirectory(hash) diff --git a/src/file_analysis/analyzer/data_event/CMakeLists.txt b/src/file_analysis/analyzer/data_event/CMakeLists.txt new file mode 100644 index 0000000000..81551feda2 --- /dev/null +++ b/src/file_analysis/analyzer/data_event/CMakeLists.txt @@ -0,0 +1,8 @@ +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro FileDataEvent) +bro_plugin_cc(DataEvent.cc Plugin.cc) +bro_plugin_end() diff --git a/src/file_analysis/DataEvent.cc b/src/file_analysis/analyzer/data_event/DataEvent.cc similarity index 100% rename from src/file_analysis/DataEvent.cc rename to src/file_analysis/analyzer/data_event/DataEvent.cc diff --git a/src/file_analysis/DataEvent.h b/src/file_analysis/analyzer/data_event/DataEvent.h similarity index 100% rename from src/file_analysis/DataEvent.h rename to src/file_analysis/analyzer/data_event/DataEvent.h diff --git a/src/file_analysis/analyzer/data_event/Plugin.cc b/src/file_analysis/analyzer/data_event/Plugin.cc new file mode 100644 index 0000000000..7eb637f3a5 --- /dev/null +++ b/src/file_analysis/analyzer/data_event/Plugin.cc @@ -0,0 +1,26 @@ +#include "plugin/Plugin.h" +#include "file_analysis/Component.h" + +#include "DataEvent.h" + +namespace plugin { namespace Bro_FileDataEvent { + +class Plugin : public plugin::Plugin { +protected: + void InitPreScript() + { + SetName("Bro::FileDataEvent"); + SetVersion(-1); + SetAPIVersion(BRO_PLUGIN_API_VERSION); + SetDynamicPlugin(false); + + SetDescription("Delivers file content via events"); + + AddComponent(new ::file_analysis::Component("DATA_EVENT", + ::file_analysis::DataEvent::Instantiate)); + } +}; + +Plugin __plugin; + +} } diff --git a/src/file_analysis/analyzer/extract/CMakeLists.txt b/src/file_analysis/analyzer/extract/CMakeLists.txt new file mode 100644 index 0000000000..df3fa2646d --- /dev/null +++ b/src/file_analysis/analyzer/extract/CMakeLists.txt @@ -0,0 +1,8 @@ +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro FileExtract) +bro_plugin_cc(Extract.cc Plugin.cc) +bro_plugin_end() diff --git a/src/file_analysis/Extract.cc b/src/file_analysis/analyzer/extract/Extract.cc similarity index 100% rename from src/file_analysis/Extract.cc rename to src/file_analysis/analyzer/extract/Extract.cc diff --git a/src/file_analysis/Extract.h b/src/file_analysis/analyzer/extract/Extract.h similarity index 100% rename from src/file_analysis/Extract.h rename to src/file_analysis/analyzer/extract/Extract.h diff --git a/src/file_analysis/analyzer/extract/Plugin.cc b/src/file_analysis/analyzer/extract/Plugin.cc new file mode 100644 index 0000000000..f6cde57f03 --- /dev/null +++ b/src/file_analysis/analyzer/extract/Plugin.cc @@ -0,0 +1,26 @@ +#include "plugin/Plugin.h" +#include "file_analysis/Component.h" + +#include "Extract.h" + +namespace plugin { namespace Bro_FileExtract { + +class Plugin : public plugin::Plugin { +protected: + void InitPreScript() + { + SetName("Bro::FileExtract"); + SetVersion(-1); + SetAPIVersion(BRO_PLUGIN_API_VERSION); + SetDynamicPlugin(false); + + SetDescription("Extract file content to local file system"); + + AddComponent(new ::file_analysis::Component("EXTRACT", + ::file_analysis::Extract::Instantiate)); + } +}; + +Plugin __plugin; + +} } diff --git a/src/file_analysis/analyzer/hash/CMakeLists.txt b/src/file_analysis/analyzer/hash/CMakeLists.txt new file mode 100644 index 0000000000..5734740198 --- /dev/null +++ b/src/file_analysis/analyzer/hash/CMakeLists.txt @@ -0,0 +1,9 @@ +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro FileHash) +bro_plugin_cc(Hash.cc Plugin.cc) +bro_plugin_bif(events.bif) +bro_plugin_end() diff --git a/src/file_analysis/Hash.cc b/src/file_analysis/analyzer/hash/Hash.cc similarity index 100% rename from src/file_analysis/Hash.cc rename to src/file_analysis/analyzer/hash/Hash.cc diff --git a/src/file_analysis/Hash.h b/src/file_analysis/analyzer/hash/Hash.h similarity index 99% rename from src/file_analysis/Hash.h rename to src/file_analysis/analyzer/hash/Hash.h index e44af337aa..13303e21fc 100644 --- a/src/file_analysis/Hash.h +++ b/src/file_analysis/analyzer/hash/Hash.h @@ -10,6 +10,8 @@ #include "File.h" #include "Analyzer.h" +#include "events.bif.h" + namespace file_analysis { /** diff --git a/src/file_analysis/analyzer/hash/Plugin.cc b/src/file_analysis/analyzer/hash/Plugin.cc new file mode 100644 index 0000000000..1a7254105e --- /dev/null +++ b/src/file_analysis/analyzer/hash/Plugin.cc @@ -0,0 +1,33 @@ +#include "plugin/Plugin.h" +#include "file_analysis/Component.h" + +#include "Hash.h" + +namespace plugin { namespace Bro_FileHash { + +class Plugin : public plugin::Plugin { +protected: + void InitPreScript() + { + SetName("Bro::FileHash"); + SetVersion(-1); + SetAPIVersion(BRO_PLUGIN_API_VERSION); + SetDynamicPlugin(false); + + SetDescription("Hash file content"); + + AddComponent(new ::file_analysis::Component("MD5", + ::file_analysis::MD5::Instantiate)); + AddComponent(new ::file_analysis::Component("SHA1", + ::file_analysis::SHA1::Instantiate)); + AddComponent(new ::file_analysis::Component("SHA256", + ::file_analysis::SHA256::Instantiate)); + + extern std::list > __bif_events_init(); + AddBifInitFunction(&__bif_events_init); + } +}; + +Plugin __plugin; + +} } diff --git a/src/file_analysis/analyzer/hash/events.bif b/src/file_analysis/analyzer/hash/events.bif new file mode 100644 index 0000000000..b4a8de1c74 --- /dev/null +++ b/src/file_analysis/analyzer/hash/events.bif @@ -0,0 +1,12 @@ +## This event is generated each time file analysis generates a digest of the +## file contents. +## +## f: The file. +## +## kind: The type of digest algorithm. +## +## hash: The result of the hashing. +## +## .. bro:see:: FileAnalysis::add_analyzer FileAnalysis::ANALYZER_MD5 +## FileAnalysis::ANALYZER_SHA1 FileAnalysis::ANALYZER_SHA256 +event file_hash%(f: fa_file, kind: string, hash: string%); diff --git a/src/file_analysis.bif b/src/file_analysis/file_analysis.bif similarity index 76% rename from src/file_analysis.bif rename to src/file_analysis/file_analysis.bif index 648c031221..148e6360da 100644 --- a/src/file_analysis.bif +++ b/src/file_analysis/file_analysis.bif @@ -1,4 +1,4 @@ -##! Internal functions and types used by the logging framework. +##! Internal functions and types used by the file analysis framework. module Files; @@ -8,25 +8,6 @@ module Files; type AnalyzerArgs: record; -## An enumeration of various file analysis actions that can be taken. -enum Analyzer %{ - - ## Extract a file to local filesystem - ANALYZER_EXTRACT, - - ## Calculate an MD5 digest of the file's contents. - ANALYZER_MD5, - - ## Calculate an SHA1 digest of the file's contents. - ANALYZER_SHA1, - - ## Calculate an SHA256 digest of the file's contents. - ANALYZER_SHA256, - - ## Deliver the file contents to the script-layer in an event. - ANALYZER_DATA_EVENT, -%} - ## :bro:see:`Files::set_timeout_interval`. function Files::__set_timeout_interval%(file_id: string, t: interval%): bool %{ @@ -76,3 +57,5 @@ function set_file_handle%(handle: string%): any file_mgr->SetHandle(handle->CheckString()); return 0; %} + +const Files::salt: string; diff --git a/src/http-analyzer.pac b/src/http-analyzer.pac deleted file mode 100644 index e12be59438..0000000000 --- a/src/http-analyzer.pac +++ /dev/null @@ -1,430 +0,0 @@ -%extern{ -#include - -// Used by unescape_URI(). -extern int is_reserved_URI_char(unsigned char ch); -extern int is_unreserved_URI_char(unsigned char ch); -%} - -# Remember to call bytestring::free() on the result. -function to_upper(s: const_bytestring): bytestring - %{ - char* buf = new char[s.length() + 1]; - const char* sp = (const char*) s.begin(); - - for ( int i = 0; i < s.length(); ++i ) - if ( islower(sp[i]) ) - buf[i] = toupper(sp[i]); - else - buf[i] = sp[i]; - - buf[s.length()] = '\0'; - - return bytestring((uint8*) buf, s.length()); - %} - -connection HTTP_Conn(bro_analyzer: BroAnalyzer) { - upflow = HTTP_Flow(true); - downflow = HTTP_Flow(false); -}; - -flow HTTP_Flow(is_orig: bool) { - flowunit = HTTP_PDU(is_orig) withcontext (connection, this); - - # States. - %member{ - int content_length_; - DeliveryMode delivery_mode_; - bytestring end_of_multipart_; - - double msg_start_time_; - int msg_begin_seq_; - int msg_header_end_seq_; - - bool build_headers_; - vector headers_; - %} - - %init{ - content_length_ = 0; - delivery_mode_ = UNKNOWN_DELIVERY_MODE; - - msg_start_time_ = 0; - msg_begin_seq_ = 0; - msg_header_end_seq_ = -1; - - build_headers_ = (::http_all_headers != 0); - %} - - %cleanup{ - end_of_multipart_.free(); - %} - - function content_length(): int - %{ - return content_length_; - %} - - function delivery_mode(): DeliveryMode - %{ - return delivery_mode_; - %} - - function end_of_multipart(): const_bytestring - %{ - return end_of_multipart_; - %} - - # Methods. - function http_request(method: const_bytestring, uri: const_bytestring, - vers: HTTP_Version): bool - %{ - if ( ::http_request ) - { - bytestring unescaped_uri = unescape_uri(uri); - BifEvent::generate_http_request(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(method), - bytestring_to_val(uri), - bytestring_to_val(unescaped_uri), - bytestring_to_val(${vers.vers_str})); - unescaped_uri.free(); - } - - http_message_begin(); - - return true; - %} - - function http_reply(vers: HTTP_Version, code: int, - reason: const_bytestring): bool - %{ - if ( ::http_reply ) - { - BifEvent::generate_http_reply(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${vers.vers_str}), code, - bytestring_to_val(reason)); - } - - http_message_begin(); - - return true; - %} - - function build_http_header_val(name: const_bytestring, - value: const_bytestring): BroVal - %{ - RecordVal* header_record = new RecordVal(mime_header_rec); - - StringVal* name_val = 0; - if ( name.length() > 0 ) - { - // Make it all uppercase. - name_val = new StringVal(name.length(), - (const char*) name.begin()); - name_val->ToUpper(); - } - else - name_val = new StringVal(""); - - header_record->Assign(0, name_val); - header_record->Assign(1, bytestring_to_val(value)); - - return header_record; - %} - - function extract_boundary(value: const_bytestring): bytestring - %{ - const char* boundary_prefix = "boundary="; - const char* boundary_begin = strcasestr( - (const char*) value.begin(), - boundary_prefix); - - if ( ! boundary_begin ) - return bytestring(); - - boundary_begin += 9; - - const char* boundary_end = strcasestr(boundary_begin, ";"); - if ( ! boundary_end ) - boundary_end = (const char*) value.end(); - - return bytestring((const uint8*) boundary_begin, - (const uint8*) boundary_end); - %} - - function is_end_of_multipart(line: const_bytestring): bool - %{ - if ( line.length() < 4 + end_of_multipart_.length() ) - return false; - - int len = end_of_multipart_.length(); - - // line =?= "--" end_of_multipart_ "--" - return ( line[0] == '-' && line[1] == '-' && - line[len + 2] == '-' && line[len + 3] == '-' && - strncmp((const char*) line.begin() + 2, - (const char*) end_of_multipart_.begin(), - len) == 0 ); - %} - - function http_header(name_colon: const_bytestring, - value: const_bytestring): bool - %{ - const_bytestring name( - name_colon.begin(), - name_colon.length() > 0 ? - name_colon.end() - 1 : - name_colon.end()); - - if ( bytestring_casecmp(name, "CONTENT-LENGTH") == 0 ) - { - content_length_ = bytestring_to_int(value, 10); - delivery_mode_ = CONTENT_LENGTH; - } - - else if ( bytestring_casecmp(name, "TRANSFER-ENCODING") == 0 ) - { - if ( bytestring_caseprefix(value, "CHUNKED") ) - delivery_mode_ = CHUNKED; - } - - else if ( bytestring_casecmp(name, "CONTENT-TYPE") == 0 ) - { - if ( bytestring_caseprefix(value, "MULTIPART") ) - { - end_of_multipart_.free(); - end_of_multipart_ = extract_boundary(value); - if ( end_of_multipart_.length() > 0 ) - delivery_mode_ = MULTIPART; - } - } - - if ( ::http_header ) - { - BifEvent::generate_http_header(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - is_orig(), - bytestring_to_val(name)->ToUpper(), - bytestring_to_val(value)); - } - - if ( build_headers_ ) - headers_.push_back(build_http_header_val(name, value)); - - return true; - %} - - function build_http_headers_val(): BroVal - %{ - TableVal* t = new TableVal(mime_header_list); - - for ( unsigned int i = 0; i < headers_.size(); ++i ) - { // index starting from 1 - Val* index = new Val(i + 1, TYPE_COUNT); - t->Assign(index, headers_[i]); - Unref(index); - } - - return t; - %} - - function gen_http_all_headers(): void - %{ - if ( ::http_all_headers ) - { - BifEvent::generate_http_all_headers(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - is_orig(), - build_http_headers_val()); - } - - headers_.clear(); - %} - - function http_end_of_headers(headers: HTTP_Headers): bool - %{ - if ( delivery_mode_ != CHUNKED && build_headers_ ) - gen_http_all_headers(); - - // Check if this is the first set of headers - // (i.e. not headers after chunks). - if ( msg_header_end_seq_ == -1 ) - msg_header_end_seq_ = flow_buffer_->data_seq(); - - return true; - %} - - function http_message_begin(): void - %{ - msg_start_time_ = network_time(); - if ( ::http_begin_entity ) - { - BifEvent::generate_http_begin_entity(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), is_orig()); - } - %} - - function build_http_message_stat(): BroVal - %{ - int msg_header_length = msg_header_end_seq_ - msg_begin_seq_; - int msg_body_length = - flow_buffer_->data_seq() - msg_header_end_seq_; - - bool msg_interrupted = false; - - RecordVal* stat = new RecordVal(http_message_stat); - int field = 0; - stat->Assign(field++, new Val(msg_start_time_, TYPE_TIME)); - stat->Assign(field++, new Val(msg_interrupted, TYPE_BOOL)); - stat->Assign(field++, new StringVal("")); - stat->Assign(field++, new Val(msg_body_length, TYPE_COUNT)); - stat->Assign(field++, new Val(0, TYPE_COUNT)); - stat->Assign(field++, new Val(msg_header_length, TYPE_COUNT)); - - return stat; - %} - - function http_message_done(pdu: HTTP_PDU): bool - %{ - if ( ! headers_.empty() ) - gen_http_all_headers(); - - if ( ::http_end_entity ) - { - BifEvent::generate_http_end_entity(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), is_orig()); - } - - if ( ::http_message_done ) - { - BifEvent::generate_http_message_done(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - is_orig(), build_http_message_stat()); - } - - end_of_multipart_.free(); - - // Initialize for next message. - msg_begin_seq_ = flow_buffer_->data_seq(); - msg_header_end_seq_ = -1; - - return true; - %} - - # Remember to call bytestring::free() on the result - function unescape_uri(uri: const_bytestring): bytestring - %{ - const u_char* line = uri.begin(); - const u_char* line_end = uri.end(); - BroAnalyzer a = connection()->bro_analyzer(); - - // ### Copied from HTTP.cc - byte_vec decoded_URI = new u_char[line_end - line + 1]; - byte_vec URI_p = decoded_URI; - - // An 'unescaped_special_char' here means a character that - // *should* be escaped, but isn't in the URI. A control - // character that appears directly in the URI would be an - // example. The RFC implies that if we do not unescape the - // URI that we see in the trace, every character should be a - // printable one -- either reserved or unreserved (or '%'). - // - // Counting the number of unescaped characters and generating - // a weird event on URI's with unescaped characters (which - // are rare) will let us locate strange-looking URI's in the - // trace -- those URI's are often interesting. - - int unescaped_special_char = 0; - - while ( line < line_end ) - { - if ( *line == '%' ) - { - ++line; - - if ( line == line_end ) - { - // How to deal with % at end of line? - // *URI_p++ = '%'; - if ( a ) - a->Weird("illegal_%_at_end_of_URI"); - break; - } - - else if ( *line == '%' ) - { - // Double '%' might be either due to - // software bug, or, more likely, an - // evasion (e.g., used by Nimda). - // *URI_p++ = '%'; - if ( a ) - a->Weird("double_%_in_URI"); - --line; // ignore the first '%' - } - - else if ( isxdigit(line[0]) && isxdigit(line[1]) ) - { - *URI_p++ = (decode_hex(line[0]) << 4) + - decode_hex(line[1]); - ++line; // place line at last hex digit - } - - else - { - if ( a ) - a->Weird("unescaped_%_in_URI"); - *URI_p++ = '%'; // put back initial '%' - // Take char. without interpretation.. - *URI_p++ = *line; - } - } - - else - { - if ( ! is_reserved_URI_char(*line) && - ! is_unreserved_URI_char(*line) ) - // Count these up as a way to compress - // the corresponding Weird event to a - // single instance. - ++unescaped_special_char; - *URI_p++ = *line; - } - - ++line; - } - - URI_p[0] = 0; - - if ( unescaped_special_char && a ) - a->Weird("unescaped_special_URI_char"); - - return bytestring(decoded_URI, URI_p - decoded_URI); - %} -}; - -refine typeattr HTTP_RequestLine += &let { - process_request: bool = - $context.flow.http_request(method, uri, version); -}; - -refine typeattr HTTP_ReplyLine += &let { - process_reply: bool = - $context.flow.http_reply(version, status.stat_num, reason); -}; - -refine typeattr HTTP_Header += &let { - process_header: bool = - $context.flow.http_header(name, value); -}; - -refine typeattr HTTP_Headers += &let { - process_end_of_headers: bool = - $context.flow.http_end_of_headers(this); -}; - -refine typeattr HTTP_PDU += &let { - process_message: bool = - $context.flow.http_message_done(this); -}; diff --git a/src/http-protocol.pac b/src/http-protocol.pac deleted file mode 100644 index e4487a75e3..0000000000 --- a/src/http-protocol.pac +++ /dev/null @@ -1,140 +0,0 @@ -enum ExpectBody { - BODY_EXPECTED, - BODY_NOT_EXPECTED, - BODY_MAYBE, -}; - -enum DeliveryMode { - UNKNOWN_DELIVERY_MODE, - CONTENT_LENGTH, - CHUNKED, - MULTIPART, -}; - -## token = 1* -## separators = "(" | ")" | "<" | ">" | "@" -## | "," | ";" | ":" | "\" | <"> -## | "/" | "[" | "]" | "?" | "=" -## | "{" | "}" | SP | HT -## reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | -## "$" | "," - -type HTTP_TOKEN = RE/[^()<>@,;:\\"\/\[\]?={} \t]+/; -type HTTP_WS = RE/[ \t]*/; -type HTTP_URI = RE/[[:alnum:][:punct:]]+/; - -type HTTP_PDU(is_orig: bool) = case is_orig of { - true -> request: HTTP_Request; - false -> reply: HTTP_Reply; -}; - -type HTTP_Request = record { - request: HTTP_RequestLine; - msg: HTTP_Message(BODY_MAYBE); -}; - -function expect_reply_body(reply_status: int): ExpectBody - %{ - // TODO: check if the request is "HEAD" - if ( (reply_status >= 100 && reply_status < 200) || - reply_status == 204 || reply_status == 304 ) - return BODY_NOT_EXPECTED; - return BODY_EXPECTED; - %} - -type HTTP_Reply = record { - reply: HTTP_ReplyLine; - msg: HTTP_Message(expect_reply_body(reply.status.stat_num)); -}; - -type HTTP_RequestLine = record { - method: HTTP_TOKEN; - : HTTP_WS; - uri: HTTP_URI; - : HTTP_WS; - version: HTTP_Version; -} &oneline; - -type HTTP_ReplyLine = record { - version: HTTP_Version; - : HTTP_WS; - status: HTTP_Status; - : HTTP_WS; - reason: bytestring &restofdata; -} &oneline; - -type HTTP_Status = record { - stat_str: RE/[0-9]{3}/; -} &let { - stat_num: int = bytestring_to_int(stat_str, 10); -}; - -type HTTP_Version = record { - : "HTTP/"; - vers_str: RE/[0-9]+\.[0-9]+/; -} &let { - vers_num: double = bytestring_to_double(vers_str); -}; - -type HTTP_Headers = HTTP_Header[] &until($input.length() == 0); - -type HTTP_Message(expect_body: ExpectBody) = record { - headers: HTTP_Headers; - body_or_not: case expect_body of { - BODY_NOT_EXPECTED -> none: empty; - default -> body: HTTP_Body(expect_body); - }; -}; - -# Multi-line headers are supported by allowing header names to be -# empty. -# -type HTTP_HEADER_NAME = RE/|([^: \t]+:)/; -type HTTP_Header = record { - name: HTTP_HEADER_NAME &transient; - : HTTP_WS; - value: bytestring &restofdata &transient; -} &oneline; - -type MIME_Line = record { - line: bytestring &restofdata &transient; -} &oneline; - -type MIME_Lines = MIME_Line[] - &until($context.flow.is_end_of_multipart($input)); - -# TODO: parse multipart message according to MIME -type HTTP_Body(expect_body: ExpectBody) = - case $context.flow.delivery_mode() of { - - CONTENT_LENGTH -> body: bytestring - &length = $context.flow.content_length(), - &chunked; - - CHUNKED -> chunks: HTTP_Chunks; - - MULTIPART -> multipart: MIME_Lines; - - default -> unknown: HTTP_UnknownBody(expect_body); -}; - -type HTTP_UnknownBody(expect_body: ExpectBody) = case expect_body of { - BODY_MAYBE, BODY_NOT_EXPECTED -> maybenot: empty; - BODY_EXPECTED -> rest: bytestring &restofflow &chunked; -}; - -type HTTP_Chunks = record { - chunks: HTTP_Chunk[] &until($element.chunk_length == 0); - headers: HTTP_Headers; -}; - -type HTTP_Chunk = record { - length_line: bytestring &oneline; - data: bytestring &length = chunk_length &chunked; - opt_crlf: case chunk_length of { - 0 -> none: empty; - default -> crlf: bytestring &oneline &check(trailing_crlf == ""); - }; -} &let { - chunk_length: int = bytestring_to_int(length_line, 16); -}; diff --git a/src/http.pac b/src/http.pac deleted file mode 100644 index 38e6ad0b5e..0000000000 --- a/src/http.pac +++ /dev/null @@ -1,10 +0,0 @@ -%include binpac.pac -%include bro.pac - -analyzer HTTP withcontext { - connection: HTTP_Conn; - flow: HTTP_Flow; -}; - -%include http-protocol.pac -%include http-analyzer.pac diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 8f3d4bb8e5..d467e32005 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -15,11 +15,9 @@ #include "EventHandler.h" #include "NetVar.h" #include "Net.h" -#include "../file_analysis/Manager.h" - - #include "CompHash.h" +#include "../file_analysis/Manager.h" #include "../threading/SerialTypes.h" using namespace input; @@ -322,6 +320,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) ReaderBackend::ReaderInfo* rinfo = new ReaderBackend::ReaderInfo(); rinfo->source = copy_string(source.c_str()); + rinfo->name = copy_string(name.c_str()); EnumVal* mode = description->LookupWithDefault(rtype->FieldOffset("mode"))->AsEnumVal(); switch ( mode->InternalInt() ) @@ -702,6 +701,7 @@ bool Manager::CreateTableStream(RecordVal* fval) bool Manager::CreateAnalysisStream(RecordVal* fval) { RecordType* rtype = fval->Type()->AsRecordType(); + if ( ! same_type(rtype, BifType::Record::Input::AnalysisDescription, 0) ) { reporter->Error("AnalysisDescription argument not of right type"); @@ -709,12 +709,11 @@ bool Manager::CreateAnalysisStream(RecordVal* fval) } AnalysisStream* stream = new AnalysisStream(); + + if ( ! CreateStream(stream, fval) ) { - if ( ! CreateStream(stream, fval) ) - { - delete stream; - return false; - } + delete stream; + return false; } stream->file_id = file_mgr->HashHandle(stream->name); @@ -1243,6 +1242,9 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) if ( i->stream_type != TABLE_STREAM ) { +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "%s is event, sending end of data", i->name.c_str()); +#endif // just signal the end of the data source SendEndOfData(i); return; @@ -1347,8 +1349,13 @@ void Manager::SendEndOfData(ReaderFrontend* reader) SendEndOfData(i); } + void Manager::SendEndOfData(const Stream *i) { +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "SendEndOfData for stream %s", + i->name.c_str()); +#endif SendEvent(end_of_data, 2, new StringVal(i->name.c_str()), new StringVal(i->info->source)); if ( i->stream_type == ANALYSIS_STREAM ) @@ -1364,6 +1371,11 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals) return; } +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "Put for stream %s", + i->name.c_str()); +#endif + int readFields = 0; if ( i->stream_type == TABLE_STREAM ) @@ -1702,6 +1714,11 @@ bool Manager::SendEvent(const string& name, const int num_vals, Value* *vals) return false; } +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "SendEvent for event %s with num_vals vals", + name.c_str(), num_vals); +#endif + RecordType *type = handler->FType()->Args(); int num_event_vals = type->NumFields(); if ( num_vals != num_event_vals ) @@ -1714,7 +1731,7 @@ bool Manager::SendEvent(const string& name, const int num_vals, Value* *vals) for ( int i = 0; i < num_vals; i++) vl->append(ValueToVal(vals[i], type->FieldType(i))); - mgr.Dispatch(new Event(handler, vl)); + mgr.QueueEvent(handler, vl, SOURCE_LOCAL); for ( int i = 0; i < num_vals; i++ ) delete vals[i]; @@ -1728,6 +1745,11 @@ void Manager::SendEvent(EventHandlerPtr ev, const int numvals, ...) { val_list* vl = new val_list; +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "SendEvent with %d vals", + numvals); +#endif + va_list lP; va_start(lP, numvals); for ( int i = 0; i < numvals; i++ ) @@ -1742,6 +1764,11 @@ void Manager::SendEvent(EventHandlerPtr ev, list events) { val_list* vl = new val_list; +#ifdef DEBUG + DBG_LOG(DBG_INPUT, "SendEvent with %d vals (list)", + events.size()); +#endif + for ( list::iterator i = events.begin(); i != events.end(); i++ ) { vl->append( *i ); @@ -2246,3 +2273,18 @@ Manager::Stream* Manager::FindStream(ReaderFrontend* reader) return 0; } + +// Function is called on Bro shutdown. +// Signal all frontends that they will cease operation. +void Manager::Terminate() + { + for ( map::iterator i = readers.begin(); i != readers.end(); ++i ) + { + if ( i->second->removed ) + continue; + + i->second->removed = true; + i->second->reader->Stop(); + } + + } diff --git a/src/input/Manager.h b/src/input/Manager.h index a1fbb94313..8156ed5248 100644 --- a/src/input/Manager.h +++ b/src/input/Manager.h @@ -91,6 +91,11 @@ public: */ bool RemoveStream(const string &id); + /** + * Signals the manager to shutdown at Bro's termination. + */ + void Terminate(); + protected: friend class ReaderFrontend; friend class PutMessage; diff --git a/src/input/ReaderBackend.h b/src/input/ReaderBackend.h index 73e5475db6..5419879e13 100644 --- a/src/input/ReaderBackend.h +++ b/src/input/ReaderBackend.h @@ -85,6 +85,11 @@ public: */ const char* source; + /** + * The name of the input stream. + */ + const char* name; + /** * A map of key/value pairs corresponding to the relevant * filter's "config" table. @@ -99,12 +104,14 @@ public: ReaderInfo() { source = 0; + name = 0; mode = MODE_NONE; } ReaderInfo(const ReaderInfo& other) { source = other.source ? copy_string(other.source) : 0; + name = other.name ? copy_string(other.name) : 0; mode = other.mode; for ( config_map::const_iterator i = other.config.begin(); i != other.config.end(); i++ ) diff --git a/src/input/fdstream.h b/src/input/fdstream.h deleted file mode 100644 index cda767dd52..0000000000 --- a/src/input/fdstream.h +++ /dev/null @@ -1,189 +0,0 @@ -/* The following code declares classes to read from and write to - * file descriptore or file handles. - * - * See - * http://www.josuttis.com/cppcode - * for details and the latest version. - * - * - open: - * - integrating BUFSIZ on some systems? - * - optimized reading of multiple characters - * - stream for reading AND writing - * - i18n - * - * (C) Copyright Nicolai M. Josuttis 2001. - * Permission to copy, use, modify, sell and distribute this software - * is granted provided this copyright notice appears in all copies. - * This software is provided "as is" without express or implied - * warranty, and with no claim as to its suitability for any purpose. - * - * Version: Jul 28, 2002 - * History: - * Jul 28, 2002: bugfix memcpy() => memmove() - * fdinbuf::underflow(): cast for return statements - * Aug 05, 2001: first public version - */ -#ifndef BOOST_FDSTREAM_HPP -#define BOOST_FDSTREAM_HPP - -#include -#include -#include -// for EOF: -#include -// for memmove(): -#include - - - -// low-level read and write functions -#ifdef _MSC_VER -# include -#else -# include -# include -//extern "C" { -// int write (int fd, const char* buf, int num); -// int read (int fd, char* buf, int num); -//} -#endif - - -// BEGIN namespace BOOST -namespace boost { - - -/************************************************************ - * fdostream - * - a stream that writes on a file descriptor - ************************************************************/ - - -class fdoutbuf : public std::streambuf { - protected: - int fd; // file descriptor - public: - // constructor - fdoutbuf (int _fd) : fd(_fd) { - } - protected: - // write one character - virtual int_type overflow (int_type c) { - if (c != EOF) { - char z = c; - if (write (fd, &z, 1) != 1) { - return EOF; - } - } - return c; - } - // write multiple characters - virtual - std::streamsize xsputn (const char* s, - std::streamsize num) { - return write(fd,s,num); - } -}; - -class fdostream : public std::ostream { - protected: - fdoutbuf buf; - public: - fdostream (int fd) : std::ostream(0), buf(fd) { - rdbuf(&buf); - } -}; - - -/************************************************************ - * fdistream - * - a stream that reads on a file descriptor - ************************************************************/ - -class fdinbuf : public std::streambuf { - protected: - int fd; // file descriptor - protected: - /* data buffer: - * - at most, pbSize characters in putback area plus - * - at most, bufSize characters in ordinary read buffer - */ - static const int pbSize = 4; // size of putback area - static const int bufSize = 1024; // size of the data buffer - char buffer[bufSize+pbSize]; // data buffer - - public: - /* constructor - * - initialize file descriptor - * - initialize empty data buffer - * - no putback area - * => force underflow() - */ - fdinbuf (int _fd) : fd(_fd) { - setg (buffer+pbSize, // beginning of putback area - buffer+pbSize, // read position - buffer+pbSize); // end position - } - - protected: - // insert new characters into the buffer - virtual int_type underflow () { -#ifndef _MSC_VER - using std::memmove; -#endif - - // is read position before end of buffer? - if (gptr() < egptr()) { - return traits_type::to_int_type(*gptr()); - } - - /* process size of putback area - * - use number of characters read - * - but at most size of putback area - */ - int numPutback; - numPutback = gptr() - eback(); - if (numPutback > pbSize) { - numPutback = pbSize; - } - - /* copy up to pbSize characters previously read into - * the putback area - */ - memmove (buffer+(pbSize-numPutback), gptr()-numPutback, - numPutback); - - // read at most bufSize new characters - int num; - num = read (fd, buffer+pbSize, bufSize); - if ( num == EAGAIN ) { - return 0; - } - if (num <= 0) { - // ERROR or EOF - return EOF; - } - - // reset buffer pointers - setg (buffer+(pbSize-numPutback), // beginning of putback area - buffer+pbSize, // read position - buffer+pbSize+num); // end of buffer - - // return next character - return traits_type::to_int_type(*gptr()); - } -}; - -class fdistream : public std::istream { - protected: - fdinbuf buf; - public: - fdistream (int fd) : std::istream(0), buf(fd) { - rdbuf(&buf); - } -}; - - -} // END namespace boost - -#endif /*BOOST_FDSTREAM_HPP*/ diff --git a/src/input/readers/Raw.cc b/src/input/readers/Raw.cc index ac96e5c0f5..46cb3656a3 100644 --- a/src/input/readers/Raw.cc +++ b/src/input/readers/Raw.cc @@ -3,32 +3,46 @@ #include "Raw.h" #include "NetVar.h" -#include -#include - #include "../../threading/SerialTypes.h" -#include "../fdstream.h" #include +#include #include #include #include #include +#include +#include using namespace input::reader; using threading::Value; using threading::Field; +const int Raw::block_size = 4096; // how big do we expect our chunks of data to be. + + Raw::Raw(ReaderFrontend *frontend) : ReaderBackend(frontend) { file = 0; - in = 0; - + stderrfile = 0; + forcekill = false; separator.assign( (const char*) BifConst::InputRaw::record_separator->Bytes(), BifConst::InputRaw::record_separator->Len()); - if ( separator.size() != 1 ) - Error("separator length has to be 1. Separator will be truncated."); + sep_length = BifConst::InputRaw::record_separator->Len(); + + buf = 0; + outbuf = 0; + bufpos = 0; + + stdin_fileno = fileno(stdin); + stdout_fileno = fileno(stdout); + stderr_fileno = fileno(stderr); + + childpid = -1; + + stdin_towrite = 0; // by default do not open stdin + use_stderr = false; } Raw::~Raw() @@ -40,41 +54,123 @@ void Raw::DoClose() { if ( file != 0 ) CloseInput(); + + if ( execute && childpid > 0 && kill(childpid, 0) == 0 ) + { + // kill child process + kill(childpid, 15); // sigterm + + if ( forcekill ) + { + usleep(200); // 200 msecs should be enough for anyone ;) + + if ( kill(childpid, 0) == 0 ) // perhaps it is already gone + kill(childpid, 9); // TERMINATE + } + } + } + +bool Raw::Execute() + { + if ( pipe(pipes) != 0 || pipe(pipes+2) || pipe(pipes+4) ) + { + Error(Fmt("Could not open pipe: %d", errno)); + return false; + } + + childpid = fork(); + if ( childpid < 0 ) + { + Error(Fmt("Could not create child process: %d", errno)); + return false; + } + + else if ( childpid == 0 ) + { + // we are the child. + close(pipes[stdout_in]); + dup2(pipes[stdout_out], stdout_fileno); + + if ( stdin_towrite ) + { + close(pipes[stdin_out]); + dup2(pipes[stdin_in], stdin_fileno); + } + + if ( use_stderr ) + { + close(pipes[stderr_in]); + dup2(pipes[stderr_out], stderr_fileno); + } + + execl("/bin/sh", "sh", "-c", fname.c_str(), NULL); + fprintf(stderr, "Exec failed :(......\n"); + exit(255); + } + else + { + // we are the parent + close(pipes[stdout_out]); + pipes[stdout_out] = -1; + + if ( Info().mode == MODE_STREAM ) + fcntl(pipes[stdout_in], F_SETFL, O_NONBLOCK); + + if ( stdin_towrite ) + { + close(pipes[stdin_in]); + pipes[stdin_in] = -1; + fcntl(pipes[stdin_out], F_SETFL, O_NONBLOCK); // ya, just always set this to nonblocking. we do not want to block on a program receiving data. + // note that there is a small gotcha with it. More data is queued when more data is read from the program output. Hence, when having + // a program in mode_manual where the first write cannot write everything, the rest will be stuck in a queue that is never emptied. + } + + if ( use_stderr ) + { + close(pipes[stderr_out]); + pipes[stderr_out] = -1; + fcntl(pipes[stderr_in], F_SETFL, O_NONBLOCK); // true for this too. + } + + file = fdopen(pipes[stdout_in], "r"); + pipes[stdout_in] = -1; // will be closed by fclose + + if ( use_stderr ) + stderrfile = fdopen(pipes[stderr_in], "r"); + pipes[stderr_in] = -1; // will be closed by fclose + if ( file == 0 || (stderrfile == 0 && use_stderr) ) + { + Error("Could not convert fileno to file"); + return false; + } + + + return true; + } } bool Raw::OpenInput() { if ( execute ) - { - file = popen(fname.c_str(), "r"); - if ( file == NULL ) - { - Error(Fmt("Could not execute command %s", fname.c_str())); - return false; - } - } + return Execute(); + else { file = fopen(fname.c_str(), "r"); - if ( file == NULL ) + fcntl(fileno(file), F_SETFD, FD_CLOEXEC); + if ( ! file ) { Error(Fmt("Init: cannot open %s", fname.c_str())); return false; } } - // This is defined in input/fdstream.h - in = new boost::fdistream(fileno(file)); - - if ( execute && Info().mode == MODE_STREAM ) - fcntl(fileno(file), F_SETFL, O_NONBLOCK); - return true; } bool Raw::CloseInput() { - if ( file == NULL ) + if ( file == 0 ) { InternalError(Fmt("Trying to close closed file for stream %s", fname.c_str())); return false; @@ -83,15 +179,20 @@ bool Raw::CloseInput() Debug(DBG_INPUT, "Raw reader starting close"); #endif - delete in; + fclose(file); - if ( execute ) - pclose(file); - else - fclose(file); + if ( use_stderr ) + fclose(stderrfile); - in = NULL; - file = NULL; + if ( execute ) // we do not care if any of those fails. They should all be defined. + { + for ( int i = 0; i < 6; i ++ ) + if ( pipes[i] != -1 ) + close(pipes[i]); + } + + file = 0; + stderrfile = 0; #ifdef DEBUG Debug(DBG_INPUT, "Raw reader finished close"); @@ -106,28 +207,9 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie mtime = 0; execute = false; firstrun = true; + int want_fields = 1; bool result; - if ( ! info.source || strlen(info.source) == 0 ) - { - Error("No source path provided"); - return false; - } - - if ( num_fields != 1 ) - { - Error("Filter for raw reader contains more than one field. " - "Filters for the raw reader may only contain exactly one string field. " - "Filter ignored."); - return false; - } - - if ( fields[0]->type != TYPE_STRING ) - { - Error("Filter for raw reader contains a field that is not of type string."); - return false; - } - // do Initialization string source = string(info.source); char last = info.source[source.length() - 1]; @@ -135,23 +217,63 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie { execute = true; fname = source.substr(0, fname.length() - 1); - - if ( (info.mode != MODE_MANUAL) ) - { - Error(Fmt("Unsupported read mode %d for source %s in execution mode", - info.mode, fname.c_str())); - return false; - } - - result = OpenInput(); - } - else + + if ( ! info.source || strlen(info.source) == 0 ) { - execute = false; - result = OpenInput(); + Error("No source path provided"); + return false; } + map::const_iterator it = info.config.find("stdin"); // data that is sent to the child process + if ( it != info.config.end() ) + { + stdin_string = it->second; + stdin_towrite = stdin_string.length(); + } + + it = info.config.find("read_stderr"); // we want to read stderr + if ( it != info.config.end() && execute ) + { + use_stderr = true; + want_fields = 2; + } + + it = info.config.find("force_kill"); // we want to be sure that our child is dead when we exit + if ( it != info.config.end() && execute ) + { + forcekill = true; + } + + if ( num_fields != want_fields ) + { + Error(Fmt("Filter for raw reader contains wrong number of fields -- got %d, expected %d. " + "Filters for the raw reader contain one string field when used in normal mode and one string and one bool fields when using execute mode with stderr capuring. " + "Filter ignored.", num_fields, want_fields)); + return false; + } + + if ( fields[0]->type != TYPE_STRING ) + { + Error("First field for raw reader always has to be of type string."); + return false; + } + if ( use_stderr && fields[1]->type != TYPE_BOOL ) + { + Error("Second field for raw reader always has to be of type bool."); + return false; + } + + if ( execute && Info().mode == MODE_REREAD ) + { + // for execs this makes no sense - would have to execute each heartbeat? + Error("Rereading only supported for files, not for executables."); + return false; + } + + + result = OpenInput(); + if ( result == false ) return result; @@ -168,18 +290,115 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie return true; } - -bool Raw::GetLine(string& str) +int64_t Raw::GetLine(FILE* arg_file) { - if ( in->peek() == std::iostream::traits_type::eof() ) - return false; + errno = 0; + int pos = 0; // strstr_n only works on ints - so no use to use something different here + int offset = 0; - if ( in->eofbit == true || in->failbit == true ) - return false; + if ( buf == 0 ) + buf = new char[block_size]; - return getline(*in, str, separator[0]); + int repeats = 1; + + for (;;) + { + size_t readbytes = fread(buf+bufpos+offset, 1, block_size-bufpos, arg_file); + pos += bufpos + readbytes; + //printf("Pos: %d\n", pos); + bufpos = offset = 0; // read full block size in next read... + + if ( pos == 0 && errno != 0 ) + break; + + // researching everything each time is a bit... cpu-intensive. But otherwhise we have + // to deal with situations where the separator is multi-character and split over multiple + // reads... + int found = strstr_n(pos, (unsigned char*) buf, separator.size(), (unsigned char*) separator.c_str()); + + if ( found == -1 ) + { + // we did not find it and have to search again in the next try. resize buffer.... + // but first check if we encountered the file end - because if we did this was it. + if ( feof(arg_file) != 0 ) + { + outbuf = buf; + buf = 0; + if ( pos == 0 ) + return -1; // signal EOF - and that we had no more data. + else + return pos; + } + + repeats++; + // bah, we cannot use realloc because we would have to change the delete in the manager to a free. + char * newbuf = new char[block_size*repeats]; + memcpy(newbuf, buf, block_size*(repeats-1)); + delete buf; + buf = newbuf; + offset = block_size*(repeats-1); + } + else + { + outbuf = buf; + buf = 0; + buf = new char[block_size]; + + + if ( found < pos ) + { + // we have leftovers. copy them into the buffer for the next line + buf = new char[block_size]; + memcpy(buf, outbuf + found + sep_length, pos - found - sep_length); + bufpos = pos - found - sep_length; + } + + return found; + } + + } + + if ( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) + return -2; + + else + { + // an error code we did no expect. This probably is bad. + Error(Fmt("Reader encountered unexpected error code %d", errno)); + return -3; + } + + InternalError("Internal control flow execution"); + assert(false); } +// write to the stdin of the child process +void Raw::WriteToStdin() + { + assert(stdin_towrite <= stdin_string.length()); + uint64_t pos = stdin_string.length() - stdin_towrite; + + errno = 0; + ssize_t written = write(pipes[stdin_out], stdin_string.c_str() + pos, stdin_towrite); + stdin_towrite -= written; + + if ( errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK ) + { + Error(Fmt("Writing to child process stdin failed: %d. Stopping writing at position %d", errno, pos)); + stdin_towrite = 0; + close(pipes[stdin_out]); + } + + if ( stdin_towrite == 0 ) // send EOF when we are done. + close(pipes[stdin_out]); + + if ( Info().mode == MODE_MANUAL && stdin_towrite != 0 ) + { + Error(Fmt("Could not write whole string to stdin of child process in one go. Please use STREAM mode to pass more data to child.")); + } + } + + // read the entire file and send appropriate thingies back to InputMgr bool Raw::DoUpdate() { @@ -191,6 +410,7 @@ bool Raw::DoUpdate() switch ( Info().mode ) { case MODE_REREAD: { + assert(childpid == -1); // mode may not be used to execute child programs // check if the file has changed struct stat sb; if ( stat(fname.c_str(), &sb) == -1 ) @@ -211,10 +431,9 @@ bool Raw::DoUpdate() case MODE_MANUAL: case MODE_STREAM: - if ( Info().mode == MODE_STREAM && file != NULL && in != NULL ) + if ( Info().mode == MODE_STREAM && file != 0 ) { - //fpurge(file); - in->clear(); // remove end of file evil bits + clearerr(file); // remove end of file evil bits break; } @@ -230,21 +449,118 @@ bool Raw::DoUpdate() } string line; - while ( GetLine(line) ) + assert ( (NumFields() == 1 && !use_stderr) || (NumFields() == 2 && use_stderr)); + for ( ;; ) { - assert (NumFields() == 1); + if ( stdin_towrite > 0 ) + WriteToStdin(); - Value** fields = new Value*[1]; + int64_t length = GetLine(file); + //printf("Read %lld bytes\n", length); + + if ( length == -3 ) + return false; + + else if ( length == -2 || length == -1 ) + // no data ready or eof + break; + + Value** fields = new Value*[2]; // just always reserve 2. This means that our [] is too long by a count of 1 if not using stderr. But who cares... // filter has exactly one text field. convert to it. Value* val = new Value(TYPE_STRING, true); - val->val.string_val.data = copy_string(line.c_str()); - val->val.string_val.length = line.size(); + val->val.string_val.data = outbuf; + val->val.string_val.length = length; fields[0] = val; + if ( use_stderr ) + { + Value* bval = new Value(TYPE_BOOL, true); + bval->val.int_val = 0; + fields[1] = bval; + } + Put(fields); + + outbuf = 0; } + if ( use_stderr ) + { + for ( ;; ) + { + int64_t length = GetLine(stderrfile); + //printf("Read stderr %lld bytes\n", length); + if ( length == -3 ) + return false; + + else if ( length == -2 || length == -1 ) + break; + + Value** fields = new Value*[2]; + Value* val = new Value(TYPE_STRING, true); + val->val.string_val.data = outbuf; + val->val.string_val.length = length; + fields[0] = val; + Value* bval = new Value(TYPE_BOOL, true); + bval->val.int_val = 1; // yes, we are stderr + fields[1] = bval; + + Put(fields); + + outbuf = 0; + } + } + + if ( ( Info().mode == MODE_MANUAL ) || ( Info().mode == MODE_REREAD ) ) + // done with the current data source + EndCurrentSend(); + + // and let's check if the child process is still alive + int return_code; + if ( childpid != -1 && waitpid(childpid, &return_code, WNOHANG) != 0 ) + { + // child died + bool signal = false; + int code = 0; + if ( WIFEXITED(return_code) ) + { + code = WEXITSTATUS(return_code); + if ( code != 0 ) + Error(Fmt("Child process exited with non-zero return code %d", code)); + } + + else if ( WIFSIGNALED(return_code) ) + { + signal = false; + code = WTERMSIG(return_code); + Error(Fmt("Child process exited due to signal %d", code)); + } + + else + assert(false); + + Value** vals = new Value*[4]; + vals[0] = new Value(TYPE_STRING, true); + vals[0]->val.string_val.data = copy_string(Info().name); + vals[0]->val.string_val.length = strlen(Info().name); + vals[1] = new Value(TYPE_STRING, true); + vals[1]->val.string_val.data = copy_string(Info().source); + vals[1]->val.string_val.length = strlen(Info().source); + vals[2] = new Value(TYPE_COUNT, true); + vals[2]->val.int_val = code; + vals[3] = new Value(TYPE_BOOL, true); + vals[3]->val.int_val = signal; + + // and in this case we can signal end_of_data even for the streaming reader + if ( Info().mode == MODE_STREAM ) + EndCurrentSend(); + + SendEvent("InputRaw::process_finished", 4, vals); + } + + + #ifdef DEBUG Debug(DBG_INPUT, "DoUpdate finished successfully"); #endif diff --git a/src/input/readers/Raw.h b/src/input/readers/Raw.h index 48912b70a7..6dbae21002 100644 --- a/src/input/readers/Raw.h +++ b/src/input/readers/Raw.h @@ -3,7 +3,6 @@ #ifndef INPUT_READERS_RAW_H #define INPUT_READERS_RAW_H -#include #include #include "../ReaderBackend.h" @@ -30,17 +29,49 @@ protected: private: bool OpenInput(); bool CloseInput(); - bool GetLine(string& str); + int64_t GetLine(FILE* file); + bool Execute(); + void WriteToStdin(); string fname; // Source with a potential "|" removed. - istream* in; FILE* file; + FILE* stderrfile; bool execute; bool firstrun; time_t mtime; // options set from the script-level. string separator; + unsigned int sep_length; // length of the separator + + static const int block_size; + int bufpos; + char* buf; + char* outbuf; + + int stdin_fileno; + int stdout_fileno; + int stderr_fileno; + + string stdin_string; + uint64_t stdin_towrite; + + bool use_stderr; + + bool forcekill; + + int pipes[6]; + pid_t childpid; + + enum IoChannels { + stdout_in = 0, + stdout_out = 1, + stdin_in = 2, + stdin_out = 3, + stderr_in = 4, + stderr_out = 5 + }; + }; } diff --git a/src/main.cc b/src/main.cc index b330f36509..acd7296b27 100644 --- a/src/main.cc +++ b/src/main.cc @@ -50,7 +50,6 @@ extern "C" void OPENSSL_add_all_algorithms_conf(void); #include "PersistenceSerializer.h" #include "EventRegistry.h" #include "Stats.h" -#include "DPM.h" #include "BroDoc.h" #include "Brofiler.h" @@ -58,6 +57,9 @@ extern "C" void OPENSSL_add_all_algorithms_conf(void); #include "input/Manager.h" #include "logging/Manager.h" #include "logging/writers/Ascii.h" +#include "analyzer/Manager.h" +#include "analyzer/Tag.h" +#include "plugin/Manager.h" #include "file_analysis/Manager.h" @@ -94,6 +96,8 @@ TimerMgr* timer_mgr; logging::Manager* log_mgr = 0; threading::Manager* thread_mgr = 0; input::Manager* input_mgr = 0; +plugin::Manager* plugin_mgr = 0; +analyzer::Manager* analyzer_mgr = 0; file_analysis::Manager* file_mgr = 0; Stmt* stmts; EventHandlerPtr net_done = 0; @@ -108,7 +112,6 @@ ProfileLogger* profiling_logger = 0; ProfileLogger* segment_logger = 0; SampleLogger* sample_logger = 0; int signal_val = 0; -DPM* dpm = 0; int optimize = 0; int do_notice_analysis = 0; int rule_bench = 0; @@ -120,8 +123,6 @@ vector params; char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value -int FLAGS_use_binpac = false; - extern std::list docs_generated; // Keep copy of command line @@ -185,6 +186,7 @@ void usage() fprintf(stderr, " -I|--print-id | print out given ID\n"); fprintf(stderr, " -K|--md5-hashkey | set key for MD5-keyed hashing\n"); fprintf(stderr, " -L|--rule-benchmark | benchmark for rules\n"); + fprintf(stderr, " -N|--print-plugins | print available plugins and exit (-NN for verbose)\n"); fprintf(stderr, " -O|--optimize | optimize policy script\n"); fprintf(stderr, " -P|--prime-dns | prime DNS\n"); fprintf(stderr, " -R|--replay | replay events\n"); @@ -209,8 +211,6 @@ void usage() fprintf(stderr, " -n|--idmef-dtd | specify path to IDMEF DTD file\n"); #endif - fprintf(stderr, " --use-binpac | use new-style BinPAC parsers when available\n"); - fprintf(stderr, " $BROPATH | file search path (%s)\n", bro_path()); fprintf(stderr, " $BROMAGIC | libmagic mime magic database search path (%s)\n", bro_magic_path()); fprintf(stderr, " $BRO_PREFIXES | prefix list (%s)\n", bro_prefixes()); @@ -243,6 +243,32 @@ void usage() exit(1); } +void show_plugins(int level) + { + plugin::Manager::plugin_list plugins = plugin_mgr->Plugins(); + + if ( ! plugins.size() ) + { + printf("No plugins registered, not even any built-ins. This is probably a bug.\n"); + return; + } + + ODesc d; + + if ( level == 1 ) + d.SetShort(); + + for ( plugin::Manager::plugin_list::const_iterator i = plugins.begin(); i != plugins.end(); i++ ) + { + (*i)->Describe(&d); + + if ( ! d.IsShort() ) + d.Add("\n"); + } + + printf("%s", d.Description()); + } + void done_with_network() { set_processing_status("TERMINATING", "done_with_network"); @@ -272,7 +298,7 @@ void done_with_network() terminating = true; - dpm->Done(); + analyzer_mgr->Done(); timer_mgr->Expire(); dns_mgr->Flush(); mgr.Drain(); @@ -331,10 +357,13 @@ void terminate_bro() file_mgr->Terminate(); log_mgr->Terminate(); + input_mgr->Terminate(); thread_mgr->Terminate(); mgr.Drain(); + plugin_mgr->FinishPlugins(); + delete timer_mgr; delete dns_mgr; delete persistence_serializer; @@ -344,8 +373,9 @@ void terminate_bro() delete event_registry; delete secondary_path; delete remote_serializer; - delete dpm; + delete analyzer_mgr; delete log_mgr; + delete plugin_mgr; delete thread_mgr; delete file_mgr; delete reporter; @@ -424,6 +454,7 @@ int main(int argc, char** argv) int override_ignore_checksums = 0; int rule_debug = 0; int RE_level = 4; + int print_plugins = 0; static struct option long_opts[] = { {"bare-mode", no_argument, 0, 'b'}, @@ -452,6 +483,7 @@ int main(int argc, char** argv) {"set-seed", required_argument, 0, 'J'}, {"md5-hashkey", required_argument, 0, 'K'}, {"rule-benchmark", no_argument, 0, 'L'}, + {"print-plugins", no_argument, 0, 'N'}, {"optimize", no_argument, 0, 'O'}, {"prime-dns", no_argument, 0, 'P'}, {"replay", required_argument, 0, 'R'}, @@ -474,8 +506,6 @@ int main(int argc, char** argv) {"pseudo-realtime", optional_argument, 0, 'E'}, - {"use-binpac", no_argument, &FLAGS_use_binpac, 1}, - {0, 0, 0, 0}, }; @@ -506,7 +536,7 @@ int main(int argc, char** argv) opterr = 0; char opts[256]; - safe_strncpy(opts, "B:D:e:f:I:i:K:l:n:p:R:r:s:T:t:U:w:x:X:y:Y:z:CFGLOPSWbdghvZ", + safe_strncpy(opts, "B:D:e:f:I:i:K:l:n:p:R:r:s:T:t:U:w:x:X:y:Y:z:CFGLNOPSWbdghvZ", sizeof(opts)); #ifdef USE_PERFTOOLS_DEBUG @@ -621,6 +651,10 @@ int main(int argc, char** argv) ++rule_bench; break; + case 'N': + ++print_plugins; + break; + case 'O': optimize = 1; break; @@ -767,7 +801,7 @@ int main(int argc, char** argv) if ( optind == argc && read_files.length() == 0 && flow_files.length() == 0 && interfaces.length() == 0 && - ! (id_name || bst_file) && ! command_line_policy ) + ! (id_name || bst_file) && ! command_line_policy && ! print_plugins ) add_input_file("-"); // Process remaining arguments. X=Y arguments indicate script @@ -781,6 +815,8 @@ int main(int argc, char** argv) add_input_file(argv[optind++]); } + push_scope(0); + dns_mgr = new DNS_Mgr(dns_type); // It would nice if this were configurable. This is similar to the @@ -791,20 +827,21 @@ int main(int argc, char** argv) persistence_serializer = new PersistenceSerializer(); remote_serializer = new RemoteSerializer(); event_registry = new EventRegistry(); + analyzer_mgr = new analyzer::Manager(); log_mgr = new logging::Manager(); input_mgr = new input::Manager(); + plugin_mgr = new plugin::Manager(); file_mgr = new file_analysis::Manager(); + plugin_mgr->InitPreScript(); + analyzer_mgr->InitPreScript(); + file_mgr->InitPreScript(); + if ( events_file ) event_player = new EventPlayer(events_file); init_event_handlers(); - push_scope(0); - - dpm = new DPM; - dpm->PreScriptInit(); - // The leak-checker tends to produce some false // positives (memory which had already been // allocated before we start the checking is @@ -818,12 +855,24 @@ int main(int argc, char** argv) yyparse(); + plugin_mgr->InitPostScript(); + analyzer_mgr->InitPostScript(); + file_mgr->InitPostScript(); + + if ( print_plugins ) + { + show_plugins(print_plugins); + exit(1); + } + #ifdef USE_PERFTOOLS_DEBUG } #endif if ( generate_documentation ) { + CreateProtoAnalyzerDoc("proto-analyzers.rst"); + std::list::iterator it; for ( it = docs_generated.begin(); it != docs_generated.end(); ++it ) @@ -1063,12 +1112,12 @@ int main(int argc, char** argv) mgr.QueueEvent(bro_script_loaded, vl); } - dpm->PostScriptInit(); - reporter->ReportViaEvents(true); mgr.Drain(); + analyzer_mgr->DumpDebug(); + have_pending_timers = ! reading_traces && timer_mgr->Size() > 0; io_sources.Register(thread_mgr, true); diff --git a/src/parse.y b/src/parse.y index 2a79ebe231..98df0de2a3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2,7 +2,7 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 88 +%expect 85 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -23,7 +23,7 @@ %token TOK_ATTR_EXPIRE_CREATE TOK_ATTR_EXPIRE_READ TOK_ATTR_EXPIRE_WRITE %token TOK_ATTR_PERSISTENT TOK_ATTR_SYNCHRONIZED %token TOK_ATTR_RAW_OUTPUT TOK_ATTR_MERGEABLE -%token TOK_ATTR_PRIORITY TOK_ATTR_GROUP TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER +%token TOK_ATTR_PRIORITY TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER %token TOK_ATTR_TYPE_COLUMN %token TOK_DEBUG @@ -79,7 +79,7 @@ #include "Expr.h" #include "Stmt.h" #include "Var.h" -#include "DNS.h" +/* #include "analyzer/protocol/dns/DNS.h" */ #include "RE.h" #include "Scope.h" #include "Reporter.h" @@ -1123,8 +1123,7 @@ decl: add_global($2, $3, $4, $5, $6, VAR_REDEF); if ( generate_documentation && - ! streq("capture_filters", $2->Name()) && - ! streq("dpd_config", $2->Name()) ) + ! streq("capture_filters", $2->Name()) ) { ID* fake_id = create_dummy_id($2, $2->Type()); BroDocObj* o = new BroDocObj(fake_id, reST_doc_comments, true); @@ -1404,8 +1403,6 @@ attr: { $$ = new Attr(ATTR_MERGEABLE); } | TOK_ATTR_PRIORITY '=' expr { $$ = new Attr(ATTR_PRIORITY, $3); } - | TOK_ATTR_GROUP '=' expr - { $$ = new Attr(ATTR_GROUP, $3); } | TOK_ATTR_TYPE_COLUMN '=' expr { $$ = new Attr(ATTR_TYPE_COLUMN, $3); } | TOK_ATTR_LOG diff --git a/src/plugin/Component.cc b/src/plugin/Component.cc new file mode 100644 index 0000000000..074f00c264 --- /dev/null +++ b/src/plugin/Component.cc @@ -0,0 +1,52 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Component.h" + +#include "../Desc.h" +#include "../Reporter.h" + +using namespace plugin; + +Component::Component(component::Type arg_type) + { + type = arg_type; + } + +Component::~Component() + { + } + +component::Type Component::Type() const + { + return type; + } + +void Component::Describe(ODesc* d) const + { + d->Add(" "); + d->Add("["); + + switch ( type ) { + case component::READER: + d->Add("Reader"); + break; + + case component::WRITER: + d->Add("Writer"); + break; + + case component::ANALYZER: + d->Add("Analyzer"); + break; + + case component::FILE_ANALYZER: + d->Add("File Analyzer"); + break; + + default: + reporter->InternalError("unknown component type in plugin::Component::Describe"); + } + + d->Add("]"); + d->Add(" "); + } diff --git a/src/plugin/Component.h b/src/plugin/Component.h new file mode 100644 index 0000000000..4ac448e466 --- /dev/null +++ b/src/plugin/Component.h @@ -0,0 +1,63 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef PLUGIN_COMPONENT_H +#define PLUGIN_COMPONENT_H + +class ODesc; + +namespace plugin { + +namespace component { + +/** + * Component types. + */ +enum Type { + READER, /// An input reader (not currently used). + WRITER, /// An logging writer (not currenly used). + ANALYZER, /// A protocol analyzer. + FILE_ANALYZER /// A file analyzer. + }; +} + +/** + * Base class for plugin components. A component is a specific piece of + * functionality that a plugin provides, such as a protocol analyzer or a log + * writer. + */ +class Component +{ +public: + /** + * Constructor. + * + * @param type The type of the compoment. + */ + Component(component::Type type); + + /** + * Destructor. + */ + virtual ~Component(); + + /** + * Returns the compoment's type. + */ + component::Type Type() const; + + /** + * Returns a textual representation of the component. The default + * version just output the type. Derived version should call the + * parent's implementation and that add further information. + * + * @param d The description object to use. + */ + virtual void Describe(ODesc* d) const; + +private: + component::Type type; +}; + +} + +#endif diff --git a/src/plugin/Macros.h b/src/plugin/Macros.h new file mode 100644 index 0000000000..f5c1a41cfa --- /dev/null +++ b/src/plugin/Macros.h @@ -0,0 +1,119 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +/** + * A set of macros wrapping internal logic for defining plugins and + * components. + */ + +#ifndef PLUGIN_MACROS_H +#define PLUGIN_MACROS_H + +#include "analyzer/Component.h" + +/** + * The current plugin API version. Plugins that won't match this version will + * be rejected. + */ +#define BRO_PLUGIN_API_VERSION 1 + +/** + * Starts the definition of a new plugin. + * + * @param _ns: A namespace for the plugin. All plugins compiled in statically + * must use the reserved "Bro" namespace. External plugins should define + * their own namespace to avoid collisions. + * + * @param _name: The plugin's name. The combiniation of namespace and name + * must be unique across all loaded plugins. + */ +#define BRO_PLUGIN_BEGIN(_ns, _name) \ + namespace plugin { namespace _ns ## _ ## _name {\ + class Plugin : public plugin::Plugin { \ + protected: \ + void InitPreScript() \ + { \ + SetName(#_ns "::" #_name); \ + SetVersion(-1);\ + SetAPIVersion(BRO_PLUGIN_API_VERSION);\ + SetDynamicPlugin(false); +// TODO: The SetDynamicPlugin() call is currently hardcoded to false. Change +// once we have dynamic plugins as well. + + +/** + * Ends the definition of a plugin. + */ +#define BRO_PLUGIN_END \ + } \ + }; \ + \ + Plugin __plugin; \ + } } + +/** + * Provides a textual description for a plugin. + * + * @param d A string with the description. + */ +#define BRO_PLUGIN_DESCRIPTION(d) SetDescription(d) + +/** + * Defines a version of the plugin. The version is mostly informational for + * the user; if a plugin's functionality changes, the version should be + * increased. + * + * @param v An integer version. + */ +#define BRO_PLUGIN_VERSION(v) SetVersion(v) + +/** + * Adds script-level items defined in a \c *.bif file to what the plugin + * provides. + * + * @param file A string with the name of \c *.bif file. When loaded, the + * plugin will make all items defined in the file available to Bro's script + * interpreter. + */ +#define BRO_PLUGIN_BIF_FILE(file) \ + extern std::list > __bif_##file##_init(); \ + AddBifInitFunction(&__bif_##file##_init); + +/** + * Defines a component implementing a protocol analyzer. + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + * + * @param cls The class that implements the analyzer. It must be derived + * (directly or indirectly) from analyzer::Analyzer. + */ +#define BRO_PLUGIN_ANALYZER(tag, cls) \ + AddComponent(new ::analyzer::Component(tag, ::analyzer::cls::InstantiateAnalyzer)); + +/** + * Defines a component implementing a protocol analyzer class that will + * not be instantiated dynamically. This is for two use-cases: (1) abstract + * analyzer base classes that aren't instantiated directly; and (2) analyzers + * that are only instantiated explicitly by other Bro components, but not + * dynamically by the manager based on their tag (e.g., the ZIP analyzer is + * attached by the HTTP analyzer when corresponding content is found). + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + */ +#define BRO_PLUGIN_ANALYZER_BARE(tag) \ + AddComponent(new ::analyzer::Component(tag, 0)); + +/** + * Defines a component implementating a support analyzer. + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + */ +#define BRO_PLUGIN_SUPPORT_ANALYZER(tag) \ + AddComponent(new ::analyzer::Component(tag, 0)); + +#endif diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc new file mode 100644 index 0000000000..93ed3f2b97 --- /dev/null +++ b/src/plugin/Manager.cc @@ -0,0 +1,85 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Manager.h" + +#include "../Reporter.h" + +using namespace plugin; + +Manager::Manager() + { + init = false; + } + +Manager::~Manager() + { + assert(! init); + } + +bool Manager::LoadPlugin(const std::string& path) + { + assert(! init); + reporter->InternalError("plugin::Manager::LoadPlugin not yet implemented"); + return false; + } + +bool Manager::LoadPluginsFrom(const std::string& dir) + { + assert(! init); + reporter->InternalError("plugin::Manager::LoadPluginsFrom not yet implemented"); + return false; + } + +bool Manager::RegisterPlugin(Plugin *plugin) + { + Manager::PluginsInternal()->push_back(plugin); + return true; + } + +void Manager::InitPreScript() + { + assert(! init); + + for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ ) + (*i)->InitPreScript(); + + init = true; + } + +void Manager::InitPostScript() + { + assert(init); + + for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ ) + (*i)->InitPostScript(); + } + +void Manager::FinishPlugins() + { + assert(init); + + for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ ) + { + (*i)->Done(); +// delete *i; + } + + Manager::PluginsInternal()->clear(); + + init = false; + } + +Manager::plugin_list Manager::Plugins() const + { + return *Manager::PluginsInternal(); + } + +Manager::plugin_list* Manager::PluginsInternal() + { + static plugin_list* plugins = 0; + + if ( ! plugins ) + plugins = new plugin_list; + + return plugins; + } diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h new file mode 100644 index 0000000000..2bbcaeb0f1 --- /dev/null +++ b/src/plugin/Manager.h @@ -0,0 +1,130 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef PLUGIN_MANAGER_H +#define PLUGIN_MANAGER_H + +#include "Plugin.h" +#include "Component.h" + +#include "../Reporter.h" + +namespace plugin { + +/** + * A singleton object managing all plugins. + */ +class Manager +{ +public: + typedef std::list plugin_list; + typedef Plugin::component_list component_list; + + /** + * Constructor. + */ + Manager(); + + /** + * Destructor. + */ + ~Manager(); + + /** + * Loads a plugin dynamically from a file. This must be called only + * before InitPluginsPreScript() + * + * This is not currently implemented. + * + * @param file The path to the plugin to load. + */ + bool LoadPlugin(const std::string& file); + + /** + * Loads plugins dynamically found in a directory. This must be + * called only before InitPluginsPreScript(). + * + * This is not currently implemented. + * + * @param dir The directory to search for plugins. + */ + bool LoadPluginsFrom(const std::string& dir); + + /** + * First-stage initializion of the manager. This is called early on + * during Bro's initialization, before any scripts are processed, and + * forwards to the corresponding Plugin methods. + */ + void InitPreScript(); + + /** + * Second-stage initialization of the manager. This is called late + * during Bro's initialization after any scripts are processed, and + * forwards to the corresponding Plugin methods. + */ + void InitPostScript(); + + /** + * Finalizes all plugins at termination time. This forwards to the + * corresponding Plugin methods. + */ + void FinishPlugins(); + + /** + * Returns a list of all available plugins. This includes all that + * are compiled in statically, as well as those loaded dynamically so + * far. + */ + plugin_list Plugins() const; + + /** + * Returns a list of all available components, in any plugin, that + * are derived from a specific class. The class is given as the + * template parameter \c T. + */ + template std::list Components() const; + + /** + * Internal method that registers a freshly instantiated plugin with + * the manager. + * + * @param plugin The plugin to register. The method does not take + * ownership, yet assumes the pointer will stay valid at least until + * the Manager is destroyed. + */ + static bool RegisterPlugin(Plugin *plugin); + +private: + static plugin_list* PluginsInternal(); + + bool init; +}; + +template +std::list Manager::Components() const + { + std::list result; + + for ( plugin_list::const_iterator p = PluginsInternal()->begin(); p != PluginsInternal()->end(); p++ ) + { + component_list components = (*p)->Components(); + + for ( component_list::const_iterator c = components.begin(); c != components.end(); c++ ) + { + T* t = dynamic_cast(*c); + + if ( t ) + result.push_back(t); + } + } + + return result; + } + +} + +/** + * The global plugin manager singleton. + */ +extern plugin::Manager* plugin_mgr; + +#endif diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc new file mode 100644 index 0000000000..084c49f51e --- /dev/null +++ b/src/plugin/Plugin.cc @@ -0,0 +1,246 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include + +#include "Plugin.h" +#include "Manager.h" +#include "Component.h" + +#include "../Desc.h" + +using namespace plugin; + +BifItem::BifItem(const std::string& arg_id, Type arg_type) + { + id = copy_string(arg_id.c_str()); + type = arg_type; + } + +BifItem::BifItem(const BifItem& other) + { + id = copy_string(other.id); + type = other.type; + } + +BifItem& BifItem::operator=(const BifItem& other) + { + if ( this != &other ) + { + id = copy_string(other.id); + type = other.type; + } + + return *this; + } + +BifItem::~BifItem() + { + delete [] id; + } + +Plugin::Plugin() + { + name = copy_string(""); + description = copy_string(""); + + // These will be reset by the BRO_PLUGIN_* macros. + version = -9999; + api_version = -9999; + dynamic = false; + + Manager::RegisterPlugin(this); + } + +Plugin::~Plugin() + { + Done(); + + delete [] name; + delete [] description; + } + +const char* Plugin::Name() const + { + return name; + } + +void Plugin::SetName(const char* arg_name) + { + name = copy_string(arg_name); + } + +const char* Plugin::Description() const + { + return description; + } + +void Plugin::SetDescription(const char* arg_description) + { + description = copy_string(arg_description); + } + +int Plugin::Version() const + { + return dynamic ? version : 0; + } + +void Plugin::SetVersion(int arg_version) + { + version = arg_version; + } + +int Plugin::APIVersion() const + { + return api_version; + } + +bool Plugin::DynamicPlugin() const + { + return dynamic; + } + +void Plugin::SetAPIVersion(int arg_version) + { + api_version = arg_version; + } + +void Plugin::SetDynamicPlugin(bool arg_dynamic) + { + dynamic = arg_dynamic; + } + +void Plugin::InitPreScript() + { + } + +void Plugin::InitPostScript() + { + for ( bif_init_func_list::const_iterator f = bif_inits.begin(); f != bif_inits.end(); f++ ) + { + bif_init_func_result items = (**f)(); + + for ( bif_init_func_result::const_iterator i = items.begin(); i != items.end(); i++ ) + { + BifItem bi((*i).first, (BifItem::Type)(*i).second); + bif_items.push_back(bi); + } + } + } + +Plugin::bif_item_list Plugin::BifItems() const + { + bif_item_list l1 = bif_items; + bif_item_list l2 = CustomBifItems(); + + for ( bif_item_list::const_iterator i = l2.begin(); i != l2.end(); i++ ) + l1.push_back(*i); + + return l1; + } + +Plugin::bif_item_list Plugin::CustomBifItems() const + { + return bif_item_list(); + } + +void Plugin::Done() + { + for ( component_list::const_iterator i = components.begin(); i != components.end(); i++ ) + delete *i; + + components.clear(); + } + +Plugin::component_list Plugin::Components() const + { + return components; + } + +void Plugin::AddComponent(Component* c) + { + components.push_back(c); + } + +void Plugin::AddBifInitFunction(bif_init_func c) + { + bif_inits.push_back(c); + } + +void Plugin::Describe(ODesc* d) const + { + d->Add("Plugin: "); + d->Add(name); + + if ( description && *description ) + { + d->Add(" - "); + d->Add(description); + } + + if ( dynamic ) + { + if ( version > 0 ) + { + d->Add(" (version "); + d->Add(version); + d->Add(")"); + } + else + d->Add(" (version not set)"); + } + + else + d->Add(" (built-in)"); + + d->Add("\n"); + + if ( d->IsShort() ) + return; + + for ( component_list::const_iterator i = components.begin(); i != components.end(); i++ ) + { + (*i)->Describe(d); + d->Add("\n"); + } + + bif_item_list items = BifItems(); + + for ( bif_item_list::const_iterator i = items.begin(); i != items.end(); i++ ) + { + const char* type = 0; + + switch ( (*i).GetType() ) { + case BifItem::FUNCTION: + type = "Function"; + break; + + case BifItem::EVENT: + type = "Event"; + break; + + case BifItem::CONSTANT: + type = "Constant"; + break; + + case BifItem::GLOBAL: + type = "Global"; + break; + + case BifItem::TYPE: + type = "Type"; + break; + + default: + type = ""; + } + + d->Add(" "); + d->Add("["); + d->Add(type); + d->Add("] "); + d->Add((*i).GetID()); + d->Add("\n"); + } + } + + diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h new file mode 100644 index 0000000000..4abd260550 --- /dev/null +++ b/src/plugin/Plugin.h @@ -0,0 +1,252 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef PLUGIN_PLUGIN_H +#define PLUGIN_PLUGIN_H + +#include +#include + +#include "Macros.h" + +class ODesc; + +namespace plugin { + +class Manager; +class Component; + +/** + * A class describing an item defined in \c *.bif file. + */ +class BifItem { +public: + /** + * Type of the item. + * + * The values here must match the integers that \c bifcl generated. + */ + enum Type { FUNCTION = 1, EVENT = 2, CONSTANT = 3, GLOBAL = 4, TYPE = 5 }; + + /** + * Constructor. + * + * @param id The script-level name of the item. This should be fully + * qualified. + * + * @param type The type of the item. + */ + BifItem(const std::string& id, Type type); + + /** + * Copy constructor. + */ + BifItem(const BifItem& other); + + /** + * Assigment operator. + */ + BifItem& operator=(const BifItem& other); + + /** + * Destructor. + */ + ~BifItem(); + + /** + * Returns the script-level ID as passed into the constructor. + */ + const char* GetID() const { return id; } + + /** + * Returns the type as passed into the constructor. + */ + Type GetType() const { return type; } + +private: + const char* id; + Type type; +}; + +/** + * Base class for all plugins. + * + * Plugins encapsulate functionality that extends one of Bro's major + * subsystems, such as analysis of a specific protocol, or logging output in + * a particular format. A plugin is a logical container that can provide one + * or more \a components implementing functionality. For example, a RPC + * plugin could provide analyzer for set of related protocols (RPC, NFS, + * etc.), each of which would be a separate component. Likewise, a SQLite + * plugin could provide both a writer and reader component. In addition to + * components, a plugin can also provide of script-level elements defined in + * *.bif files. + * + * Currently, all plugins are compiled statically into the final Bro binary. + * Later, we will extend the infrastructure to also support plugins loaded + * dynamically as shared libraries. + */ +class Plugin { +public: + typedef std::list component_list; + typedef std::list bif_item_list; + + /** + * Constructor. + */ + Plugin(); + + /** + * Destructor. + */ + virtual ~Plugin(); + + /** + * Returns the name of the plugin. + */ + const char* Name() const; + + /** + * Returns a short textual description of the plugin, if provided. + */ + const char* Description() const; + + /** + * Returns the version of the plugin. Version are only meaningful for + * dynamically compiled plugins; for statically compiled ones, this + * will always return 0. + */ + int Version() const; + + /** + * Returns true if this is a dynamically linked in plugin. + */ + bool DynamicPlugin() const; + + /** + * Returns the internal API version that this plugin relies on. Only + * plugins that match Bro's current API version may be used. For + * statically compiled plugins this is automatically the case, but + * dynamically loaded plugins may cause a mismatch if they were + * compiled for a different Bro version. + */ + int APIVersion() const; + + /** + * Returns a list of all components the plugin provides. + */ + component_list Components() const; + + /** + * Returns a list of all BiF items that the plugin provides. This + * must be called only after InitBif() has been executed. + */ + bif_item_list BifItems() const; + + /** + * First-stage initialization of the plugin called early during Bro's + * startup, before scripts are parsed. This can be overridden by + * derived classes; they must however call the parent's + * implementation. + */ + virtual void InitPreScript(); + + /** + * Second-stage initialization of the plugin called late during Bro's + * startup, after scripts are parsed. This can be overridden by + * derived classes; they must however call the parent's + * implementation. + */ + virtual void InitPostScript(); + + /** + * Finalizer method that derived classes can override for performing + * custom tasks at shutdown. Implementation must call the parent's + * version. + */ + virtual void Done(); + + /** + * Returns a textual description of the plugin. + * + * @param d Description object to use for rendering. If "short mode" + * is disabled, the rendering will include a list of all components + * and BiF items. + */ + void Describe(ODesc* d) const; + +protected: + typedef std::list > bif_init_func_result; + typedef bif_init_func_result (*bif_init_func)(); + + /** + * Sets the plugins name. + * + * @param name The name. Makes a copy internally. + */ + void SetName(const char* name); + + /** + * Sets the plugin's textual description. + * + * @param name The description. Makes a copy internally. + */ + void SetDescription(const char* descr); + + /** + * Sets the plugin's version. + * + * @param version The version. + */ + void SetVersion(int version); + + /** + * Sets the API version the plugin requires. + * BRO_PLUGIN_VERSION_BUILTIN indicates that it's a plugin linked in + * statically. + */ + void SetAPIVersion(int version); + + /** + * Marks the plugin as statically or dynamically linked. + * + * @param dynamic True if this is a dynamically linked plugin. + */ + void SetDynamicPlugin(bool dynamic); + + /** + * Takes ownership. + */ + void AddComponent(Component* c); + + /** + * Virtual method that can be overriden by derived class to provide + * information about further script-level elements that the plugins + * provides on its own, i.e., outside of the standard mechanism + * processing *.bif files automatically. The returned information is + * for informational purpuses only and will show up in the result of + * BifItems() as well as in the Describe() output. + */ + virtual bif_item_list CustomBifItems() const; + + /** + * Internal function adding an entry point for registering + * auto-generated BiFs. + */ + void AddBifInitFunction(bif_init_func c); + +private: + typedef std::list bif_init_func_list; + + const char* name; + const char* description; + int version; + int api_version; + bool dynamic; + + component_list components; + bif_item_list bif_items; + bif_init_func_list bif_inits; +}; + +} + +#endif diff --git a/src/plugins.cc.in b/src/plugins.cc.in new file mode 100644 index 0000000000..4527d5d1a9 --- /dev/null +++ b/src/plugins.cc.in @@ -0,0 +1,22 @@ + +// A work-around the problem that for static libraries unused globals +// aren't linked into the final binary. CMake automatically inserts +// code here to reference the globals that initializes each of the +// statically compiled plugins. +// +// Note: This won't be necessary anymore once we can assume CMake >2.8.8 +// as a required depencendy. If so, switch bro_HAVE_OBJECT_LIBRARIES +// in src/CMakeLists.txt to TRUE and remove this. + +#include + +${__BRO_DECL_PLUGINS} + +size_t __make_sure_to_use_plugin_globals() +{ + // This function is never actually called. + + size_t i = 0; + ${__BRO_USE_PLUGINS} + return i; +} diff --git a/src/scan.l b/src/scan.l index ffbc125728..f23fa10f75 100644 --- a/src/scan.l +++ b/src/scan.l @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include "input.h" @@ -22,9 +24,11 @@ #include "PolicyFile.h" #include "broparse.h" #include "BroDoc.h" -#include "Analyzer.h" -#include "AnalyzerTags.h" #include "Reporter.h" +#include "RE.h" +#include "Net.h" + +#include "analyzer/Analyzer.h" extern YYLTYPE yylloc; // holds start line and column of token extern int print_loaded_scripts; @@ -67,9 +71,6 @@ void clear_reST_doc_comments(); // Adds changes to capture_filter to the current script's reST documentation. static void check_capture_filter_changes(); -// Adds changes to dpd_config to the current script's reST documentation. -static void check_dpd_config_changes(); - static const char* canon_doc_comment(const char* comment) { // "##Text" and "## Text" are treated the same in order to be able @@ -328,7 +329,6 @@ when return TOK_WHEN; &encrypt return TOK_ATTR_ENCRYPT; &error_handler return TOK_ATTR_ERROR_HANDLER; &expire_func return TOK_ATTR_EXPIRE_FUNC; -&group return TOK_ATTR_GROUP; &log return TOK_ATTR_LOG; &mergeable return TOK_ATTR_MERGEABLE; &optional return TOK_ATTR_OPTIONAL; @@ -344,6 +344,34 @@ when return TOK_WHEN; @DEBUG return TOK_DEBUG; // marks input for debugger +@DIR { + string rval = current_scanned_file_path; + + if ( ! rval.empty() && rval[0] == '.' ) + { + char path[MAXPATHLEN]; + + if ( ! getcwd(path, MAXPATHLEN) ) + reporter->InternalError("getcwd failed: %s", strerror(errno)); + else + rval = string(path) + "/" + rval; + } + + RET_CONST(new StringVal(rval.c_str())); + } + +@FILENAME { + char* filename_copy = copy_string(::filename); + const char* bname = basename(filename_copy); + + if ( ! bname ) + reporter->InternalError("basename failed: %s", strerror(errno)); + + StringVal* rval = new StringVal(bname); + delete [] filename_copy; + RET_CONST(rval); + } + @load{WS}{FILE} { const char* new_file = skip_whitespace(yytext + 5); // Skip "@load". if ( generate_documentation ) @@ -552,7 +580,7 @@ YYLTYPE GetCurrentLocation() static int load_files(const char* orig_file) { // Whether we pushed on a FileInfo that will restore the - // current module after the final file has been scanned. + // current module after the final file has been scanned. bool did_module_restore = false; const char* full_filename = ""; @@ -822,7 +850,6 @@ int yywrap() while ( input_files.length() > 0 ) { check_capture_filter_changes(); - check_dpd_config_changes(); if ( load_files(input_files[0]) ) { @@ -838,7 +865,6 @@ int yywrap() } check_capture_filter_changes(); - check_dpd_config_changes(); // For each file scanned so far, and for each @prefix, look for a // prefixed and flattened version of the loaded file in BROPATH. The @@ -1003,51 +1029,6 @@ static void check_capture_filter_changes() } } -static void check_dpd_config_changes() - { - if ( ! generate_documentation ) - return; - - // Lookup the "dpd_config" identifier, if it has any defined value, - // add it to the script's documentation, and clear the table so that - // it doesn't taint the documentation for subsequent scripts. - ID* dpd_config = global_scope()->Lookup("dpd_config"); - if ( ! dpd_config ) - return; - - TableVal* dpd_table = dpd_config->ID_Val()->AsTableVal(); - ListVal* dpd_list = dpd_table->ConvertToList(); - - for ( int i = 0; i < dpd_list->Length(); ++i ) - { - Val* key = dpd_list->Index(i); - if ( ! key ) - continue; - - Val* v = dpd_table->Lookup(key); - if ( ! v ) - continue; - - int tag = key->AsListVal()->Index(0)->AsCount(); - ODesc valdesc; - valdesc.SetIndentSpaces(4); - valdesc.PushIndent(); - v->Describe(&valdesc); - - if ( tag < AnalyzerTag::Error || tag > AnalyzerTag::LastAnalyzer ) - { - fprintf(stderr, "Warning: skipped bad analyzer tag: %i\n", tag); - continue; - } - - last_reST_doc->AddPortAnalysis( - Analyzer::GetTagName((AnalyzerTag::Tag)tag), - valdesc.Description()); - } - - dpd_table->RemoveAll(); - } - void print_current_reST_doc_comments() { if ( ! reST_doc_comments ) diff --git a/src/util-config.h.in b/src/util-config.h.in index 4c57495eb6..ff5e28537a 100644 --- a/src/util-config.h.in +++ b/src/util-config.h.in @@ -1,4 +1,5 @@ #define BRO_SCRIPT_INSTALL_PATH "@BRO_SCRIPT_INSTALL_PATH@" #define BRO_SCRIPT_SOURCE_PATH "@BRO_SCRIPT_SOURCE_PATH@" -#define BRO_BUILD_PATH "@CMAKE_CURRENT_BINARY_DIR@" +#define BRO_BUILD_SOURCE_PATH "@CMAKE_BINARY_DIR@/src" +#define BRO_BUILD_SCRIPTS_PATH "@CMAKE_BINARY_DIR@/scripts" #define BRO_MAGIC_INSTALL_PATH "@BRO_MAGIC_INSTALL_PATH@" diff --git a/src/util.cc b/src/util.cc index a031f41ffe..cff36f0f23 100644 --- a/src/util.cc +++ b/src/util.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -298,6 +299,13 @@ void to_upper(char* s) } } +string to_upper(const std::string& s) + { + string t = s; + std::transform(t.begin(), t.end(), t.begin(), ::toupper); + return t; + } + const char* strchr_n(const char* s, const char* end_of_s, char ch) { for ( ; s < end_of_s; ++s ) @@ -1026,8 +1034,10 @@ void get_script_subpath(const std::string& full_filename, const char** subpath) my_subpath.erase(0, strlen(BRO_SCRIPT_INSTALL_PATH)); else if ( (p = my_subpath.find(BRO_SCRIPT_SOURCE_PATH)) != std::string::npos ) my_subpath.erase(0, strlen(BRO_SCRIPT_SOURCE_PATH)); - else if ( (p = my_subpath.find(BRO_BUILD_PATH)) != std::string::npos ) - my_subpath.erase(0, strlen(BRO_BUILD_PATH)); + else if ( (p = my_subpath.find(BRO_BUILD_SOURCE_PATH)) != std::string::npos ) + my_subpath.erase(0, strlen(BRO_BUILD_SOURCE_PATH)); + else if ( (p = my_subpath.find(BRO_BUILD_SCRIPTS_PATH)) != std::string::npos ) + my_subpath.erase(0, strlen(BRO_BUILD_SCRIPTS_PATH)); // if root path found, remove path separators until next path component if ( p != std::string::npos ) @@ -1607,3 +1617,18 @@ const char* bro_magic_buffer(magic_t cookie, const void* buffer, size_t length) return rval; } + +const char* canonify_name(const char* name) + { + unsigned int len = strlen(name); + char* nname = new char[len + 1]; + + for ( unsigned int i = 0; i < len; i++ ) + { + char c = isalnum(name[i]) ? name[i] : '_'; + nname[i] = toupper(c); + } + + nname[len] = '\0'; + return nname; + } diff --git a/src/util.h b/src/util.h index b0ac760117..cafa63b7e8 100644 --- a/src/util.h +++ b/src/util.h @@ -5,8 +5,14 @@ // Expose C99 functionality from inttypes.h, which would otherwise not be // available in C++. +#ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS +#endif + +#ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS +#endif + #include #include @@ -114,6 +120,7 @@ extern char* skip_digits(char* s); extern char* get_word(char*& s); extern void get_word(int length, const char* s, int& pwlen, const char*& pw); extern void to_upper(char* s); +extern std::string to_upper(const std::string& s); extern const char* strchr_n(const char* s, const char* end_of_s, char ch); extern const char* strrchr_n(const char* s, const char* end_of_s, char ch); extern int decode_hex(char ch); @@ -376,4 +383,12 @@ extern magic_t magic_mime_cookie; void bro_init_magic(magic_t* cookie_ptr, int flags); const char* bro_magic_buffer(magic_t cookie, const void* buffer, size_t length); +/** + * Canonicalizes a name by converting it to uppercase letters and replacing + * all non-alphanumeric characters with an underscore. + * @param name The string to canonicalize. + * @return The canonicalized version of \a name which caller may later delete[]. + */ +const char* canonify_name(const char* name); + #endif diff --git a/testing/btest/Baseline/core.check-unused-event-handlers/.stderr b/testing/btest/Baseline/core.check-unused-event-handlers/.stderr index 8d8bf1a85b..1a32ad442c 100644 --- a/testing/btest/Baseline/core.check-unused-event-handlers/.stderr +++ b/testing/btest/Baseline/core.check-unused-event-handlers/.stderr @@ -1 +1,2 @@ warning in , line 1: event handler never invoked: this_is_never_used +warning in , line 1: event handler never invoked: InputRaw::process_finished diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 840f555711..9d3fb87861 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,19 +3,67 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2013-05-15-23-01-21 +#open 2013-06-10-19-50-56 #fields name #types string scripts/base/init-bare.bro - build/src/base/const.bif.bro - build/src/base/types.bif.bro - build/src/base/strings.bif.bro - build/src/base/bro.bif.bro - build/src/base/reporter.bif.bro - build/src/base/event.bif.bro + build/scripts/base/bif/const.bif.bro + build/scripts/base/bif/types.bif.bro + build/scripts/base/bif/strings.bif.bro + build/scripts/base/bif/bro.bif.bro + build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/event.bif.bro + build/scripts/base/bif/plugins/__load__.bro + build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro + build/scripts/base/bif/plugins/Bro_AYIYA.events.bif.bro + build/scripts/base/bif/plugins/Bro_BackDoor.events.bif.bro + build/scripts/base/bif/plugins/Bro_BitTorrent.events.bif.bro + build/scripts/base/bif/plugins/Bro_ConnSize.events.bif.bro + build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro + build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro + build/scripts/base/bif/plugins/Bro_FTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_FTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_File.events.bif.bro + build/scripts/base/bif/plugins/Bro_FileHash.events.bif.bro + build/scripts/base/bif/plugins/Bro_Finger.events.bif.bro + build/scripts/base/bif/plugins/Bro_GTPv1.events.bif.bro + build/scripts/base/bif/plugins/Bro_Gnutella.events.bif.bro + build/scripts/base/bif/plugins/Bro_HTTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_HTTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_ICMP.events.bif.bro + build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro + build/scripts/base/bif/plugins/Bro_Ident.events.bif.bro + build/scripts/base/bif/plugins/Bro_InterConn.events.bif.bro + build/scripts/base/bif/plugins/Bro_Login.events.bif.bro + build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro + build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro + build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro + build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro + build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro + build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SOCKS.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSH.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSL.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSL.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SteppingStone.events.bif.bro + build/scripts/base/bif/plugins/Bro_Syslog.events.bif.bro + build/scripts/base/bif/plugins/Bro_TCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_TCP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_Teredo.events.bif.bro + build/scripts/base/bif/plugins/Bro_UDP.events.bif.bro + build/scripts/base/bif/plugins/Bro_ZIP.events.bif.bro scripts/base/frameworks/logging/__load__.bro scripts/base/frameworks/logging/main.bro - build/src/base/logging.bif.bro + build/scripts/base/bif/logging.bif.bro scripts/base/frameworks/logging/postprocessors/__load__.bro scripts/base/frameworks/logging/postprocessors/scp.bro scripts/base/frameworks/logging/postprocessors/sftp.bro @@ -26,15 +74,18 @@ scripts/base/init-bare.bro scripts/base/frameworks/logging/writers/none.bro scripts/base/frameworks/input/__load__.bro scripts/base/frameworks/input/main.bro - build/src/base/input.bif.bro + build/scripts/base/bif/input.bif.bro scripts/base/frameworks/input/readers/ascii.bro scripts/base/frameworks/input/readers/raw.bro scripts/base/frameworks/input/readers/benchmark.bro scripts/base/frameworks/input/readers/binary.bro scripts/base/frameworks/input/readers/sqlite.bro + scripts/base/frameworks/analyzer/__load__.bro + scripts/base/frameworks/analyzer/main.bro + build/scripts/base/bif/analyzer.bif.bro scripts/base/frameworks/file-analysis/__load__.bro scripts/base/frameworks/file-analysis/main.bro - build/src/base/file_analysis.bif.bro + build/scripts/base/bif/file_analysis.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2013-05-15-23-01-21 +#close 2013-06-10-19-50-56 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 3cfd9b58a7..b861f44266 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,19 +3,67 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2013-05-16-00-19-22 +#open 2013-06-10-19-50-57 #fields name #types string scripts/base/init-bare.bro - build/src/base/const.bif.bro - build/src/base/types.bif.bro - build/src/base/strings.bif.bro - build/src/base/bro.bif.bro - build/src/base/reporter.bif.bro - build/src/base/event.bif.bro + build/scripts/base/bif/const.bif.bro + build/scripts/base/bif/types.bif.bro + build/scripts/base/bif/strings.bif.bro + build/scripts/base/bif/bro.bif.bro + build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/event.bif.bro + build/scripts/base/bif/plugins/__load__.bro + build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro + build/scripts/base/bif/plugins/Bro_AYIYA.events.bif.bro + build/scripts/base/bif/plugins/Bro_BackDoor.events.bif.bro + build/scripts/base/bif/plugins/Bro_BitTorrent.events.bif.bro + build/scripts/base/bif/plugins/Bro_ConnSize.events.bif.bro + build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro + build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro + build/scripts/base/bif/plugins/Bro_FTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_FTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_File.events.bif.bro + build/scripts/base/bif/plugins/Bro_FileHash.events.bif.bro + build/scripts/base/bif/plugins/Bro_Finger.events.bif.bro + build/scripts/base/bif/plugins/Bro_GTPv1.events.bif.bro + build/scripts/base/bif/plugins/Bro_Gnutella.events.bif.bro + build/scripts/base/bif/plugins/Bro_HTTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_HTTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_ICMP.events.bif.bro + build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro + build/scripts/base/bif/plugins/Bro_Ident.events.bif.bro + build/scripts/base/bif/plugins/Bro_InterConn.events.bif.bro + build/scripts/base/bif/plugins/Bro_Login.events.bif.bro + build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro + build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro + build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro + build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro + build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro + build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SOCKS.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSH.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSL.events.bif.bro + build/scripts/base/bif/plugins/Bro_SSL.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SteppingStone.events.bif.bro + build/scripts/base/bif/plugins/Bro_Syslog.events.bif.bro + build/scripts/base/bif/plugins/Bro_TCP.events.bif.bro + build/scripts/base/bif/plugins/Bro_TCP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_Teredo.events.bif.bro + build/scripts/base/bif/plugins/Bro_UDP.events.bif.bro + build/scripts/base/bif/plugins/Bro_ZIP.events.bif.bro scripts/base/frameworks/logging/__load__.bro scripts/base/frameworks/logging/main.bro - build/src/base/logging.bif.bro + build/scripts/base/bif/logging.bif.bro scripts/base/frameworks/logging/postprocessors/__load__.bro scripts/base/frameworks/logging/postprocessors/scp.bro scripts/base/frameworks/logging/postprocessors/sftp.bro @@ -26,15 +74,18 @@ scripts/base/init-bare.bro scripts/base/frameworks/logging/writers/none.bro scripts/base/frameworks/input/__load__.bro scripts/base/frameworks/input/main.bro - build/src/base/input.bif.bro + build/scripts/base/bif/input.bif.bro scripts/base/frameworks/input/readers/ascii.bro scripts/base/frameworks/input/readers/raw.bro scripts/base/frameworks/input/readers/benchmark.bro scripts/base/frameworks/input/readers/binary.bro scripts/base/frameworks/input/readers/sqlite.bro + scripts/base/frameworks/analyzer/__load__.bro + scripts/base/frameworks/analyzer/main.bro + build/scripts/base/bif/analyzer.bif.bro scripts/base/frameworks/file-analysis/__load__.bro scripts/base/frameworks/file-analysis/main.bro - build/src/base/file_analysis.bif.bro + build/scripts/base/bif/file_analysis.bif.bro scripts/base/init-default.bro scripts/base/utils/site.bro scripts/base/utils/patterns.bro @@ -141,4 +192,4 @@ scripts/base/init-default.bro scripts/base/protocols/syslog/main.bro scripts/base/misc/find-checksum-offloading.bro scripts/policy/misc/loaded-scripts.bro -#close 2013-05-16-00-19-22 +#close 2013-06-10-19-50-57 diff --git a/testing/btest/Baseline/doc.autogen-reST-example/example.rst b/testing/btest/Baseline/doc.autogen-reST-example/example.rst index 1f60efe70b..2cb75a6b9f 100644 --- a/testing/btest/Baseline/doc.autogen-reST-example/example.rst +++ b/testing/btest/Baseline/doc.autogen-reST-example/example.rst @@ -109,17 +109,6 @@ Notices Configuration Changes ##################### -Port Analysis -^^^^^^^^^^^^^ -Loading this script makes the following changes to :bro:see:`dpd_config`. - -SSL:: - - [ports={ - 443/tcp, - 562/tcp - }] - Packet Filter ^^^^^^^^^^^^^ Loading this script makes the following changes to :bro:see:`capture_filters`. diff --git a/testing/btest/Baseline/istate.events-ssl/events.rec.log b/testing/btest/Baseline/istate.events-ssl/events.rec.log index 04993fb84a..8c7f4f621c 100644 --- a/testing/btest/Baseline/istate.events-ssl/events.rec.log +++ b/testing/btest/Baseline/istate.events-ssl/events.rec.log @@ -8,7 +8,6 @@ http_all_headers http_content_type http_end_entity http_message_done -http_signature_found http_reply http_begin_entity http_header diff --git a/testing/btest/Baseline/istate.events-ssl/events.snd.log b/testing/btest/Baseline/istate.events-ssl/events.snd.log index 04993fb84a..8c7f4f621c 100644 --- a/testing/btest/Baseline/istate.events-ssl/events.snd.log +++ b/testing/btest/Baseline/istate.events-ssl/events.snd.log @@ -8,7 +8,6 @@ http_all_headers http_content_type http_end_entity http_message_done -http_signature_found http_reply http_begin_entity http_header diff --git a/testing/btest/Baseline/istate.events/events.rec.log b/testing/btest/Baseline/istate.events/events.rec.log index 04993fb84a..8c7f4f621c 100644 --- a/testing/btest/Baseline/istate.events/events.rec.log +++ b/testing/btest/Baseline/istate.events/events.rec.log @@ -8,7 +8,6 @@ http_all_headers http_content_type http_end_entity http_message_done -http_signature_found http_reply http_begin_entity http_header diff --git a/testing/btest/Baseline/istate.events/events.snd.log b/testing/btest/Baseline/istate.events/events.snd.log index 04993fb84a..8c7f4f621c 100644 --- a/testing/btest/Baseline/istate.events/events.snd.log +++ b/testing/btest/Baseline/istate.events/events.snd.log @@ -8,7 +8,6 @@ http_all_headers http_content_type http_end_entity http_message_done -http_signature_found http_reply http_begin_entity http_header diff --git a/testing/btest/Baseline/language.at-dir/out b/testing/btest/Baseline/language.at-dir/out new file mode 100644 index 0000000000..4cd8e27d6a --- /dev/null +++ b/testing/btest/Baseline/language.at-dir/out @@ -0,0 +1 @@ +/Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-dir diff --git a/testing/btest/Baseline/language.at-dir/out2 b/testing/btest/Baseline/language.at-dir/out2 new file mode 100644 index 0000000000..f8e3c550d3 --- /dev/null +++ b/testing/btest/Baseline/language.at-dir/out2 @@ -0,0 +1 @@ +/Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.at-path/. diff --git a/testing/btest/Baseline/language.at-filename/out b/testing/btest/Baseline/language.at-filename/out new file mode 100644 index 0000000000..12cfb152d9 --- /dev/null +++ b/testing/btest/Baseline/language.at-filename/out @@ -0,0 +1 @@ +at-filename.bro diff --git a/testing/btest/Baseline/language.table-redef/out b/testing/btest/Baseline/language.table-redef/out new file mode 100644 index 0000000000..fd1939df7e --- /dev/null +++ b/testing/btest/Baseline/language.table-redef/out @@ -0,0 +1,6 @@ +{ +[def] = 99.0, +[neat] = 1.0, +[cool] = 28.0, +[abc] = 8.0 +} diff --git a/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output b/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output new file mode 100644 index 0000000000..600f353088 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output @@ -0,0 +1,5 @@ +APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_DNS +APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_FTP +APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_HTTP +APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_SSH +APPLIED:, 1299499195.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=8/tcp], Analyzer::ANALYZER_DNS diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.actions.data_event/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.actions.data_event/out index d0816d8a94..ddc3449a4c 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.actions.data_event/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.actions.data_event/out @@ -1,23 +1,23 @@ FILE_NEW -Cx92a0ym5R8, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER ^J0.26 | 201 MIME_TYPE text/plain -file_stream, Cx92a0ym5R8, 1500, ^J0.26 | 2012-08-24 15:10:04 -0700^J^J * Fixing update-changes, which could pick the wrong control file. (Robin Sommer)^J^J * Fixing GPG signing script. (Robin Sommer)^J^J0.25 | 2012-08-01 13:55:46 -0500^J^J * Fix configure script to exit with non-zero status on error (Jon Siwek)^J^J0.24 | 2012-07-05 12:50:43 -0700^J^J * Raise minimum required CMake version to 2.6.3 (Jon Siwek)^J^J * Adding script to delete old fully-merged branches. (Robin Sommer)^J^J0.23-2 | 2012-01-25 13:24:01 -0800^J^J * Fix a bro-cut error message. (Daniel Thayer)^J^J0.23 | 2012-01-11 12:16:11 -0800^J^J * Tweaks to release scripts, plus a new one for signing files.^J (Robin Sommer)^J^J0.22 | 2012-01-10 16:45:19 -0800^J^J * Tweaks for OpenBSD support. (Jon Siwek)^J^J * bro-cut extensions and fixes. (Robin Sommer)^J ^J - If no field names are given on the command line, we now pass through^J all fields. Adresses #657.^J^J - Removing some GNUism from awk script. Addresses #653.^J^J - Added option for time output in UTC. Addresses #668.^J^J - Added output field separator option -F. Addresses #649.^J^J - Fixing option -c: only some header lines were passed through^J rather than all. (Robin Sommer)^J^J * Fix parallel make portability. (Jon Siwek)^J^J0.21-9 | 2011-11-07 05:44:14 -0800^J^J * Fixing compiler warnings. Addresses #388. (Jon Siwek)^J^J0.21-2 | 2011-11-02 18:12:13 -0700^J^J * Fix for misnaming temp file in update-changes script. (Robin Sommer)^J^J0.21-1 | 2011-11-02 18:10:39 -0700^J^J * Little fix for make-relea -file_chunk, Cx92a0ym5R8, 1500, 0, ^J0.26 | 2012-08-24 15:10:04 -0700^J^J * Fixing update-changes, which could pick the wrong control file. (Robin Sommer)^J^J * Fixing GPG signing script. (Robin Sommer)^J^J0.25 | 2012-08-01 13:55:46 -0500^J^J * Fix configure script to exit with non-zero status on error (Jon Siwek)^J^J0.24 | 2012-07-05 12:50:43 -0700^J^J * Raise minimum required CMake version to 2.6.3 (Jon Siwek)^J^J * Adding script to delete old fully-merged branches. (Robin Sommer)^J^J0.23-2 | 2012-01-25 13:24:01 -0800^J^J * Fix a bro-cut error message. (Daniel Thayer)^J^J0.23 | 2012-01-11 12:16:11 -0800^J^J * Tweaks to release scripts, plus a new one for signing files.^J (Robin Sommer)^J^J0.22 | 2012-01-10 16:45:19 -0800^J^J * Tweaks for OpenBSD support. (Jon Siwek)^J^J * bro-cut extensions and fixes. (Robin Sommer)^J ^J - If no field names are given on the command line, we now pass through^J all fields. Adresses #657.^J^J - Removing some GNUism from awk script. Addresses #653.^J^J - Added option for time output in UTC. Addresses #668.^J^J - Added output field separator option -F. Addresses #649.^J^J - Fixing option -c: only some header lines were passed through^J rather than all. (Robin Sommer)^J^J * Fix parallel make portability. (Jon Siwek)^J^J0.21-9 | 2011-11-07 05:44:14 -0800^J^J * Fixing compiler warnings. Addresses #388. (Jon Siwek)^J^J0.21-2 | 2011-11-02 18:12:13 -0700^J^J * Fix for misnaming temp file in update-changes script. (Robin Sommer)^J^J0.21-1 | 2011-11-02 18:10:39 -0700^J^J * Little fix for make-relea -file_stream, Cx92a0ym5R8, 1024, se script, which could pick out the wrong^J tag. (Robin Sommer)^J^J0.21 | 2011-10-27 17:40:45 -0700^J^J * Fixing bro-cut's usage message and argument error handling. (Robin Sommer)^J^J * Bugfix in update-changes script. (Robin Sommer)^J^J * update-changes now ignores commits it did itself. (Robin Sommer)^J^J * Fix a bug in the update-changes script. (Robin Sommer)^J^J * bro-cut now always installs to $prefix/bin by `make install`. (Jon Siwek)^J^J * Options to adjust time format for bro-cut. (Robin Sommer)^J^J The default with -d is now ISO format. The new option "-D "^J specifies a custom strftime()-style format string. Alternatively,^J the environment variable BRO_CUT_TIMEFMT can set the format as^J well.^J^J * bro-cut now understands the field separator header. (Robin Sommer)^J^J * Renaming options -h/-H -> -c/-C, and doing some general cleanup.^J^J0.2 | 2011-10-25 19:53:57 -0700^J^J * Adding support for replacing version string in a setup.py. (Robin^J Sommer)^J^J * Change generated root cert DN indices f -file_chunk, Cx92a0ym5R8, 1024, 1500, se script, which could pick out the wrong^J tag. (Robin Sommer)^J^J0.21 | 2011-10-27 17:40:45 -0700^J^J * Fixing bro-cut's usage message and argument error handling. (Robin Sommer)^J^J * Bugfix in update-changes script. (Robin Sommer)^J^J * update-changes now ignores commits it did itself. (Robin Sommer)^J^J * Fix a bug in the update-changes script. (Robin Sommer)^J^J * bro-cut now always installs to $prefix/bin by `make install`. (Jon Siwek)^J^J * Options to adjust time format for bro-cut. (Robin Sommer)^J^J The default with -d is now ISO format. The new option "-D "^J specifies a custom strftime()-style format string. Alternatively,^J the environment variable BRO_CUT_TIMEFMT can set the format as^J well.^J^J * bro-cut now understands the field separator header. (Robin Sommer)^J^J * Renaming options -h/-H -> -c/-C, and doing some general cleanup.^J^J0.2 | 2011-10-25 19:53:57 -0700^J^J * Adding support for replacing version string in a setup.py. (Robin^J Sommer)^J^J * Change generated root cert DN indices f -file_stream, Cx92a0ym5R8, 476, ormat for RFC2253^J compliance. (Jon Siwek)^J^J * New tool devel-tools/check-release to run before making releases.^J (Robin Sommer)^J^J * devel-tools/update-changes gets a new option -a to amend to^J previous commit if possible. Default is now not to (used to be the^J opposite). (Robin Sommer)^J^J * Change Mozilla trust root generation to index certs by subject DN. (Jon Siwek)^J^J * Change distclean to only remove build dir. (Jon Siwek)^J^J * Make dist now cleans the -file_chunk, Cx92a0ym5R8, 476, 2524, ormat for RFC2253^J compliance. (Jon Siwek)^J^J * New tool devel-tools/check-release to run before making releases.^J (Robin Sommer)^J^J * devel-tools/update-changes gets a new option -a to amend to^J previous commit if possible. Default is now not to (used to be the^J opposite). (Robin Sommer)^J^J * Change Mozilla trust root generation to index certs by subject DN. (Jon Siwek)^J^J * Change distclean to only remove build dir. (Jon Siwek)^J^J * Make dist now cleans the -file_stream, Cx92a0ym5R8, 1024, copied source (Jon Siwek)^J^J * Small tweak to make-release for forced git-clean. (Jon Siwek)^J^J * Fix to not let updates scripts loose their executable permissions.^J (Robin Sommer)^J^J * devel-tools/update-changes now looks for a 'release' tag to^J idenfify the stable version, and 'beta' for the beta versions.^J (Robin Sommer).^J^J * Distribution cleanup. (Robin Sommer)^J^J * New script devel-tools/make-release to create source tar balls.^J (Robin Sommer)^J^J * Removing bdcat. With the new log format, this isn't very useful^J anymore. (Robin Sommer)^J^J * Adding script that shows all pending git fastpath commits. (Robin^J Sommer)^J^J * Script to measure CPU time by loading an increasing set of^J scripts. (Robin Sommer)^J^J * extract-conn script now deals wit *.gz files. (Robin Sommer)^J^J * Tiny update to output a valid CA list file for SSL cert^J validation. (Seth Hall)^J^J * Adding "install-aux" target. Addresses #622. (Jon Siwek)^J^J * Distribution cleanup. (Jon Siwek and Robin Sommer)^J^J * FindPCAP -file_chunk, Cx92a0ym5R8, 1024, 3000, copied source (Jon Siwek)^J^J * Small tweak to make-release for forced git-clean. (Jon Siwek)^J^J * Fix to not let updates scripts loose their executable permissions.^J (Robin Sommer)^J^J * devel-tools/update-changes now looks for a 'release' tag to^J idenfify the stable version, and 'beta' for the beta versions.^J (Robin Sommer).^J^J * Distribution cleanup. (Robin Sommer)^J^J * New script devel-tools/make-release to create source tar balls.^J (Robin Sommer)^J^J * Removing bdcat. With the new log format, this isn't very useful^J anymore. (Robin Sommer)^J^J * Adding script that shows all pending git fastpath commits. (Robin^J Sommer)^J^J * Script to measure CPU time by loading an increasing set of^J scripts. (Robin Sommer)^J^J * extract-conn script now deals wit *.gz files. (Robin Sommer)^J^J * Tiny update to output a valid CA list file for SSL cert^J validation. (Seth Hall)^J^J * Adding "install-aux" target. Addresses #622. (Jon Siwek)^J^J * Distribution cleanup. (Jon Siwek and Robin Sommer)^J^J * FindPCAP -file_stream, Cx92a0ym5R8, 476, now links against thread library when necessary (e.g.^J PF_RING's libpcap) (Jon Siwek)^J^J * Install binaries with an RPATH (Jon Siwek)^J^J * Workaround for FreeBSD CMake port missing debug flags (Jon Siwek)^J^J * Rewrite of the update-changes script. (Robin Sommer)^J^J0.1-1 | 2011-06-14 21:12:41 -0700^J^J * Add a script for generating Mozilla's CA list for the SSL analyzer.^J (Seth Hall)^J^J0.1 | 2011-04-01 16:28:22 -0700^J^J * Converting build process to CMake. (Jon Siwek)^J -file_chunk, Cx92a0ym5R8, 476, 4024, now links against thread library when necessary (e.g.^J PF_RING's libpcap) (Jon Siwek)^J^J * Install binaries with an RPATH (Jon Siwek)^J^J * Workaround for FreeBSD CMake port missing debug flags (Jon Siwek)^J^J * Rewrite of the update-changes script. (Robin Sommer)^J^J0.1-1 | 2011-06-14 21:12:41 -0700^J^J * Add a script for generating Mozilla's CA list for the SSL analyzer.^J (Seth Hall)^J^J0.1 | 2011-04-01 16:28:22 -0700^J^J * Converting build process to CMake. (Jon Siwek)^J -file_stream, Cx92a0ym5R8, 205, ^J * Removing cf/hf/ca-* from distribution. The README has a note where^J to find them now. (Robin Sommer)^J^J * General cleanup. (Robin Sommer)^J^J * Initial import of bro/aux from SVN r7088. (Jon Siwek)^J -file_chunk, Cx92a0ym5R8, 205, 4500, ^J * Removing cf/hf/ca-* from distribution. The README has a note where^J to find them now. (Robin Sommer)^J^J * General cleanup. (Robin Sommer)^J^J * Initial import of bro/aux from SVN r7088. (Jon Siwek)^J +file_stream, file #0, 1500, ^J0.26 | 2012-08-24 15:10:04 -0700^J^J * Fixing update-changes, which could pick the wrong control file. (Robin Sommer)^J^J * Fixing GPG signing script. (Robin Sommer)^J^J0.25 | 2012-08-01 13:55:46 -0500^J^J * Fix configure script to exit with non-zero status on error (Jon Siwek)^J^J0.24 | 2012-07-05 12:50:43 -0700^J^J * Raise minimum required CMake version to 2.6.3 (Jon Siwek)^J^J * Adding script to delete old fully-merged branches. (Robin Sommer)^J^J0.23-2 | 2012-01-25 13:24:01 -0800^J^J * Fix a bro-cut error message. (Daniel Thayer)^J^J0.23 | 2012-01-11 12:16:11 -0800^J^J * Tweaks to release scripts, plus a new one for signing files.^J (Robin Sommer)^J^J0.22 | 2012-01-10 16:45:19 -0800^J^J * Tweaks for OpenBSD support. (Jon Siwek)^J^J * bro-cut extensions and fixes. (Robin Sommer)^J ^J - If no field names are given on the command line, we now pass through^J all fields. Adresses #657.^J^J - Removing some GNUism from awk script. Addresses #653.^J^J - Added option for time output in UTC. Addresses #668.^J^J - Added output field separator option -F. Addresses #649.^J^J - Fixing option -c: only some header lines were passed through^J rather than all. (Robin Sommer)^J^J * Fix parallel make portability. (Jon Siwek)^J^J0.21-9 | 2011-11-07 05:44:14 -0800^J^J * Fixing compiler warnings. Addresses #388. (Jon Siwek)^J^J0.21-2 | 2011-11-02 18:12:13 -0700^J^J * Fix for misnaming temp file in update-changes script. (Robin Sommer)^J^J0.21-1 | 2011-11-02 18:10:39 -0700^J^J * Little fix for make-relea +file_chunk, file #0, 1500, 0, ^J0.26 | 2012-08-24 15:10:04 -0700^J^J * Fixing update-changes, which could pick the wrong control file. (Robin Sommer)^J^J * Fixing GPG signing script. (Robin Sommer)^J^J0.25 | 2012-08-01 13:55:46 -0500^J^J * Fix configure script to exit with non-zero status on error (Jon Siwek)^J^J0.24 | 2012-07-05 12:50:43 -0700^J^J * Raise minimum required CMake version to 2.6.3 (Jon Siwek)^J^J * Adding script to delete old fully-merged branches. (Robin Sommer)^J^J0.23-2 | 2012-01-25 13:24:01 -0800^J^J * Fix a bro-cut error message. (Daniel Thayer)^J^J0.23 | 2012-01-11 12:16:11 -0800^J^J * Tweaks to release scripts, plus a new one for signing files.^J (Robin Sommer)^J^J0.22 | 2012-01-10 16:45:19 -0800^J^J * Tweaks for OpenBSD support. (Jon Siwek)^J^J * bro-cut extensions and fixes. (Robin Sommer)^J ^J - If no field names are given on the command line, we now pass through^J all fields. Adresses #657.^J^J - Removing some GNUism from awk script. Addresses #653.^J^J - Added option for time output in UTC. Addresses #668.^J^J - Added output field separator option -F. Addresses #649.^J^J - Fixing option -c: only some header lines were passed through^J rather than all. (Robin Sommer)^J^J * Fix parallel make portability. (Jon Siwek)^J^J0.21-9 | 2011-11-07 05:44:14 -0800^J^J * Fixing compiler warnings. Addresses #388. (Jon Siwek)^J^J0.21-2 | 2011-11-02 18:12:13 -0700^J^J * Fix for misnaming temp file in update-changes script. (Robin Sommer)^J^J0.21-1 | 2011-11-02 18:10:39 -0700^J^J * Little fix for make-relea +file_stream, file #0, 1024, se script, which could pick out the wrong^J tag. (Robin Sommer)^J^J0.21 | 2011-10-27 17:40:45 -0700^J^J * Fixing bro-cut's usage message and argument error handling. (Robin Sommer)^J^J * Bugfix in update-changes script. (Robin Sommer)^J^J * update-changes now ignores commits it did itself. (Robin Sommer)^J^J * Fix a bug in the update-changes script. (Robin Sommer)^J^J * bro-cut now always installs to $prefix/bin by `make install`. (Jon Siwek)^J^J * Options to adjust time format for bro-cut. (Robin Sommer)^J^J The default with -d is now ISO format. The new option "-D "^J specifies a custom strftime()-style format string. Alternatively,^J the environment variable BRO_CUT_TIMEFMT can set the format as^J well.^J^J * bro-cut now understands the field separator header. (Robin Sommer)^J^J * Renaming options -h/-H -> -c/-C, and doing some general cleanup.^J^J0.2 | 2011-10-25 19:53:57 -0700^J^J * Adding support for replacing version string in a setup.py. (Robin^J Sommer)^J^J * Change generated root cert DN indices f +file_chunk, file #0, 1024, 1500, se script, which could pick out the wrong^J tag. (Robin Sommer)^J^J0.21 | 2011-10-27 17:40:45 -0700^J^J * Fixing bro-cut's usage message and argument error handling. (Robin Sommer)^J^J * Bugfix in update-changes script. (Robin Sommer)^J^J * update-changes now ignores commits it did itself. (Robin Sommer)^J^J * Fix a bug in the update-changes script. (Robin Sommer)^J^J * bro-cut now always installs to $prefix/bin by `make install`. (Jon Siwek)^J^J * Options to adjust time format for bro-cut. (Robin Sommer)^J^J The default with -d is now ISO format. The new option "-D "^J specifies a custom strftime()-style format string. Alternatively,^J the environment variable BRO_CUT_TIMEFMT can set the format as^J well.^J^J * bro-cut now understands the field separator header. (Robin Sommer)^J^J * Renaming options -h/-H -> -c/-C, and doing some general cleanup.^J^J0.2 | 2011-10-25 19:53:57 -0700^J^J * Adding support for replacing version string in a setup.py. (Robin^J Sommer)^J^J * Change generated root cert DN indices f +file_stream, file #0, 476, ormat for RFC2253^J compliance. (Jon Siwek)^J^J * New tool devel-tools/check-release to run before making releases.^J (Robin Sommer)^J^J * devel-tools/update-changes gets a new option -a to amend to^J previous commit if possible. Default is now not to (used to be the^J opposite). (Robin Sommer)^J^J * Change Mozilla trust root generation to index certs by subject DN. (Jon Siwek)^J^J * Change distclean to only remove build dir. (Jon Siwek)^J^J * Make dist now cleans the +file_chunk, file #0, 476, 2524, ormat for RFC2253^J compliance. (Jon Siwek)^J^J * New tool devel-tools/check-release to run before making releases.^J (Robin Sommer)^J^J * devel-tools/update-changes gets a new option -a to amend to^J previous commit if possible. Default is now not to (used to be the^J opposite). (Robin Sommer)^J^J * Change Mozilla trust root generation to index certs by subject DN. (Jon Siwek)^J^J * Change distclean to only remove build dir. (Jon Siwek)^J^J * Make dist now cleans the +file_stream, file #0, 1024, copied source (Jon Siwek)^J^J * Small tweak to make-release for forced git-clean. (Jon Siwek)^J^J * Fix to not let updates scripts loose their executable permissions.^J (Robin Sommer)^J^J * devel-tools/update-changes now looks for a 'release' tag to^J idenfify the stable version, and 'beta' for the beta versions.^J (Robin Sommer).^J^J * Distribution cleanup. (Robin Sommer)^J^J * New script devel-tools/make-release to create source tar balls.^J (Robin Sommer)^J^J * Removing bdcat. With the new log format, this isn't very useful^J anymore. (Robin Sommer)^J^J * Adding script that shows all pending git fastpath commits. (Robin^J Sommer)^J^J * Script to measure CPU time by loading an increasing set of^J scripts. (Robin Sommer)^J^J * extract-conn script now deals wit *.gz files. (Robin Sommer)^J^J * Tiny update to output a valid CA list file for SSL cert^J validation. (Seth Hall)^J^J * Adding "install-aux" target. Addresses #622. (Jon Siwek)^J^J * Distribution cleanup. (Jon Siwek and Robin Sommer)^J^J * FindPCAP +file_chunk, file #0, 1024, 3000, copied source (Jon Siwek)^J^J * Small tweak to make-release for forced git-clean. (Jon Siwek)^J^J * Fix to not let updates scripts loose their executable permissions.^J (Robin Sommer)^J^J * devel-tools/update-changes now looks for a 'release' tag to^J idenfify the stable version, and 'beta' for the beta versions.^J (Robin Sommer).^J^J * Distribution cleanup. (Robin Sommer)^J^J * New script devel-tools/make-release to create source tar balls.^J (Robin Sommer)^J^J * Removing bdcat. With the new log format, this isn't very useful^J anymore. (Robin Sommer)^J^J * Adding script that shows all pending git fastpath commits. (Robin^J Sommer)^J^J * Script to measure CPU time by loading an increasing set of^J scripts. (Robin Sommer)^J^J * extract-conn script now deals wit *.gz files. (Robin Sommer)^J^J * Tiny update to output a valid CA list file for SSL cert^J validation. (Seth Hall)^J^J * Adding "install-aux" target. Addresses #622. (Jon Siwek)^J^J * Distribution cleanup. (Jon Siwek and Robin Sommer)^J^J * FindPCAP +file_stream, file #0, 476, now links against thread library when necessary (e.g.^J PF_RING's libpcap) (Jon Siwek)^J^J * Install binaries with an RPATH (Jon Siwek)^J^J * Workaround for FreeBSD CMake port missing debug flags (Jon Siwek)^J^J * Rewrite of the update-changes script. (Robin Sommer)^J^J0.1-1 | 2011-06-14 21:12:41 -0700^J^J * Add a script for generating Mozilla's CA list for the SSL analyzer.^J (Seth Hall)^J^J0.1 | 2011-04-01 16:28:22 -0700^J^J * Converting build process to CMake. (Jon Siwek)^J +file_chunk, file #0, 476, 4024, now links against thread library when necessary (e.g.^J PF_RING's libpcap) (Jon Siwek)^J^J * Install binaries with an RPATH (Jon Siwek)^J^J * Workaround for FreeBSD CMake port missing debug flags (Jon Siwek)^J^J * Rewrite of the update-changes script. (Robin Sommer)^J^J0.1-1 | 2011-06-14 21:12:41 -0700^J^J * Add a script for generating Mozilla's CA list for the SSL analyzer.^J (Seth Hall)^J^J0.1 | 2011-04-01 16:28:22 -0700^J^J * Converting build process to CMake. (Jon Siwek)^J +file_stream, file #0, 205, ^J * Removing cf/hf/ca-* from distribution. The README has a note where^J to find them now. (Robin Sommer)^J^J * General cleanup. (Robin Sommer)^J^J * Initial import of bro/aux from SVN r7088. (Jon Siwek)^J +file_chunk, file #0, 205, 4500, ^J * Removing cf/hf/ca-* from distribution. The README has a note where^J to find them now. (Robin Sommer)^J^J * General cleanup. (Robin Sommer)^J^J * Initial import of bro/aux from SVN r7088. (Jon Siwek)^J FILE_STATE_REMOVE -Cx92a0ym5R8, 4705, 0 +file #0, 4705, 0 [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp] total bytes: 4705 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.remove_action/get.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.remove_action/get.out index 846363961e..4b572d5df9 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.remove_action/get.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.remove_action/get.out @@ -1,11 +1,11 @@ FILE_NEW -Cx92a0ym5R8, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER ^J0.26 | 201 MIME_TYPE text/plain FILE_STATE_REMOVE -Cx92a0ym5R8, 4705, 0 +file #0, 4705, 0 [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp] total bytes: 4705 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.set_timeout_interval/bro..stdout b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.set_timeout_interval/bro..stdout index 9cb4b5cc68..160a51a543 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.set_timeout_interval/bro..stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.set_timeout_interval/bro..stdout @@ -1,20 +1,20 @@ FILE_NEW -oDwT1BbzjM1, 0, 0 +file #0, 0, 0 MIME_TYPE application/x-dosexec FILE_STATE_REMOVE -oDwT1BbzjM1, 1022920, 0 +file #0, 1022920, 0 [orig_h=192.168.72.14, orig_p=3254/tcp, resp_h=65.54.95.206, resp_p=80/tcp] total bytes: 1022920 source: HTTP FILE_NEW -oDwT1BbzjM1, 0, 0 +file #1, 0, 0 MIME_TYPE application/octet-stream FILE_TIMEOUT FILE_TIMEOUT FILE_STATE_REMOVE -oDwT1BbzjM1, 206024, 0 +file #1, 206024, 0 [orig_h=192.168.72.14, orig_p=3257/tcp, resp_h=65.54.95.14, resp_p=80/tcp] total bytes: 1022920 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.stop/get.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.stop/get.out index 6000f36f85..f7182027aa 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.stop/get.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.stop/get.out @@ -1,5 +1,5 @@ FILE_NEW -Cx92a0ym5R8, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER ^J0.26 | 201 MIME_TYPE diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.ftp/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.ftp/out index 2e1907c91c..4463db6958 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.ftp/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.ftp/out @@ -1,11 +1,11 @@ FILE_NEW -sidhzrR4IT8, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER The Nationa MIME_TYPE text/x-pascal FILE_STATE_REMOVE -sidhzrR4IT8, 16557, 0 +file #0, 16557, 0 [orig_h=141.142.228.5, orig_p=50737/tcp, resp_h=141.142.192.162, resp_p=38141/tcp] source: FTP_DATA MD5: 7192a8075196267203adb3dfaa5c908d diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/Cx92a0ym5R8-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/1-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/Cx92a0ym5R8-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/1-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/kg59rqyYxN-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/2-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/kg59rqyYxN-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/2-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get-gzip.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get-gzip.out index c425a7301f..2b46d02042 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get-gzip.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get-gzip.out @@ -1,11 +1,11 @@ FILE_NEW -kg59rqyYxN, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER {^J "origin MIME_TYPE text/plain FILE_STATE_REMOVE -kg59rqyYxN, 197, 0 +file #0, 197, 0 [orig_h=141.142.228.5, orig_p=50153/tcp, resp_h=54.243.118.187, resp_p=80/tcp] source: HTTP MD5: 5baba7eea57bc8a42a92c817ed566d72 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get.out index ebac8b624e..bb2f622969 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.get/get.out @@ -1,11 +1,11 @@ FILE_NEW -Cx92a0ym5R8, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER ^J0.26 | 201 MIME_TYPE text/plain FILE_STATE_REMOVE -Cx92a0ym5R8, 4705, 0 +file #0, 4705, 0 [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp] total bytes: 4705 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/TJdltRTxco1-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/1-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/TJdltRTxco1-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/1-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/QJO04kPdawk-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/2-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/QJO04kPdawk-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/2-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/dDH5dHdsRH4-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/3-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/dDH5dHdsRH4-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/3-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/TaUJcEIboHh-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/4-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/TaUJcEIboHh-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/4-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/out index fc34e97be2..4b6fa76c0c 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.multipart/out @@ -1,50 +1,50 @@ FILE_NEW -TJdltRTxco1, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER test^M^J MIME_TYPE text/plain FILE_STATE_REMOVE -TJdltRTxco1, 6, 0 +file #0, 6, 0 [orig_h=141.142.228.5, orig_p=57262/tcp, resp_h=54.243.88.146, resp_p=80/tcp] source: HTTP MD5: 9f06243abcb89c70e0c331c61d871fa7 SHA1: fde773a18bb29f5ed65e6f0a7aa717fd1fa485d4 SHA256: 837ccb607e312b170fac7383d7ccfd61fa5072793f19a25e75fbacb56539b86b FILE_NEW -QJO04kPdawk, 0, 0 +file #1, 0, 0 FILE_BOF_BUFFER test2^M^J MIME_TYPE text/plain FILE_STATE_REMOVE -QJO04kPdawk, 7, 0 +file #1, 7, 0 [orig_h=141.142.228.5, orig_p=57262/tcp, resp_h=54.243.88.146, resp_p=80/tcp] source: HTTP MD5: d68af81ef370b3873d50f09140068810 SHA1: 51a7b6f2d91f6a87822dc04560f2972bc14fc97e SHA256: de0edd0ac4a705aff70f34734e90a1d0a1d8b76abe4bb53f3ea934bc105b3b17 FILE_NEW -dDH5dHdsRH4, 0, 0 +file #2, 0, 0 FILE_BOF_BUFFER test3^M^J MIME_TYPE text/plain FILE_STATE_REMOVE -dDH5dHdsRH4, 7, 0 +file #2, 7, 0 [orig_h=141.142.228.5, orig_p=57262/tcp, resp_h=54.243.88.146, resp_p=80/tcp] source: HTTP MD5: 1a3d75d44753ad246f0bd333cdaf08b0 SHA1: 4f98809ab09272dfcc58266e3f23ae2393f70e76 SHA256: 018c67a2c30ed9977e1dddfe98cac542165dac355cf9764c91a362613e752933 FILE_NEW -TaUJcEIboHh, 0, 0 +file #3, 0, 0 FILE_BOF_BUFFER {^J "data": MIME_TYPE text/plain FILE_STATE_REMOVE -TaUJcEIboHh, 465, 0 +file #3, 465, 0 [orig_h=141.142.228.5, orig_p=57262/tcp, resp_h=54.243.88.146, resp_p=80/tcp] total bytes: 465 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.out index 02435aaca7..f8f2538e92 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.out @@ -1,10 +1,10 @@ FILE_NEW -7gZBKVUgy4l, 0, 0 +file #0, 0, 0 MIME_TYPE application/pdf FILE_OVER_NEW_CONNECTION FILE_STATE_REMOVE -7gZBKVUgy4l, 555523, 0 +file #0, 555523, 0 [orig_h=10.101.84.70, orig_p=10978/tcp, resp_h=129.174.93.161, resp_p=80/tcp] [orig_h=10.101.84.70, orig_p=10977/tcp, resp_h=129.174.93.161, resp_p=80/tcp] total bytes: 555523 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.size b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.size index 13d0c3c958..49f10feff1 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.size +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/a.size @@ -1 +1 @@ -555523 7gZBKVUgy4l-file0 +555523 file-0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.out index 8ea01332c8..b2a0cb66a2 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.out @@ -1,19 +1,19 @@ FILE_NEW -oDwT1BbzjM1, 0, 0 +file #0, 0, 0 MIME_TYPE application/x-dosexec FILE_STATE_REMOVE -oDwT1BbzjM1, 1022920, 0 +file #0, 1022920, 0 [orig_h=192.168.72.14, orig_p=3254/tcp, resp_h=65.54.95.206, resp_p=80/tcp] total bytes: 1022920 source: HTTP FILE_NEW -oDwT1BbzjM1, 0, 0 +file #1, 0, 0 MIME_TYPE application/octet-stream FILE_TIMEOUT FILE_STATE_REMOVE -oDwT1BbzjM1, 206024, 0 +file #1, 206024, 0 [orig_h=192.168.72.14, orig_p=3257/tcp, resp_h=65.54.95.14, resp_p=80/tcp] total bytes: 1022920 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.size b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.size index c1c1d71db7..5066aeab6d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.size +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/b.size @@ -1 +1 @@ -1022920 oDwT1BbzjM1-file0 +1022920 file-0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.out index 1ad4f52f36..7c5e9dfeca 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.out @@ -1,10 +1,10 @@ FILE_NEW -uHS14uhRKGe, 0, 0 +file #0, 0, 0 MIME_TYPE application/octet-stream FILE_OVER_NEW_CONNECTION FILE_STATE_REMOVE -uHS14uhRKGe, 498702, 0 +file #0, 498702, 0 [orig_h=10.45.179.94, orig_p=19950/tcp, resp_h=129.174.93.170, resp_p=80/tcp] [orig_h=10.45.179.94, orig_p=19953/tcp, resp_h=129.174.93.170, resp_p=80/tcp] total bytes: 498668 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.size b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.size index da0f4d480c..e38aaa1e25 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.size +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.partial-content/c.size @@ -1 +1 @@ -498668 uHS14uhRKGe-file0 +498668 file-0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/aFQKI8SPOL2-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/1-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/aFQKI8SPOL2-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/1-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/CCU3vUEr06l-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/2-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/CCU3vUEr06l-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/2-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/HCzA0dVwDPj-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/3-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/HCzA0dVwDPj-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/3-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/a1Zu1fteVEf-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/4-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/a1Zu1fteVEf-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/4-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/xXlF7wFdsR-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/5-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/xXlF7wFdsR-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/5-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/out index 67d7c5d555..02ac2f0a7e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.pipeline/out @@ -1,37 +1,37 @@ FILE_NEW -aFQKI8SPOL2, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER /*^J******** MIME_TYPE text/plain FILE_STATE_REMOVE -aFQKI8SPOL2, 2675, 0 +file #0, 2675, 0 [orig_h=192.168.1.104, orig_p=1673/tcp, resp_h=63.245.209.11, resp_p=80/tcp] source: HTTP MD5: b932c3310ce47e158d1a5a42e0b01279 SHA1: 0e42ae17eea9b074981bd3a34535ad3a22d02706 SHA256: 5b037a2c5e36f56e63a3012c73e46a04b27741d8ff8f8b62c832fb681fc60f42 FILE_NEW -CCU3vUEr06l, 0, 0 +file #1, 0, 0 FILE_BOF_BUFFER //-- Google MIME_TYPE text/plain FILE_STATE_REMOVE -CCU3vUEr06l, 21421, 0 +file #1, 21421, 0 [orig_h=192.168.1.104, orig_p=1673/tcp, resp_h=63.245.209.11, resp_p=80/tcp] source: HTTP MD5: e732f7bf1d7cb4eedcb1661697d7bc8c SHA1: 8f241117afaa8ca5f41dc059e66d75c283dcc983 SHA256: 6a509fd05aa7c8fa05080198894bb19e638554ffcee0e0b3d7bc8ff54afee1da FILE_NEW -HCzA0dVwDPj, 0, 0 +file #2, 0, 0 FILE_BOF_BUFFER GIF89a^D\0^D\0\xb3 MIME_TYPE image/gif FILE_STATE_REMOVE -HCzA0dVwDPj, 94, 0 +file #2, 94, 0 [orig_h=192.168.1.104, orig_p=1673/tcp, resp_h=63.245.209.11, resp_p=80/tcp] total bytes: 94 source: HTTP @@ -39,13 +39,13 @@ MD5: d903de7e30db1691d3130ba5eae6b9a7 SHA1: 81f5f056ce5e97d940854bb0c48017b45dd9f15e SHA256: 6fb22aa9d780ea63bd7a2e12b92b16fcbf1c4874f1d3e11309a5ba984433c315 FILE_NEW -a1Zu1fteVEf, 0, 0 +file #3, 0, 0 FILE_BOF_BUFFER \x89PNG^M^J^Z^J\0\0\0 MIME_TYPE image/png FILE_STATE_REMOVE -a1Zu1fteVEf, 2349, 0 +file #3, 2349, 0 [orig_h=192.168.1.104, orig_p=1673/tcp, resp_h=63.245.209.11, resp_p=80/tcp] total bytes: 2349 source: HTTP @@ -53,13 +53,13 @@ MD5: e0029eea80812e9a8e57b8d05d52938a SHA1: 560eab5a0177246827a94042dd103916d8765ac7 SHA256: e0b4500c1fd1d675da4137461cbe64d3c8489f4180d194e47683b20e7fb876f4 FILE_NEW -xXlF7wFdsR, 0, 0 +file #4, 0, 0 FILE_BOF_BUFFER \x89PNG^M^J^Z^J\0\0\0 MIME_TYPE image/png FILE_STATE_REMOVE -xXlF7wFdsR, 27579, 0 +file #4, 27579, 0 [orig_h=192.168.1.104, orig_p=1673/tcp, resp_h=63.245.209.11, resp_p=80/tcp] total bytes: 27579 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/v5HLI7MxPQh-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/1-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/v5HLI7MxPQh-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/1-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/PZS1XGHkIf1-file b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/2-file similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/PZS1XGHkIf1-file rename to testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/2-file diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/out index 0eecaf994a..3103ecb39e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.http.post/out @@ -1,11 +1,11 @@ FILE_NEW -v5HLI7MxPQh, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER hello world MIME_TYPE text/plain FILE_STATE_REMOVE -v5HLI7MxPQh, 11, 0 +file #0, 11, 0 [orig_h=141.142.228.5, orig_p=53595/tcp, resp_h=54.243.55.129, resp_p=80/tcp] total bytes: 11 source: HTTP @@ -13,13 +13,13 @@ MD5: 5eb63bbbe01eeed093cb22bb8f5acdc3 SHA1: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed SHA256: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 FILE_NEW -PZS1XGHkIf1, 0, 0 +file #1, 0, 0 FILE_BOF_BUFFER {^J "origin MIME_TYPE text/plain FILE_STATE_REMOVE -PZS1XGHkIf1, 366, 0 +file #1, 366, 0 [orig_h=141.142.228.5, orig_p=53595/tcp, resp_h=54.243.55.129, resp_p=80/tcp] total bytes: 366 source: HTTP diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.input.basic/bro..stdout b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.input.basic/bro..stdout index a7d837475f..afeb32b334 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.input.basic/bro..stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.input.basic/bro..stdout @@ -1,11 +1,11 @@ FILE_NEW -nYgPNGLrZf9, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER #separator MIME_TYPE text/plain FILE_STATE_REMOVE -nYgPNGLrZf9, 311, 0 +file #0, 311, 0 source: ../input.log MD5: bf4dfa6169b74146da5236e918743599 SHA1: 0a0f20de89c86d7bce1301af6548d6e9ae87b0f1 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.irc/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.irc/out index 03b0c9e932..36da7bdeed 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.irc/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.irc/out @@ -1,11 +1,11 @@ FILE_NEW -wqKMAamJVSb, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER PK^C^D^T\0\0\0^H\0\xae MIME_TYPE application/zip FILE_STATE_REMOVE -wqKMAamJVSb, 42208, 0 +file #0, 42208, 0 [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp] source: IRC_DATA MD5: 8c0803242f549c2780cb88b9a9215c65 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.logging/file_analysis.log b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.logging/file_analysis.log index ac2a836ba5..f95a70d50a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.logging/file_analysis.log +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.logging/file_analysis.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path file_analysis -#open 2013-05-21-16-47-14 +#open 2013-06-07-18-51-45 #fields id parent_id source is_orig last_active seen_bytes total_bytes missing_bytes overflow_bytes timeout_interval bof_buffer_size mime_type timedout conn_uids extracted_files md5 sha1 sha256 #types string string string bool time count count count count interval count string bool table[string] table[string] string string string -Cx92a0ym5R8 - HTTP F 1362692527.009775 4705 4705 0 0 120.000000 1024 text/plain F UWkUyAuUGXf Cx92a0ym5R8-file 397168fd09991a0e712254df7bc639ac 1dd7ac0398df6cbc0696445a91ec681facf4dc47 4e7c7ef0984119447e743e3ec77e1de52713e345cde03fe7df753a35849bed18 -#close 2013-05-21-16-47-14 +BYYd1GSNX5c - HTTP F 1362692527.009775 4705 4705 0 0 120.000000 1024 text/plain F UWkUyAuUGXf BYYd1GSNX5c-file 397168fd09991a0e712254df7bc639ac 1dd7ac0398df6cbc0696445a91ec681facf4dc47 4e7c7ef0984119447e743e3ec77e1de52713e345cde03fe7df753a35849bed18 +#close 2013-06-07-18-51-46 diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out index 83dc60f18e..ac4e6e50fa 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.smtp/out @@ -1,37 +1,37 @@ FILE_NEW -cwR7l6Zctxb, 0, 0 +file #0, 0, 0 FILE_BOF_BUFFER Hello^M^J^M^J ^M MIME_TYPE text/plain FILE_STATE_REMOVE -cwR7l6Zctxb, 79, 0 +file #0, 79, 0 [orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp] source: SMTP MD5: 92bca2e6cdcde73647125da7dccbdd07 SHA1: b7e497be8a9f5e2c4b6980fceb015360f98f4a13 SHA256: 785a8a044d1454ec88837108f443bbb30cc4f529393ffd57118261036bfe59f5 FILE_NEW -ZAOEQmRyxv1, 0, 0 +file #1, 0, 0 FILE_BOF_BUFFER , want_record=F, ev=line +{ +print outfile, A::description; +print outfile, A::tpe; +print outfile, A::s; +try = try + 1; +if (2 == try) +{ +Input::remove(input2); +close(outfile); +terminate(); +} + +}, config={ +[stdin] = hello^Jthere^A^B^C^D^E^A^B^Cyay +}] +Input::EVENT_NEW +hello +[source=cat |, reader=Input::READER_RAW, mode=Input::STREAM, name=input2, fields=, want_record=F, ev=line +{ +print outfile, A::description; +print outfile, A::tpe; +print outfile, A::s; +try = try + 1; +if (2 == try) +{ +Input::remove(input2); +close(outfile); +terminate(); +} + +}, config={ +[stdin] = hello^Jthere^A^B^C^D^E^A^B^Cyay +}] +Input::EVENT_NEW +there^A^B^C^D^E^A^B^Cyay diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestdin/test.txt b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestdin/test.txt new file mode 100644 index 0000000000..0205cd7c3a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestdin/test.txt @@ -0,0 +1,2 @@ +hello +thereyay \ No newline at end of file diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream/out new file mode 100644 index 0000000000..59a5f2c116 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream/out @@ -0,0 +1,153 @@ +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +sdfkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +DSF"DFKJ"SDFKLh304yrsdkfj@#(*U$34jfDJup3UF +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +q3r3057fdf +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +sdfs\d +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW + +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +dfsdf +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +sdf +[source=tail -f ../input.log |, reader=Input::READER_RAW, mode=Input::STREAM, name=input, fields=, want_record=F, ev=line +{ +print A::outfile, A::description; +print A::outfile, A::tpe; +print A::outfile, A::s; +A::try = A::try + 1; +if (8 == A::try) +{ +print A::outfile, done; +close(A::outfile); +Input::remove(input); +terminate(); +} + +}, config={ + +}] +Input::EVENT_NEW +3rw43wRRERLlL#RWERERERE. +done diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.long/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.long/out new file mode 100644 index 0000000000..fac8e79c0b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.long/out @@ -0,0 +1,2 @@ +Input::EVENT_NEW +8193 diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.rereadraw/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.rereadraw/out similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.input.rereadraw/out rename to testing/btest/Baseline/scripts.base.frameworks.input.raw.rereadraw/out diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.stderr/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.stderr/out new file mode 100644 index 0000000000..b7f857339d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.stderr/out @@ -0,0 +1,27 @@ +Input::EVENT_NEW +..: +F +Input::EVENT_NEW +bro +F +Input::EVENT_NEW +out +F +Input::EVENT_NEW +stderr.bro +F +Input::EVENT_NEW +stderr output contained nonexistant +T +Input::EVENT_NEW +stderr output contained nonexistant +T +Input::EVENT_NEW +stderr output contained nonexistant +T +done +End of Data event +input +Process finished event +input +Exit code != 0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.streamraw/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.streamraw/out similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.input.streamraw/out rename to testing/btest/Baseline/scripts.base.frameworks.input.raw.streamraw/out diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt index bcfad8fd80..e919233b79 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt @@ -34,7 +34,8 @@ - + + @@ -61,21 +62,22 @@ - + + # Extent, type='http' -ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file -1300475168.784020 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 1 GET bits.wikimedia.org /skins-1.5/monobook/main.css http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.916018 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.916183 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.918358 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.952307 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.952296 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/4/4a/Wiktionary-logo-en-35px.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.954820 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikiquote-logo.svg/35px-Wikiquote-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.962687 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 1 GET meta.wikimedia.org /images/wikimedia-button.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.975934 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikibooks-logo.svg/35px-Wikibooks-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.976436 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/d/df/Wikispecies-logo.svg/35px-Wikispecies-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475168.979264 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4c/Wikisource-logo.svg/35px-Wikisource-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475169.014619 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4a/Commons-logo.svg/35px-Commons-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475169.014593 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/9/91/Wikiversity-logo.svg/35px-Wikiversity-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 -1300475169.014927 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/7/75/Wikimedia_Community_Logo.svg/35px-Wikimedia_Community_Logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extracted_request_files extracted_response_files +1300475168.784020 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 1 GET bits.wikimedia.org /skins-1.5/monobook/main.css http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.916018 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.916183 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.918358 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.952307 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.952296 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/4/4a/Wiktionary-logo-en-35px.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.954820 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikiquote-logo.svg/35px-Wikiquote-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.962687 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 1 GET meta.wikimedia.org /images/wikimedia-button.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.975934 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikibooks-logo.svg/35px-Wikibooks-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.976436 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/d/df/Wikispecies-logo.svg/35px-Wikispecies-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.979264 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4c/Wikisource-logo.svg/35px-Wikisource-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014619 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4a/Commons-logo.svg/35px-Commons-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014593 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/9/91/Wikiversity-logo.svg/35px-Wikiversity-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014927 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/7/75/Wikimedia_Community_Logo.svg/35px-Wikimedia_Community_Logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/extractions b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/extractions new file mode 100644 index 0000000000..1933de9992 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/extractions @@ -0,0 +1,22 @@ +-rw-rw-r-- 1 600 netbsd 50158695 Feb 21 03:10 ls-lRA.gz +-rw-rw-r-- 1 600 netbsd 50158695 Feb 21 03:10 ls-lRA.gz +-rw-rw-r-- 1 root wheel 77 Aug 16 2009 robots.txt +-rw-rw-r-- 1 root wheel 77 Aug 16 2009 robots.txt +Disallow: *.bz2 +Disallow: *.bz2 +Disallow: *.gz +Disallow: *.gz +Disallow: *.tbz +Disallow: *.tbz +Disallow: *.tgz +Disallow: *.tgz +User-agent: * +User-agent: * +drwxr-x--x 3 root wheel 512 Aug 16 2009 etc +drwxr-x--x 3 root wheel 512 Aug 16 2009 etc +drwxr-xr-x 7 root wheel 512 Aug 20 2009 pub +drwxr-xr-x 7 root wheel 512 Aug 20 2009 pub +lrwxrwxr-x 1 root wheel 32 Aug 16 2009 .message -> pub/NetBSD/README.export-control +lrwxrwxr-x 1 root wheel 32 Aug 16 2009 .message -> pub/NetBSD/README.export-control +total 98028 +total 98028 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-BTsa70Ua9x7.dat b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-BTsa70Ua9x7.dat deleted file mode 100644 index a59965e6f6..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-BTsa70Ua9x7.dat +++ /dev/null @@ -1,5 +0,0 @@ -User-agent: * -Disallow: *.tgz -Disallow: *.gz -Disallow: *.tbz -Disallow: *.bz2 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-Rqjkzoroau4.dat b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-Rqjkzoroau4.dat deleted file mode 100644 index 8bd2e31300..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-Rqjkzoroau4.dat +++ /dev/null @@ -1,6 +0,0 @@ -total 98028 -lrwxrwxr-x 1 root wheel 32 Aug 16 2009 .message -> pub/NetBSD/README.export-control -drwxr-x--x 3 root wheel 512 Aug 16 2009 etc --rw-rw-r-- 1 600 netbsd 50158695 Feb 21 03:10 ls-lRA.gz -drwxr-xr-x 7 root wheel 512 Aug 20 2009 pub --rw-rw-r-- 1 root wheel 77 Aug 16 2009 robots.txt diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-VLQvJybrm38.dat b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-VLQvJybrm38.dat deleted file mode 100644 index 8bd2e31300..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-VLQvJybrm38.dat +++ /dev/null @@ -1,6 +0,0 @@ -total 98028 -lrwxrwxr-x 1 root wheel 32 Aug 16 2009 .message -> pub/NetBSD/README.export-control -drwxr-x--x 3 root wheel 512 Aug 16 2009 etc --rw-rw-r-- 1 600 netbsd 50158695 Feb 21 03:10 ls-lRA.gz -drwxr-xr-x 7 root wheel 512 Aug 20 2009 pub --rw-rw-r-- 1 root wheel 77 Aug 16 2009 robots.txt diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-zrfwSs9K1yk.dat b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-zrfwSs9K1yk.dat deleted file mode 100644 index a59965e6f6..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp-item-zrfwSs9K1yk.dat +++ /dev/null @@ -1,5 +0,0 @@ -User-agent: * -Disallow: *.tgz -Disallow: *.gz -Disallow: *.tbz -Disallow: *.bz2 diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp.log index c2b02ec4c8..e77f59dc44 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-extract/ftp.log @@ -3,19 +3,19 @@ #empty_field (empty) #unset_field - #path ftp -#open 2013-04-12-16-32-25 +#open 2013-06-07-18-57-22 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type file_size reply_code reply_msg tags data_channel.passive data_channel.orig_h data_channel.resp_h data_channel.resp_p extraction_file #types time string addr port addr port string string string string string count count string table[string] bool addr addr port string 1329843175.680248 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test PASV - - - 227 Entering Passive Mode (199,233,217,249,221,90) (empty) T 141.142.220.235 199.233.217.249 56666 - 1329843175.791528 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test LIST - - - 226 Transfer complete. (empty) - - - - - 1329843179.815947 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test PASV - - - 227 Entering Passive Mode (199,233,217,249,221,91) (empty) T 141.142.220.235 199.233.217.249 56667 - -1329843193.984222 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 - - - - - - - (empty) - - - - ftp-item-Rqjkzoroau4.dat -1329843193.984222 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 - - - - - - - (empty) - - - - ftp-item-BTsa70Ua9x7.dat +1329843193.984222 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 - - - - - - - (empty) - - - - ftp-item-pVhQhhFsB2b.dat +1329843193.984222 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 - - - - - - - (empty) - - - - ftp-item-fFCPkV1sEsc.dat 1329843179.926563 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test RETR ftp://199.233.217.249/./robots.txt text/plain 77 226 Transfer complete. (empty) - - - - - 1329843194.040188 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test PORT 141,142,220,235,131,46 - - 200 PORT command successful. (empty) F 199.233.217.249 141.142.220.235 33582 - 1329843194.095782 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test LIST - - - 226 Transfer complete. (empty) - - - - - 1329843197.672179 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test PORT 141,142,220,235,147,203 - - 200 PORT command successful. (empty) F 199.233.217.249 141.142.220.235 37835 - -1329843199.968212 nQcgTWjvg4c 199.233.217.249 61920 141.142.220.235 33582 - - - - - - - (empty) - - - - ftp-item-VLQvJybrm38.dat +1329843199.968212 nQcgTWjvg4c 199.233.217.249 61920 141.142.220.235 33582 - - - - - - - (empty) - - - - ftp-item-g3zS3MuJFh.dat 1329843197.727769 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 anonymous test RETR ftp://199.233.217.249/./robots.txt text/plain 77 226 Transfer complete. (empty) - - - - - -1329843200.079930 j4u32Pc5bif 199.233.217.249 61918 141.142.220.235 37835 - - - - - - - (empty) - - - - ftp-item-zrfwSs9K1yk.dat -#close 2013-04-12-16-32-25 +1329843200.079930 j4u32Pc5bif 199.233.217.249 61918 141.142.220.235 37835 - - - - - - - (empty) - - - - ftp-item-lMf4UWRkEO5.dat +#close 2013-06-07-18-57-22 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http-item-BFymS6bFgT3.dat b/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http-item.dat similarity index 100% rename from testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http-item-BFymS6bFgT3.dat rename to testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http-item.dat diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http.log index fa189fcc1f..53b80e5e9e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-extract-files/http.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path http -#open 2013-05-21-21-11-25 +#open 2013-06-07-19-04-27 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extracted_request_files extracted_response_files #types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string vector[string] vector[string] -1128727435.634189 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - - http-item-BFymS6bFgT3.dat -#close 2013-05-21-21-11-25 +1128727435.634189 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - - http-item-54zlJFqn0x6.dat +#close 2013-06-07-19-04-27 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-QJO04kPdawk.dat b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-QJO04kPdawk.dat deleted file mode 100644 index ac2a9e002d..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-QJO04kPdawk.dat +++ /dev/null @@ -1 +0,0 @@ -test2 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TJdltRTxco1.dat b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TJdltRTxco1.dat deleted file mode 100644 index 77356c3140..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TJdltRTxco1.dat +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TaUJcEIboHh.dat b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TaUJcEIboHh.dat deleted file mode 100644 index 8f0eb247e3..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-TaUJcEIboHh.dat +++ /dev/null @@ -1,21 +0,0 @@ -{ - "data": "", - "form": { - "example": "test", - "example2": "test2", - "example3": "test3" - }, - "origin": "141.142.228.5", - "json": null, - "url": "http://httpbin.org/post", - "args": {}, - "headers": { - "Content-Type": "multipart/form-data; boundary=----------------------------4ebf00fbcf09", - "User-Agent": "curl/7.30.0", - "Connection": "close", - "Accept": "*/*", - "Content-Length": "350", - "Host": "httpbin.org" - }, - "files": {} -} \ No newline at end of file diff --git a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-dDH5dHdsRH4.dat b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-dDH5dHdsRH4.dat deleted file mode 100644 index ae48ec8c20..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http-item-dDH5dHdsRH4.dat +++ /dev/null @@ -1 +0,0 @@ -test3 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http.log b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http.log index 7f71d93d9c..0bd15badef 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.multipart-extract/http.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path http -#open 2013-05-21-21-31-32 +#open 2013-06-07-19-57-15 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extracted_request_files extracted_response_files #types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string vector[string] vector[string] -1369159408.455878 UWkUyAuUGXf 141.142.228.5 57262 54.243.88.146 80 1 POST httpbin.org /post - curl/7.30.0 370 465 200 OK - - - (empty) - - - text/plain - http-item-TJdltRTxco1.dat,http-item-QJO04kPdawk.dat,http-item-dDH5dHdsRH4.dat http-item-TaUJcEIboHh.dat -#close 2013-05-21-21-31-32 +1369159408.455878 UWkUyAuUGXf 141.142.228.5 57262 54.243.88.146 80 1 POST httpbin.org /post - curl/7.30.0 370 465 200 OK - - - (empty) - - - text/plain - http-item-lcf92jVphSl.dat,http-item-z8gOS6arddh.dat,http-item-tBYz7eElzTb.dat http-item-GVJrSB2Vxk6.dat +#close 2013-06-07-19-57-15 diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc-dcc-item-wqKMAamJVSb.dat b/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc-dcc-item.dat similarity index 100% rename from testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc-dcc-item-wqKMAamJVSb.dat rename to testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc-dcc-item.dat diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc.log b/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc.log index 88a95d98f7..28ca448e05 100644 --- a/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc.log +++ b/testing/btest/Baseline/scripts.base.protocols.irc.dcc-extract/irc.log @@ -3,11 +3,11 @@ #empty_field (empty) #unset_field - #path irc -#open 2013-03-27-18-49-16 +#open 2013-06-07-19-08-42 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p nick user command value addl dcc_file_name dcc_file_size dcc_mime_type extraction_file #types time string addr port addr port string string string string string string count string string 1311189164.119437 UWkUyAuUGXf 192.168.1.77 57640 66.198.80.67 6667 - - NICK bloed - - - - - 1311189164.119437 UWkUyAuUGXf 192.168.1.77 57640 66.198.80.67 6667 bloed - USER sdkfje sdkfje Montreal.QC.CA.Undernet.org dkdkrwq - - - - 1311189174.474127 UWkUyAuUGXf 192.168.1.77 57640 66.198.80.67 6667 bloed sdkfje JOIN #easymovies (empty) - - - - -1311189316.326025 UWkUyAuUGXf 192.168.1.77 57640 66.198.80.67 6667 bloed sdkfje DCC #easymovies (empty) ladyvampress-default(2011-07-07)-OS.zip 42208 application/zip irc-dcc-item-wqKMAamJVSb.dat -#close 2013-03-27-18-49-16 +1311189316.326025 UWkUyAuUGXf 192.168.1.77 57640 66.198.80.67 6667 bloed sdkfje DCC #easymovies (empty) ladyvampress-default(2011-07-07)-OS.zip 42208 application/zip irc-dcc-item-A3OSdqG9zvk.dat +#close 2013-06-07-19-08-42 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-Ltd7QO7jEv3.dat b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/extractions similarity index 96% rename from testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-Ltd7QO7jEv3.dat rename to testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/extractions index 9eb3055735..45d776a8e9 100644 --- a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-Ltd7QO7jEv3.dat +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/extractions @@ -1,264 +1,277 @@ -Version 4.9.9.1 -* Many bug fixes -* Improved editor -Version 4.9.9.0 -* Support for latest Mingw compiler system builds -* Bug fixes -Version 4.9.8.9 -* New code tooltip display -* Improved Indent/Unindent and Remove Comment -* Improved automatic indent -* Added support for the "interface" keyword -* WebUpdate should now report installation problems from PackMan -* New splash screen and association icons -* Improved installer -* Many bug fixes -Version 4.9.8.7 -* Added support for GCC > 3.2 -* Debug variables are now resent during next debug session -* Watched Variables not in correct context are now kept and updated when it is needed -* Added new compiler/linker options: 20 - - Strip executable - - Generate instructions for a specific machine (i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + k6, k6-2, k6-3, athlon, athlon-tbird, athlon-4, athlon-xp, athlon-mp, winchip-c6, winchip2, k8, c3 and c3-2) - - Enable use of processor specific built-in functions (mmmx, sse, sse2, pni, 3dnow) -* "Default" button in Compiler Options is back -* Error messages parsing improved -* Bug fixes - -Version 4.9.8.5 -* Added the possibility to modify the value of a variable during debugging (right click on a watch variable and select "Modify value") -* During Dev-C++ First Time COnfiguration window, users can now choose between using or not class browser and code completion features. -* Many bug fixes - -Version 4.9.8.4 -* Added the possibility to specify an include directory for the code completion cache to be created at Dev-C++ first startup -* Improved code completion cache -* WebUpdate will now backup downloaded DevPaks in Dev-C++\Packages directory, and Dev-C++ executable in devcpp.exe.BACKUP -* Big speed up in function parameters listing while editing -* Bug fixes - -Version 4.9.8.3 -* On Dev-C++ first time configuration dialog, a code completion cache of all the standard 20 - include files can now be generated. -* Improved WebUpdate module -* Many bug fixes - -Version 4.9.8.2 -* New debug feature for DLLs: attach to a running process -* New project option: Use custom Makefile. 20 -* New WebUpdater module. -* Allow user to specify an alternate configuration file in Environment Options 20 + "windows.h", he gets all the WinAPI! If he adds "wx/wx.h", he gets all of + #included directly or indirectly)! + (available when right-clicking the class-browser (still can be overriden by using "-c" command line parameter). -* Lots of bug fixes. - -Version 4.9.8.1 -* When creating a DLL, the created static lib respects now the project-defined output directory - -Version 4.9.8.0 -* Changed position of compiler/linker parameters in Project Options. -* Improved help file -* Bug fixes - -Version 4.9.7.9 -* Resource errors are now reported in the Resource sheet -* Many bug fixes - -Version 4.9.7.8 -* Made whole bottom report control floating instead of only debug output. -* Many bug fixes - -Version 4.9.7.7 -* Printing settings are now saved -* New environment options : "watch variable under mouse" and "Report watch errors" -* Bug fixes - -Version 4.9.7.6 -* Debug variable browser -* Added possibility to include in a Template the Project's directories (include, libs and ressources) -* Changed tint of Class browser pictures colors to match the New Look style -* Bug fixes - -Version 4.9.7.5 -* Bug fixes - -Version 4.9.7.4 -* When compiling with debugging symbols, an extra definition is passed to the - compiler: -D__DEBUG__ -* Each project creates a _private.h file containing version - information definitions -* When compiling the current file only, no dependency checks are performed -* ~300% Speed-up in class parser -* Added "External programs" in Tools/Environment Options (for units "Open with") -* Added "Open with" in project units context menu -* Added "Classes" toolbar -* Fixed pre-compilation dependency checks to work correctly -* Added new file menu entry: Save Project As -* Bug-fix for double quotes in devcpp.cfg file read by vUpdate -* Other bug fixes - -Version 4.9.7.3 -* When adding debugging symbols on request, remove "-s" option from linker -* Compiling progress window -* Environment options : "Show progress window" and "Auto-close progress window" -* Bug fixes - -Version 4.9.7.2 -* Bug fixes - -Version 4.9.7.1 -* "Build priority" per-unit -* "Include file in linking process" per-unit -* New feature: compile current file only -* Separated C++ compiler options from C compiler options in Makefile (see bug report #654744) -* Separated C++ include dirs from C include dirs in Makefile (see bug report #654744) -* Necessary UI changes in Project Options -* Added display of project filename, project output and a summary of the project files in Project Options General tab. -* Fixed the "compiler-dirs-with-spaces" bug that crept-in in 4.9.7.0 -* Multi-select files in project-view (when "double-click to open" is configured in Environment Settings) -* Resource files are treated as ordinary files now -* Updates in "Project Options/Files" code -* MSVC import now creates the folders structure of the original VC project -* Bug fixes - -Version 4.9.7.0 -* Allow customizing of per-unit compile command in projects -* Added two new macros: and -* Added support for macros in the "default source code" (Tools/Editor Options/Code) -* Separated layout info from project file. It is now kept in a different file (the same filename as the project's but with extension ".layout"). If you - have your project under CVS control, you ''ll know why this had to happen... -* Compiler settings per-project -* Compiler set per-project -* Implemented new compiler settings framework -* "Compile as C++" per-unit -* "Include file in compilation process" per-unit -* Project version info (creates the relevant VERSIONINFO struct in the private - resource) -* Support XP Themes (creates the CommonControls 6.0 manifest file and includes - it in the private resource) -* Added CVS "login" and "logout" commands -* Project manager and debugging window (in Debug tab) can now be trasnformed into floating windows. -* Added "Add Library" button in Project Options -* Bug fixes - -Version 4.9.6.9 -* Implemented search in help files for the word at cursor (context sensitive help) -* Implemented "compiler sets" infrastructure to switch between different compilers easily (e.g. gcc-2.95 and gcc-3.2) -* Added "Files" tab in CVS form to allow selection of more than one file for - the requested CVS action + - Enable use of processor specific built-in functions (mmmx, sse, sse2, pni, 3dnow) + - Generate instructions for a specific machine (i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, 20 + - Strip executable + -c 20 -Version 4.9.6.8 -* support for DLL application hosting, for debugging and executing DLLs under Dev-C++. -* New class browser option: "Show inherited members" -* Added support for the '::' member access operator in code-completion -* Added *working* function arguments hint -* Added bracket highlighting. When the caret is on a bracket, that bracket and + Instead open the file in an already launched Dev-C++. + It used to be a checkbox, allowing only two states (on or off), but there is + The user can define this in the class browser's context menu under "View mode". + Well, it adds caching to code-completion. Depending on the cache size, + a third relevant option now: "Project classes" so it didn't fit the purpose... + and selecting "View mode"). + cause of many errors (although it should be fixed by now), we are giving the + class inheritance and visibility (shows items only from files + code-completion and the user has all the commands (belonging to the files + compiler: -D__DEBUG__ + displayed in the editor when the mouse moves over a word. Since this was the + have your project under CVS control, you ''ll know why this had to happen... + he added in the cache) at his fingertips. If, for example, the user adds + include files can now be generated. + information definitions + it in the private resource) its counterpart are highlighted -* Nested folders in project view - -Version 4.9.6.7 -* XP Theme support + resource) + the program may take a bit longer to start-up, but provides very fast + the requested CVS action + then we even get a stack trace in the bug report! + user the option to disable this feature. + wxWindows! You get the picture... +* "Build priority" per-unit +* "Compile as C++" per-unit +* "Default" button in Compiler Options is back +* "Include file in compilation process" per-unit +* "Include file in linking process" per-unit +* Added "Add Library" button in Project Options +* Added "Classes" toolbar +* Added "External programs" in Tools/Environment Options (for units "Open with") +* Added "Files" tab in CVS form to allow selection of more than one file for +* Added "Open with" in project units context menu +* Added "Tip of the day" system. +* Added *working* function arguments hint +* Added CVS "login" and "logout" commands * Added CVS commands "Add" and "Remove" +* Added ExceptionsAnalyzer. If the devcpp.map file is in the devcpp.exe directory +* Added bracket highlighting. When the caret is on a bracket, that bracket and * Added configuration option for "Templates Directory" in "Environment Options" -* Code-completion updates -* Bug fixes - -Version 4.9.6.6 -* Editor colors are initialized properly on Dev-C++ first-run +* Added display of project filename, project output and a summary of the project files in Project Options General tab. * Added doxygen-style comments in NewClass, NewMemberFunction and NewMemberVariable wizards * Added file's date/time stamp in File/Properties window -* Current windows listing in Window menu -* Bug fixes - -Version 4.9.6.5 -* CVS support -* Window list (in Window menu) -* bug fixes - -version 4.9.6.4 -* added ENTER key for opening file in project browser, DEL to delete from the project. -* bug fixes - -version 4.9.6.3 -* Bug fixes - -version 4.9.6.2 -* Bug fixes - -version 4.9.6.1 -* New "Abort compilation" button -* Bug fixes -* Now checks for vRoach existance when sending a crash report - -Version 4.9.5.5 -* New option in Editor Options: Show editor hints. User can disable the hints - displayed in the editor when the mouse moves over a word. Since this was the - cause of many errors (although it should be fixed by now), we are giving the - user the option to disable this feature. -* New option in Editor Options (code-completion): Use code-completion cache. - Well, it adds caching to code-completion. Depending on the cache size, - the program may take a bit longer to start-up, but provides very fast - code-completion and the user has all the commands (belonging to the files - he added in the cache) at his fingertips. If, for example, the user adds - "windows.h", he gets all the WinAPI! If he adds "wx/wx.h", he gets all of - wxWindows! You get the picture... -* Removed "Only show classes from current file" option in class browser settings. - It used to be a checkbox, allowing only two states (on or off), but there is - a third relevant option now: "Project classes" so it didn't fit the purpose... - The user can define this in the class browser's context menu under "View mode". -* Fixed the dreaded "Clock skew detected" compiler warning! -* Fixed many class browser bugs, including some that had to do with class folders. - -Version 4.9.5.4 -* Under NT, 2000 and XP, user application data directory will be used to store config files (i.e : C:\Documents and Settings\Username\Local Settings\Application Data) - -Version 4.9.5.3 -* Added ExceptionsAnalyzer. If the devcpp.map file is in the devcpp.exe directory - then we even get a stack trace in the bug report! * Added new WebUpdate module (inactive temporarily). * Added new code for code-completion caching of files (disabled - work in progress). - -Version 4.9.5.2 +* Added new compiler/linker options: 20 +* Added new file menu entry: Save Project As * Added new option in class-browser: Use colors - (available when right-clicking the class-browser - and selecting "View mode"). -* Dev-C++ now traps access violation of your programs (and of itself too ;) - -Version 4.9.5.1 -* Implemented the "File/Export/Project to HTML" function. -* Added "Tip of the day" system. -* When running a source file in explorer, don't spawn new instance. - Instead open the file in an already launched Dev-C++. -* Class-parser speed-up (50% to 85% improvement timed!!!) -* Many code-completion updates. Now takes into account context, - class inheritance and visibility (shows items only from files - #included directly or indirectly)! -* Caching of result set of code-completion for speed-up. -* New option "Execution/Parameters" (and "Debug/Parameters"). - -Version 4.9.5.0 (5.0 beta 5): -* CPU Window (still in development) -* ToDo list +* Added possibility to include in a Template the Project's directories (include, libs and ressources) +* Added support for GCC > 3.2 +* Added support for macros in the "default source code" (Tools/Editor Options/Code) +* Added support for the "interface" keyword +* Added support for the '::' member access operator in code-completion +* Added the possibility to modify the value of a variable during debugging (right click on a watch variable and select "Modify value") +* Added the possibility to specify an include directory for the code completion cache to be created at Dev-C++ first startup +* Added two new macros: and +* Allow customizing of per-unit compile command in projects +* Allow user to specify an alternate configuration file in Environment Options 20 * Backtrace in debugging -* Run to cursor +* Big speed up in function parameters listing while editing +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug fixes +* Bug-fix for double quotes in devcpp.cfg file read by vUpdate +* CPU Window (still in development) +* CVS support +* Caching of result set of code-completion for speed-up. +* Changed position of compiler/linker parameters in Project Options. +* Changed tint of Class browser pictures colors to match the New Look style +* Class-parser speed-up (50% to 85% improvement timed!!!) +* Code-completion updates +* Compiler set per-project +* Compiler settings per-project +* Compiling progress window +* Current windows listing in Window menu +* Debug variable browser +* Debug variables are now resent during next debug session +* Dev-C++ now traps access violation of your programs (and of itself too ;) +* During Dev-C++ First Time COnfiguration window, users can now choose between using or not class browser and code completion features. +* Each project creates a _private.h file containing version +* Editor colors are initialized properly on Dev-C++ first-run +* Environment options : "Show progress window" and "Auto-close progress window" +* Error messages parsing improved +* Fixed many class browser bugs, including some that had to do with class folders. +* Fixed pre-compilation dependency checks to work correctly +* Fixed the "compiler-dirs-with-spaces" bug that crept-in in 4.9.7.0 +* Fixed the dreaded "Clock skew detected" compiler warning! * Folders in Project and Class Browser -* Send custom commands to GDB -* Makefile can now be customized. -* Modified the behaviour of the -c param : 20 - -c -* Saving of custom syntax parameter group -* Possibility of changing compilers and tools filename. -* Many bug fixes - - -Version 4.9.4.1 (5.0 beta 4.1): - -* back to gcc 2.95.3 -* Profiling support -* new update/packages checker (vUpdate) +* Implemented "compiler sets" infrastructure to switch between different compilers easily (e.g. gcc-2.95 and gcc-3.2) +* Implemented new compiler settings framework +* Implemented search in help files for the word at cursor (context sensitive help) +* Implemented the "File/Export/Project to HTML" function. +* Improved Indent/Unindent and Remove Comment +* Improved WebUpdate module +* Improved automatic indent +* Improved code completion cache +* Improved editor +* Improved help file +* Improved installer +* Lots of bug fixes. * Lots of bugfixes - +* MSVC import now creates the folders structure of the original VC project +* Made whole bottom report control floating instead of only debug output. +* Makefile can now be customized. +* Many bug fixes +* Many bug fixes +* Many bug fixes +* Many bug fixes +* Many bug fixes +* Many bug fixes +* Many bug fixes +* Many code-completion updates. Now takes into account context, +* Modified the behaviour of the -c param : 20 +* Multi-select files in project-view (when "double-click to open" is configured in Environment Settings) +* Necessary UI changes in Project Options +* Nested folders in project view +* New "Abort compilation" button +* New WebUpdater module. +* New class browser option: "Show inherited members" +* New code tooltip display +* New debug feature for DLLs: attach to a running process +* New environment options : "watch variable under mouse" and "Report watch errors" +* New feature: compile current file only +* New option "Execution/Parameters" (and "Debug/Parameters"). +* New option in Editor Options (code-completion): Use code-completion cache. +* New option in Editor Options: Show editor hints. User can disable the hints +* New project option: Use custom Makefile. 20 +* New splash screen and association icons +* Now checks for vRoach existance when sending a crash report +* On Dev-C++ first time configuration dialog, a code completion cache of all the standard 20 +* Other bug fixes +* Possibility of changing compilers and tools filename. +* Printing settings are now saved +* Profiling support +* Project manager and debugging window (in Debug tab) can now be trasnformed into floating windows. +* Project version info (creates the relevant VERSIONINFO struct in the private +* Removed "Only show classes from current file" option in class browser settings. +* Resource errors are now reported in the Resource sheet +* Resource files are treated as ordinary files now +* Run to cursor +* Saving of custom syntax parameter group +* Send custom commands to GDB +* Separated C++ compiler options from C compiler options in Makefile (see bug report #654744) +* Separated C++ include dirs from C include dirs in Makefile (see bug report #654744) +* Separated layout info from project file. It is now kept in a different file +* Support XP Themes (creates the CommonControls 6.0 manifest file and includes +* Support for latest Mingw compiler system builds +* ToDo list +* Under NT, 2000 and XP, user application data directory will be used to store config files (i.e : C:\Documents and Settings\Username\Local Settings\Application Data) +* Updates in "Project Options/Files" code +* Watched Variables not in correct context are now kept and updated when it is needed +* WebUpdate should now report installation problems from PackMan +* WebUpdate will now backup downloaded DevPaks in Dev-C++\Packages directory, and Dev-C++ executable in devcpp.exe.BACKUP +* When adding debugging symbols on request, remove "-s" option from linker +* When compiling the current file only, no dependency checks are performed +* When compiling with debugging symbols, an extra definition is passed to the +* When creating a DLL, the created static lib respects now the project-defined output directory +* When running a source file in explorer, don't spawn new instance. +* Window list (in Window menu) +* XP Theme support +* added ENTER key for opening file in project browser, DEL to delete from the project. +* back to gcc 2.95.3 +* bug fixes +* bug fixes +* new update/packages checker (vUpdate) +* support for DLL application hosting, for debugging and executing DLLs under Dev-C++. +* ~300% Speed-up in class parser +Find the attachment +GPS +Hello +I send u smtp pcap file +Version 4.9.4.1 (5.0 beta 4.1): +Version 4.9.5.0 (5.0 beta 5): +Version 4.9.5.1 +Version 4.9.5.2 +Version 4.9.5.3 +Version 4.9.5.4 +Version 4.9.5.5 +Version 4.9.6.5 +Version 4.9.6.6 +Version 4.9.6.7 +Version 4.9.6.8 +Version 4.9.6.9 +Version 4.9.7.0 +Version 4.9.7.1 +Version 4.9.7.2 +Version 4.9.7.3 +Version 4.9.7.4 +Version 4.9.7.5 +Version 4.9.7.6 +Version 4.9.7.7 +Version 4.9.7.8 +Version 4.9.7.9 +Version 4.9.8.0 +Version 4.9.8.1 +Version 4.9.8.2 +Version 4.9.8.3 +Version 4.9.8.4 +Version 4.9.8.5 +Version 4.9.8.7 +Version 4.9.8.9 +Version 4.9.9.0 +Version 4.9.9.1 +version 4.9.6.1 +version 4.9.6.2 +version 4.9.6.3 +version 4.9.6.4 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/filecount b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/filecount new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/filecount @@ -0,0 +1 @@ +2 diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-cwR7l6Zctxb.dat b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-cwR7l6Zctxb.dat deleted file mode 100644 index f4dd7d22f4..0000000000 --- a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp-entity-cwR7l6Zctxb.dat +++ /dev/null @@ -1,13 +0,0 @@ -Hello - - - -I send u smtp pcap file - -Find the attachment - - - -GPS - - diff --git a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp_entities.log b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp_entities.log index 9724dd2168..865694e8a2 100644 --- a/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp_entities.log +++ b/testing/btest/Baseline/scripts.base.protocols.smtp.mime-extract/smtp_entities.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path smtp_entities -#open 2013-03-26-20-43-14 +#open 2013-06-07-19-32-56 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth filename content_len mime_type md5 extraction_file excerpt #types time string addr port addr port count string count string string string string -1254722770.692743 arKYeMETxOg 10.10.1.4 1470 74.53.140.153 25 1 - 79 text/plain - smtp-entity-cwR7l6Zctxb.dat (empty) +1254722770.692743 arKYeMETxOg 10.10.1.4 1470 74.53.140.153 25 1 - 79 text/plain - smtp-entity-mR3f2AAKo11.dat (empty) 1254722770.692743 arKYeMETxOg 10.10.1.4 1470 74.53.140.153 25 1 - 1918 text/html - - (empty) -1254722770.692804 arKYeMETxOg 10.10.1.4 1470 74.53.140.153 25 1 NEWS.txt 10823 text/plain - smtp-entity-Ltd7QO7jEv3.dat (empty) -#close 2013-03-26-20-43-14 +1254722770.692804 arKYeMETxOg 10.10.1.4 1470 74.53.140.153 25 1 NEWS.txt 10823 text/plain - smtp-entity-ZNp0KBSLByc.dat (empty) +#close 2013-06-07-19-32-56 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log new file mode 100644 index 0000000000..375c033c38 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2013-07-02-18-46-17 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id subject issuer_subject not_valid_before not_valid_after last_alert client_subject client_issuer_subject +#types time string addr port addr port string string string string string string time time string string string +1357328848.549370 UWkUyAuUGXf 10.0.0.80 56637 68.233.76.12 443 TLSv12 TLS_RSA_WITH_RC4_128_MD5 - - CN=*.taleo.net,OU=Comodo PremiumSSL Wildcard,OU=Web,O=Taleo Inc.,street=4140 Dublin Boulevard,street=Suite 400,L=Dublin,ST=CA,postalCode=94568,C=US CN=COMODO High-Assurance Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB 1304467200.000000 1467676799.000000 - - - +#close 2013-07-02-18-46-17 diff --git a/testing/btest/Baseline/scripts.base.protocols.syslog.trace/syslog.log b/testing/btest/Baseline/scripts.base.protocols.syslog.trace/syslog.log new file mode 100644 index 0000000000..df53ef42f6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.syslog.trace/syslog.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path syslog +#open 2013-04-05-20-06-27 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto facility severity message +#types time string addr port addr port enum string string string +1365191811.424495 UWkUyAuUGXf 127.0.0.1 57067 127.0.0.1 514 udp LOCAL0 NOTICE Apr 5 12:56:51 robin: Hello, syslog!\x00 +#close 2013-04-05-20-06-27 diff --git a/testing/btest/Baseline/signatures.dpd/dpd-ipv4.out b/testing/btest/Baseline/signatures.dpd/dpd-ipv4.out index abb41f330c..d9f5126aab 100644 --- a/testing/btest/Baseline/signatures.dpd/dpd-ipv4.out +++ b/testing/btest/Baseline/signatures.dpd/dpd-ipv4.out @@ -1,6 +1,4 @@ -dpd_config, { - -} +|Analyzer::all_registered_ports()|, 0 signature_match [orig_h=141.142.220.235, orig_p=50003/tcp, resp_h=199.233.217.249, resp_p=21/tcp] - matched my_ftp_client ftp_reply 199.233.217.249:21 - 220 ftp.NetBSD.org FTP server (NetBSD-ftpd 20100320) ready. ftp_request 141.142.220.235:50003 - USER anonymous diff --git a/testing/btest/Baseline/signatures.dpd/dpd-ipv6.out b/testing/btest/Baseline/signatures.dpd/dpd-ipv6.out index a2227ee890..f26ff25291 100644 --- a/testing/btest/Baseline/signatures.dpd/dpd-ipv6.out +++ b/testing/btest/Baseline/signatures.dpd/dpd-ipv6.out @@ -1,6 +1,4 @@ -dpd_config, { - -} +|Analyzer::all_registered_ports()|, 0 signature_match [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49185/tcp, resp_h=2001:470:4867:99::21, resp_p=21/tcp] - matched my_ftp_client ftp_reply [2001:470:4867:99::21]:21 - 220 ftp.NetBSD.org FTP server (NetBSD-ftpd 20100320) ready. ftp_request [2001:470:1f11:81f:c999:d94:aa7c:2e3e]:49185 - USER anonymous diff --git a/testing/btest/Baseline/signatures.dpd/nosig-ipv4.out b/testing/btest/Baseline/signatures.dpd/nosig-ipv4.out index 55566505d8..1b3be8e060 100644 --- a/testing/btest/Baseline/signatures.dpd/nosig-ipv4.out +++ b/testing/btest/Baseline/signatures.dpd/nosig-ipv4.out @@ -1,3 +1 @@ -dpd_config, { - -} +|Analyzer::all_registered_ports()|, 0 diff --git a/testing/btest/Baseline/signatures.dpd/nosig-ipv6.out b/testing/btest/Baseline/signatures.dpd/nosig-ipv6.out index 55566505d8..1b3be8e060 100644 --- a/testing/btest/Baseline/signatures.dpd/nosig-ipv6.out +++ b/testing/btest/Baseline/signatures.dpd/nosig-ipv6.out @@ -1,3 +1 @@ -dpd_config, { - -} +|Analyzer::all_registered_ports()|, 0 diff --git a/testing/btest/Traces/ssh-on-port-80.trace b/testing/btest/Traces/ssh-on-port-80.trace new file mode 100644 index 0000000000..6c0ae22e30 Binary files /dev/null and b/testing/btest/Traces/ssh-on-port-80.trace differ diff --git a/testing/btest/Traces/syslog-single-udp.trace b/testing/btest/Traces/syslog-single-udp.trace new file mode 100644 index 0000000000..9e1505a38a Binary files /dev/null and b/testing/btest/Traces/syslog-single-udp.trace differ diff --git a/testing/btest/Traces/tls1.2.trace b/testing/btest/Traces/tls1.2.trace new file mode 100644 index 0000000000..87d50c277c Binary files /dev/null and b/testing/btest/Traces/tls1.2.trace differ diff --git a/testing/btest/bifs/analyzer_name.bro b/testing/btest/bifs/analyzer_name.bro index 9297d2ca27..266d1c159f 100644 --- a/testing/btest/bifs/analyzer_name.bro +++ b/testing/btest/bifs/analyzer_name.bro @@ -4,6 +4,6 @@ event bro_init() { - local a = 1; - print analyzer_name(a); + local a = Analyzer::ANALYZER_PIA_TCP; + print Analyzer::name(a); } diff --git a/testing/btest/btest.cfg b/testing/btest/btest.cfg index 4f888f710b..4a13833094 100644 --- a/testing/btest/btest.cfg +++ b/testing/btest/btest.cfg @@ -12,7 +12,7 @@ BRO_SEED_FILE=%(testbase)s/random.seed TZ=UTC LC_ALL=C BTEST_PATH=%(testbase)s/../../aux/btest -PATH=%(testbase)s/../../build/src:%(testbase)s/../scripts:%(testbase)s/../../aux/btest:%(default_path)s +PATH=%(testbase)s/../../build/src:%(testbase)s/../scripts:%(testbase)s/../../aux/btest:%(testbase)s/../../aux/bro-aux/bro-cut:%(default_path)s TRACES=%(testbase)s/Traces SCRIPTS=%(testbase)s/../scripts DIST=%(testbase)s/../.. diff --git a/testing/btest/core/tunnels/gtp/non_recursive.test b/testing/btest/core/tunnels/gtp/non_recursive.test index d44bfce79d..0b03c0d6ae 100644 --- a/testing/btest/core/tunnels/gtp/non_recursive.test +++ b/testing/btest/core/tunnels/gtp/non_recursive.test @@ -5,7 +5,7 @@ # So if we find inside a GTP tunnel anohter IP/UDP packet with port 2152, # it is just a UDP packet, but not another GTP tunnel. -event protocol_violation(c: connection, atype: count, aid: count, reason: string) +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) { print "protocol_violation", c$id, reason; } diff --git a/testing/btest/core/tunnels/teredo-known-services.test b/testing/btest/core/tunnels/teredo-known-services.test index 862930758f..d03ef2ab71 100644 --- a/testing/btest/core/tunnels/teredo-known-services.test +++ b/testing/btest/core/tunnels/teredo-known-services.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -b -r $TRACES/tunnels/false-teredo.pcap base/frameworks/dpd protocols/conn/known-services Tunnel::delay_teredo_confirmation=T "Site::local_nets+={192.168.1.0/24}" +# @TEST-EXEC: bro -r $TRACES/tunnels/false-teredo.pcap base/frameworks/dpd protocols/conn/known-services Tunnel::delay_teredo_confirmation=T "Site::local_nets+={192.168.1.0/24}" # @TEST-EXEC: test ! -e known_services.log # @TEST-EXEC: bro -b -r $TRACES/tunnels/false-teredo.pcap base/frameworks/dpd protocols/conn/known-services Tunnel::delay_teredo_confirmation=F "Site::local_nets+={192.168.1.0/24}" # @TEST-EXEC: btest-diff known_services.log diff --git a/testing/btest/language/at-dir.bro b/testing/btest/language/at-dir.bro new file mode 100644 index 0000000000..b826e3a5da --- /dev/null +++ b/testing/btest/language/at-dir.bro @@ -0,0 +1,10 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out +# @TEST-EXEC: bro -b ./pathtest.bro >out2 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out2 + +print @DIR; + +@TEST-START-FILE pathtest.bro +print @DIR; +@TEST-END-FILE diff --git a/testing/btest/language/at-filename.bro b/testing/btest/language/at-filename.bro new file mode 100644 index 0000000000..83e4e968f3 --- /dev/null +++ b/testing/btest/language/at-filename.bro @@ -0,0 +1,4 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +print @FILENAME; diff --git a/testing/btest/language/table-redef.bro b/testing/btest/language/table-redef.bro new file mode 100644 index 0000000000..290610499f --- /dev/null +++ b/testing/btest/language/table-redef.bro @@ -0,0 +1,26 @@ +# @TEST-EXEC: bro -b %INPUT > out +# @TEST-EXEC: btest-diff out + +const foo: table[string] of double &redef; + +# full (re)initialization +redef foo = { ["nope"] = 37.0 }; + +# full (re)initialization, discards "nope" index +redef foo = { ["abc"] = 42.0 }; + +# add elements +redef foo += { ["def"] = -42.0, ["ghi"] = 7.0 }; + +# remove elements from LHS based on indices shared with RHS +redef foo -= { ["ghi"] = 0.0 }; + +# RHS can be a table value +redef foo += table(["cool"] = 5.0, ["neat"] = 1.0); + +# Redef at a single index is allowed, same as += when RHS has overlapping index +redef foo["cool"] = 28.0; +redef foo["abc"] = 8.0; +redef foo += { ["def"] = 99.0 }; + +print foo; diff --git a/testing/btest/scripts/base/frameworks/analyzer/disable-analyzer.bro b/testing/btest/scripts/base/frameworks/analyzer/disable-analyzer.bro new file mode 100644 index 0000000000..749236f6c6 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/analyzer/disable-analyzer.bro @@ -0,0 +1,14 @@ +# +# @TEST-EXEC: bro -r ${TRACES}/var-services-std-ports.trace %INPUT +# @TEST-EXEC: cat conn.log | bro-cut service | grep -vq dns +# @TEST-EXEC: cat conn.log | bro-cut service | grep -vq ssh +# + +redef Analyzer::disabled_analyzers += { Analyzer::ANALYZER_SSH }; + +event bro_init() + { + Analyzer::disable_analyzer(Analyzer::ANALYZER_DNS); + } + + diff --git a/testing/btest/scripts/base/frameworks/analyzer/enable-analyzer.bro b/testing/btest/scripts/base/frameworks/analyzer/enable-analyzer.bro new file mode 100644 index 0000000000..bcee794768 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/analyzer/enable-analyzer.bro @@ -0,0 +1,13 @@ +# +# @TEST-EXEC: bro -r ${TRACES}/var-services-std-ports.trace %INPUT +# @TEST-EXEC: cat conn.log | bro-cut service | grep -q dns +# + +redef Analyzer::disable_all = T; + +event bro_init() + { + Analyzer::enable_analyzer(Analyzer::ANALYZER_DNS); + } + + diff --git a/testing/btest/scripts/base/frameworks/analyzer/register-for-port.bro b/testing/btest/scripts/base/frameworks/analyzer/register-for-port.bro new file mode 100644 index 0000000000..f3b54177e2 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/analyzer/register-for-port.bro @@ -0,0 +1,13 @@ +# +# @TEST-EXEC: bro -r ${TRACES}/ssh-on-port-80.trace %INPUT dpd_buffer_size=0; +# @TEST-EXEC: cat conn.log | bro-cut service | grep -q ssh +# +# @TEST-EXEC: bro -r ${TRACES}/ssh-on-port-80.trace dpd_buffer_size=0; +# @TEST-EXEC: cat conn.log | bro-cut service | grep -vq ssh + +event bro_init() + { + Analyzer::register_for_port(Analyzer::ANALYZER_SSH, 80/tcp); + } + + diff --git a/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro b/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro new file mode 100644 index 0000000000..114ea73673 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro @@ -0,0 +1,36 @@ +# +# @TEST-EXEC: bro -b -r ${TRACES}/rotation.trace %INPUT | sort >output +# @TEST-EXEC: btest-diff output + +global x = 0; + +event new_connection(c: connection) + { + # Make sure expiration executes. + Analyzer::schedule_analyzer(1.2.3.4, 1.2.3.4, 8/tcp, Analyzer::ANALYZER_MODBUS, 100hrs); + + if ( x > 0 ) + return; + + x = 1; + + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_SSH, 100hrs); + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_HTTP, 100hrs); + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_DNS, 100hrs); + Analyzer::schedule_analyzer(0.0.0.0, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_FTP, 100hrs); + + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 7/tcp, Analyzer::ANALYZER_SSH, 1sec); + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 8/tcp, Analyzer::ANALYZER_HTTP, 1sec); + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 8/tcp, Analyzer::ANALYZER_DNS, 100hrs); + Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 9/tcp, Analyzer::ANALYZER_FTP, 1sec); + } + +event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) + { + print "APPLIED:", network_time(), c$id, a; + } + + + + + diff --git a/testing/btest/scripts/base/frameworks/file-analysis/http/get.bro b/testing/btest/scripts/base/frameworks/file-analysis/http/get.bro index 317a6276e6..f7f4a0395b 100644 --- a/testing/btest/scripts/base/frameworks/file-analysis/http/get.bro +++ b/testing/btest/scripts/base/frameworks/file-analysis/http/get.bro @@ -1,13 +1,15 @@ -# @TEST-EXEC: bro -r $TRACES/http/get.trace $SCRIPTS/file-analysis-test.bro %INPUT >get.out -# @TEST-EXEC: bro -r $TRACES/http/get-gzip.trace $SCRIPTS/file-analysis-test.bro %INPUT >get-gzip.out +# @TEST-EXEC: bro -r $TRACES/http/get.trace $SCRIPTS/file-analysis-test.bro %INPUT c=1 >get.out +# @TEST-EXEC: bro -r $TRACES/http/get-gzip.trace $SCRIPTS/file-analysis-test.bro %INPUT c=2 >get-gzip.out # @TEST-EXEC: btest-diff get.out # @TEST-EXEC: btest-diff get-gzip.out -# @TEST-EXEC: btest-diff Cx92a0ym5R8-file -# @TEST-EXEC: btest-diff kg59rqyYxN-file +# @TEST-EXEC: btest-diff 1-file +# @TEST-EXEC: btest-diff 2-file redef test_file_analysis_source = "HTTP"; +global c = 0 &redef; + redef test_get_file_name = function(f: fa_file): string { - return fmt("%s-file", f$id); + return fmt("%d-file", c); }; diff --git a/testing/btest/scripts/base/frameworks/file-analysis/http/multipart.bro b/testing/btest/scripts/base/frameworks/file-analysis/http/multipart.bro index e5200df42e..57fe2348c2 100644 --- a/testing/btest/scripts/base/frameworks/file-analysis/http/multipart.bro +++ b/testing/btest/scripts/base/frameworks/file-analysis/http/multipart.bro @@ -1,13 +1,16 @@ # @TEST-EXEC: bro -r $TRACES/http/multipart.trace $SCRIPTS/file-analysis-test.bro %INPUT >out # @TEST-EXEC: btest-diff out -# @TEST-EXEC: btest-diff TJdltRTxco1-file -# @TEST-EXEC: btest-diff QJO04kPdawk-file -# @TEST-EXEC: btest-diff dDH5dHdsRH4-file -# @TEST-EXEC: btest-diff TaUJcEIboHh-file +# @TEST-EXEC: btest-diff 1-file +# @TEST-EXEC: btest-diff 2-file +# @TEST-EXEC: btest-diff 3-file +# @TEST-EXEC: btest-diff 4-file redef test_file_analysis_source = "HTTP"; +global cnt: count = 0; + redef test_get_file_name = function(f: fa_file): string { - return fmt("%s-file", f$id); + ++cnt; + return fmt("%d-file", cnt); }; diff --git a/testing/btest/scripts/base/frameworks/file-analysis/http/partial-content.bro b/testing/btest/scripts/base/frameworks/file-analysis/http/partial-content.bro index 1f3d54daea..93443f0ca8 100644 --- a/testing/btest/scripts/base/frameworks/file-analysis/http/partial-content.bro +++ b/testing/btest/scripts/base/frameworks/file-analysis/http/partial-content.bro @@ -1,16 +1,16 @@ # @TEST-EXEC: bro -r $TRACES/http/206_example_a.pcap $SCRIPTS/file-analysis-test.bro %INPUT >a.out # @TEST-EXEC: btest-diff a.out -# @TEST-EXEC: wc -c 7gZBKVUgy4l-file0 | sed 's/^[ \t]* //g' >a.size +# @TEST-EXEC: wc -c file-0 | sed 's/^[ \t]* //g' >a.size # @TEST-EXEC: btest-diff a.size # @TEST-EXEC: bro -r $TRACES/http/206_example_b.pcap $SCRIPTS/file-analysis-test.bro %INPUT >b.out # @TEST-EXEC: btest-diff b.out -# @TEST-EXEC: wc -c oDwT1BbzjM1-file0 | sed 's/^[ \t]* //g' >b.size +# @TEST-EXEC: wc -c file-0 | sed 's/^[ \t]* //g' >b.size # @TEST-EXEC: btest-diff b.size # @TEST-EXEC: bro -r $TRACES/http/206_example_c.pcap $SCRIPTS/file-analysis-test.bro %INPUT >c.out # @TEST-EXEC: btest-diff c.out -# @TEST-EXEC: wc -c uHS14uhRKGe-file0 | sed 's/^[ \t]* //g' >c.size +# @TEST-EXEC: wc -c file-0 | sed 's/^[ \t]* //g' >c.size # @TEST-EXEC: btest-diff c.size global cnt: count = 0; @@ -19,7 +19,7 @@ redef test_file_analysis_source = "HTTP"; redef test_get_file_name = function(f: fa_file): string { - local rval: string = fmt("%s-file%d", f$id, cnt); + local rval: string = fmt("file-%d", cnt); ++cnt; return rval; }; diff --git a/testing/btest/scripts/base/frameworks/file-analysis/http/pipeline.bro b/testing/btest/scripts/base/frameworks/file-analysis/http/pipeline.bro index 5135b03786..36743a8bad 100644 --- a/testing/btest/scripts/base/frameworks/file-analysis/http/pipeline.bro +++ b/testing/btest/scripts/base/frameworks/file-analysis/http/pipeline.bro @@ -1,14 +1,16 @@ # @TEST-EXEC: bro -r $TRACES/http/pipelined-requests.trace $SCRIPTS/file-analysis-test.bro %INPUT >out # @TEST-EXEC: btest-diff out -# @TEST-EXEC: btest-diff aFQKI8SPOL2-file -# @TEST-EXEC: btest-diff CCU3vUEr06l-file -# @TEST-EXEC: btest-diff HCzA0dVwDPj-file -# @TEST-EXEC: btest-diff a1Zu1fteVEf-file -# @TEST-EXEC: btest-diff xXlF7wFdsR-file +# @TEST-EXEC: btest-diff 1-file +# @TEST-EXEC: btest-diff 2-file +# @TEST-EXEC: btest-diff 3-file +# @TEST-EXEC: btest-diff 4-file +# @TEST-EXEC: btest-diff 5-file redef test_file_analysis_source = "HTTP"; +global c = 0; + redef test_get_file_name = function(f: fa_file): string { - return fmt("%s-file", f$id); + return fmt("%d-file", ++c); }; diff --git a/testing/btest/scripts/base/frameworks/file-analysis/http/post.bro b/testing/btest/scripts/base/frameworks/file-analysis/http/post.bro index 5db64c9ff0..79ac1cb5c1 100644 --- a/testing/btest/scripts/base/frameworks/file-analysis/http/post.bro +++ b/testing/btest/scripts/base/frameworks/file-analysis/http/post.bro @@ -1,11 +1,13 @@ # @TEST-EXEC: bro -r $TRACES/http/post.trace $SCRIPTS/file-analysis-test.bro %INPUT >out # @TEST-EXEC: btest-diff out -# @TEST-EXEC: btest-diff v5HLI7MxPQh-file -# @TEST-EXEC: btest-diff PZS1XGHkIf1-file +# @TEST-EXEC: btest-diff 1-file +# @TEST-EXEC: btest-diff 2-file redef test_file_analysis_source = "HTTP"; +global c = 0; + redef test_get_file_name = function(f: fa_file): string { - return fmt("%s-file", f$id); + return fmt("%d-file", ++c); }; diff --git a/testing/btest/scripts/base/frameworks/input/raw.bro b/testing/btest/scripts/base/frameworks/input/raw/basic.bro similarity index 100% rename from testing/btest/scripts/base/frameworks/input/raw.bro rename to testing/btest/scripts/base/frameworks/input/raw/basic.bro diff --git a/testing/btest/scripts/base/frameworks/input/executeraw.bro b/testing/btest/scripts/base/frameworks/input/raw/execute.bro similarity index 100% rename from testing/btest/scripts/base/frameworks/input/executeraw.bro rename to testing/btest/scripts/base/frameworks/input/raw/execute.bro diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro b/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro new file mode 100644 index 0000000000..729844e4b4 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro @@ -0,0 +1,44 @@ +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-wait -k 5 +# @TEST-EXEC: btest-diff test.txt +# @TEST-EXEC: btest-diff out + +redef exit_only_after_terminate = T; +@load base/frameworks/communication # let network-time run. otherwise there are no heartbeats... + +global outfile: file; +global try: count; + +module A; + +type Val: record { + s: string; +}; + +event line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print outfile, description; + print outfile, tpe; + print outfile, s; + try = try + 1; + if ( try == 2 ) + { + Input::remove("input2"); + close(outfile); + terminate(); + } + } + +event bro_init() + { + local config_strings: table[string] of string = { + ["stdin"] = "hello\nthere\1\2\3\4\5\1\2\3yay" + #["stdin"] = "yay" + }; + + try = 0; + outfile = open("../out"); + Input::add_event([$source="cat > ../test.txt |", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F, $config=config_strings]); + Input::remove("input"); + Input::add_event([$source="cat |", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input2", $fields=Val, $ev=line, $want_record=F, $config=config_strings]); + } diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestream.bro b/testing/btest/scripts/base/frameworks/input/raw/executestream.bro new file mode 100644 index 0000000000..ead33018dc --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestream.bro @@ -0,0 +1,61 @@ +# @TEST-EXEC: cp input1.log input.log +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: sleep 3 +# @TEST-EXEC: cat input2.log >> input.log +# @TEST-EXEC: sleep 3 +# @TEST-EXEC: cat input3.log >> input.log +# @TEST-EXEC: btest-bg-wait -k 5 +# @TEST-EXEC: btest-diff out + +redef exit_only_after_terminate = T; + +@TEST-START-FILE input1.log +sdfkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF +@TEST-END-FILE + +@TEST-START-FILE input2.log +DSF"DFKJ"SDFKLh304yrsdkfj@#(*U$34jfDJup3UF +q3r3057fdf +@TEST-END-FILE + +@TEST-START-FILE input3.log +sdfs\d + +dfsdf +sdf +3rw43wRRERLlL#RWERERERE. +@TEST-END-FILE + +@load base/frameworks/communication # let network-time run + +module A; + +type Val: record { + s: string; +}; + +global try: count; +global outfile: file; + +event line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print outfile, description; + print outfile, tpe; + print outfile, s; + + try = try + 1; + if ( try == 8 ) + { + print outfile, "done"; + close(outfile); + Input::remove("input"); + terminate(); + } + } + +event bro_init() + { + outfile = open("../out"); + try = 0; + Input::add_event([$source="tail -f ../input.log |", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F]); + } diff --git a/testing/btest/scripts/base/frameworks/input/raw/long.bro b/testing/btest/scripts/base/frameworks/input/raw/long.bro new file mode 100644 index 0000000000..ac07639f77 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/long.bro @@ -0,0 +1,37 @@ +# @TEST-EXEC: dd if=/dev/zero of=input.log bs=8193 count=1 +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-wait -k 5 +# @TEST-EXEC: btest-diff out +# +# this test should be longer than one block-size. to test behavior of input-reader if it has to re-allocate stuff. + +redef exit_only_after_terminate = T; + +global outfile: file; +global try: count; + +module A; + +type Val: record { + s: string; +}; + +event line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print outfile, tpe; + print outfile, |s|; + try = try + 1; + if ( try == 1 ) + { + close(outfile); + terminate(); + } + } + +event bro_init() + { + try = 0; + outfile = open("../out"); + Input::add_event([$source="../input.log", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F]); + Input::remove("input"); + } diff --git a/testing/btest/scripts/base/frameworks/input/rereadraw.bro b/testing/btest/scripts/base/frameworks/input/raw/rereadraw.bro similarity index 100% rename from testing/btest/scripts/base/frameworks/input/rereadraw.bro rename to testing/btest/scripts/base/frameworks/input/raw/rereadraw.bro diff --git a/testing/btest/scripts/base/frameworks/input/raw/stderr.bro b/testing/btest/scripts/base/frameworks/input/raw/stderr.bro new file mode 100644 index 0000000000..e84ed048cd --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/stderr.bro @@ -0,0 +1,66 @@ +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-wait -k 5 +# @TEST-EXEC: btest-diff out + +redef exit_only_after_terminate = T; + +type Val: record { + s: string; + is_stderr: bool; +}; + +global try: count; +global outfile: file; + +event line(description: Input::EventDescription, tpe: Input::Event, s: string, is_stderr: bool) + { + print outfile, tpe; + if ( is_stderr ) + { + # work around localized error messages. and if some localization does not include the filename... well... that would be bad :) + if ( strstr(s, "nonexistant") > 0 ) + { + print outfile, "stderr output contained nonexistant"; + } + } + else + { + print outfile, s; + } + print outfile, is_stderr; + + try = try + 1; + if ( try == 7 ) + { + print outfile, "done"; + Input::remove("input"); + } + } + +event Input::end_of_data(name: string, source:string) + { + print outfile, "End of Data event"; + print outfile, name; + terminate(); # due to the current design, end_of_data will be called after process_finshed and all line events. + # this could potentially change + } + +event InputRaw::process_finished(name: string, source:string, exit_code:count, signal_exit:bool) + { + print outfile, "Process finished event"; + print outfile, name; + if ( exit_code != 0 ) + print outfile, "Exit code != 0"; + } + +event bro_init() + { + + local config_strings: table[string] of string = { + ["read_stderr"] = "1" + }; + + outfile = open("../out"); + try = 0; + Input::add_event([$source="ls .. ../nonexistant ../nonexistant2 ../nonexistant3 |", $reader=Input::READER_RAW, $name="input", $fields=Val, $ev=line, $want_record=F, $config=config_strings]); + } diff --git a/testing/btest/scripts/base/frameworks/input/streamraw.bro b/testing/btest/scripts/base/frameworks/input/raw/streamraw.bro similarity index 100% rename from testing/btest/scripts/base/frameworks/input/streamraw.bro rename to testing/btest/scripts/base/frameworks/input/raw/streamraw.bro diff --git a/testing/btest/scripts/base/protocols/ftp/ftp-extract.bro b/testing/btest/scripts/base/protocols/ftp/ftp-extract.bro index 785d4009b9..8cbacdbf6f 100644 --- a/testing/btest/scripts/base/protocols/ftp/ftp-extract.bro +++ b/testing/btest/scripts/base/protocols/ftp/ftp-extract.bro @@ -3,10 +3,8 @@ # @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT # @TEST-EXEC: btest-diff conn.log # @TEST-EXEC: btest-diff ftp.log -# @TEST-EXEC: btest-diff ftp-item-Rqjkzoroau4.dat -# @TEST-EXEC: btest-diff ftp-item-BTsa70Ua9x7.dat -# @TEST-EXEC: btest-diff ftp-item-VLQvJybrm38.dat -# @TEST-EXEC: btest-diff ftp-item-zrfwSs9K1yk.dat +# @TEST-EXEC: cat ftp-item-*.dat | sort > extractions +# @TEST-EXEC: btest-diff extractions redef FTP::logged_commands += {"LIST"}; redef FTP::extract_file_types=/.*/; diff --git a/testing/btest/scripts/base/protocols/http/http-extract-files.bro b/testing/btest/scripts/base/protocols/http/http-extract-files.bro index 2eca91a9b2..6156009821 100644 --- a/testing/btest/scripts/base/protocols/http/http-extract-files.bro +++ b/testing/btest/scripts/base/protocols/http/http-extract-files.bro @@ -1,5 +1,6 @@ # @TEST-EXEC: bro -C -r $TRACES/web.trace %INPUT # @TEST-EXEC: btest-diff http.log -# @TEST-EXEC: btest-diff http-item-BFymS6bFgT3.dat +# @TEST-EXEC: mv http-item-*.dat http-item.dat +# @TEST-EXEC: btest-diff http-item.dat redef HTTP::extract_file_types += /text\/html/; diff --git a/testing/btest/scripts/base/protocols/http/multipart-extract.bro b/testing/btest/scripts/base/protocols/http/multipart-extract.bro index 5d72cb349f..c2789750a3 100644 --- a/testing/btest/scripts/base/protocols/http/multipart-extract.bro +++ b/testing/btest/scripts/base/protocols/http/multipart-extract.bro @@ -1,8 +1,5 @@ # @TEST-EXEC: bro -C -r $TRACES/http/multipart.trace %INPUT # @TEST-EXEC: btest-diff http.log -# @TEST-EXEC: btest-diff http-item-TJdltRTxco1.dat -# @TEST-EXEC: btest-diff http-item-QJO04kPdawk.dat -# @TEST-EXEC: btest-diff http-item-dDH5dHdsRH4.dat -# @TEST-EXEC: btest-diff http-item-TaUJcEIboHh.dat +# @TEST-EXEC: cat http-item-* | sort > extractions redef HTTP::extract_file_types += /.*/; diff --git a/testing/btest/scripts/base/protocols/irc/dcc-extract.test b/testing/btest/scripts/base/protocols/irc/dcc-extract.test index a82b2338e9..cbfc6890da 100644 --- a/testing/btest/scripts/base/protocols/irc/dcc-extract.test +++ b/testing/btest/scripts/base/protocols/irc/dcc-extract.test @@ -3,8 +3,9 @@ # @TEST-EXEC: bro -r $TRACES/irc-dcc-send.trace %INPUT # @TEST-EXEC: btest-diff irc.log -# @TEST-EXEC: btest-diff irc-dcc-item-wqKMAamJVSb.dat +# @TEST-EXEC: mv irc-dcc-item-*.dat irc-dcc-item.dat +# @TEST-EXEC: btest-diff irc-dcc-item.dat # @TEST-EXEC: bro -r $TRACES/irc-dcc-send.trace %INPUT IRC::extraction_prefix="test" -# @TEST-EXEC: test -e test-wqKMAamJVSb.dat +# @TEST-EXEC: test -e test-*.dat redef IRC::extract_file_types=/.*/; diff --git a/testing/btest/scripts/base/protocols/modbus/events.bro b/testing/btest/scripts/base/protocols/modbus/events.bro index 46d9c0ce7a..a5fe26be9c 100644 --- a/testing/btest/scripts/base/protocols/modbus/events.bro +++ b/testing/btest/scripts/base/protocols/modbus/events.bro @@ -2,7 +2,7 @@ # @TEST-EXEC: bro -r $TRACES/modbus/modbus.trace %INPUT | sort | uniq -c | sed 's/^ *//g' >output # @TEST-EXEC: btest-diff output # @TEST-EXEC: cat output | awk '{print $2}' | grep "^modbus_" | sort | uniq | wc -l >covered -# @TEST-EXEC: cat ${DIST}/src/event.bif | grep "^event modbus_" | wc -l >total +# @TEST-EXEC: cat ${DIST}/src/analyzer/protocol/modbus/events.bif | grep "^event modbus_" | wc -l >total # @TEST-EXEC: echo `cat covered` of `cat total` events triggered by trace >coverage # @TEST-EXEC: btest-diff coverage diff --git a/testing/btest/scripts/base/protocols/smtp/mime-extract.test b/testing/btest/scripts/base/protocols/smtp/mime-extract.test index 9a0f9c9150..0caa5d530c 100644 --- a/testing/btest/scripts/base/protocols/smtp/mime-extract.test +++ b/testing/btest/scripts/base/protocols/smtp/mime-extract.test @@ -1,10 +1,10 @@ # @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT # @TEST-EXEC: btest-diff smtp_entities.log -# @TEST-EXEC: btest-diff smtp-entity-cwR7l6Zctxb.dat -# @TEST-EXEC: btest-diff smtp-entity-Ltd7QO7jEv3.dat +# @TEST-EXEC: cat smtp-entity-*.dat | sort > extractions +# @TEST-EXEC: btest-diff extractions # @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT SMTP::extraction_prefix="test" -# @TEST-EXEC: test -e test-cwR7l6Zctxb.dat -# @TEST-EXEC: test -e test-Ltd7QO7jEv3.dat +# @TEST-EXEC: cnt=0 && for f in test-*.dat; do cnt=$((cnt+1)); done && echo $cnt >filecount +# @TEST-EXEC: btest-diff filecount @load base/protocols/smtp diff --git a/testing/btest/scripts/base/protocols/ssl/tls-1.2.test b/testing/btest/scripts/base/protocols/ssl/tls-1.2.test new file mode 100644 index 0000000000..25b9083587 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/tls-1.2.test @@ -0,0 +1,2 @@ +# @TEST-EXEC: bro -r $TRACES/tls1.2.trace %INPUT +# @TEST-EXEC: btest-diff ssl.log diff --git a/testing/btest/scripts/base/protocols/syslog/trace.test b/testing/btest/scripts/base/protocols/syslog/trace.test new file mode 100644 index 0000000000..78b681a9d8 --- /dev/null +++ b/testing/btest/scripts/base/protocols/syslog/trace.test @@ -0,0 +1,4 @@ +# @TEST-EXEC: bro -r $TRACES/syslog-single-udp.trace %INPUT +# @TEST-EXEC: btest-diff syslog.log + +@load base/protocols/syslog diff --git a/testing/btest/signatures/dpd.bro b/testing/btest/signatures/dpd.bro index a302603bd2..39f1b01294 100644 --- a/testing/btest/signatures/dpd.bro +++ b/testing/btest/signatures/dpd.bro @@ -33,7 +33,7 @@ signature my_ftp_server { event bro_init() { # no analyzer attached to any port by default, depends entirely on sigs - print "dpd_config", dpd_config; + print "|Analyzer::all_registered_ports()|", |Analyzer::all_registered_ports()|; } event signature_match(state: signature_state, msg: string, data: string) diff --git a/testing/scripts/diff-canonifier-external b/testing/scripts/diff-canonifier-external index 04ef699538..f4356154e4 100755 --- a/testing/scripts/diff-canonifier-external +++ b/testing/scripts/diff-canonifier-external @@ -4,6 +4,7 @@ `dirname $0`/diff-remove-timestamps \ | `dirname $0`/diff-remove-uids \ + | `dirname $0`/diff-remove-file-ids \ | `dirname $0`/diff-remove-x509-names \ | `dirname $0`/diff-canon-notice-policy \ | `dirname $0`/diff-sort diff --git a/testing/scripts/diff-remove-file-ids b/testing/scripts/diff-remove-file-ids new file mode 100755 index 0000000000..f54177d8ba --- /dev/null +++ b/testing/scripts/diff-remove-file-ids @@ -0,0 +1,33 @@ +#! /usr/bin/awk -f +# +# A diff canonifier that removes all file IDs from file_analysis.log + +BEGIN { + FS="\t"; + OFS="\t"; + process = 0; + } + +$1 == "#path" && $2 == "file_analysis" { + process = 1; + } + +process && column1 > 0 && column2 > 0 { + $column1 = "XXXXXXXXXXX"; + $column2 = "XXXXXXXXXXX"; + } + +/^#/ { + for ( i = 0; i < NF; ++i ) { + if ( $i == "id" ) + column1 = i - 1; + + if ( $i == "parent_id" ) + column2 = i - 1; + } + } + +{ print } + + + diff --git a/testing/scripts/file-analysis-test.bro b/testing/scripts/file-analysis-test.bro index cb1027d8f1..9df640c893 100644 --- a/testing/scripts/file-analysis-test.bro +++ b/testing/scripts/file-analysis-test.bro @@ -8,23 +8,35 @@ global test_get_file_name: function(f: fa_file): string = global test_print_file_data_events: bool = F &redef; +global file_count: count = 0; + +global file_map: table[string] of count; + +function canonical_file_name(f: fa_file): string + { + return fmt("file #%d", file_map[f$id]); + } + event file_chunk(f: fa_file, data: string, off: count) { if ( test_print_file_data_events ) - print "file_chunk", f$id, |data|, off, data; + print "file_chunk", canonical_file_name(f), |data|, off, data; } event file_stream(f: fa_file, data: string) { if ( test_print_file_data_events ) - print "file_stream", f$id, |data|, data; + print "file_stream", canonical_file_name(f), |data|, data; } event file_new(f: fa_file) { print "FILE_NEW"; - print f$id, f$seen_bytes, f$missing_bytes; + file_map[f$id] = file_count; + ++file_count; + + print canonical_file_name(f), f$seen_bytes, f$missing_bytes; if ( test_file_analysis_source == "" || f$source == test_file_analysis_source ) @@ -72,7 +84,7 @@ event file_gap(f: fa_file, offset: count, len: count) event file_state_remove(f: fa_file) { print "FILE_STATE_REMOVE"; - print f$id, f$seen_bytes, f$missing_bytes; + print canonical_file_name(f), f$seen_bytes, f$missing_bytes; if ( f?$conns ) for ( cid in f$conns ) print cid;