mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/master' into topic/bernhard/input-update
This commit is contained in:
commit
b39bffd9aa
494 changed files with 15196 additions and 12261 deletions
45
CHANGES
45
CHANGES
|
@ -1,4 +1,49 @@
|
|||
|
||||
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)
|
||||
|
||||
* Allow named vector/set/table/record constructors. Addresses #983.
|
||||
(Jon Siwek)
|
||||
|
||||
* Adding Makefile target test-all that also runs the BroControl test
|
||||
suite. (Robin Sommer)
|
||||
|
||||
2.1-664 | 2013-05-28 21:37:46 -0700
|
||||
|
||||
* Dangling pointer fix. Addresses #1004. (Jon Siwek)
|
||||
|
||||
2.1-659 | 2013-05-24 17:24:18 -0700
|
||||
|
||||
* Fix broken/missing documentation. (Jon Siwek)
|
||||
|
|
3
Makefile
3
Makefile
|
@ -63,6 +63,9 @@ distclean:
|
|||
test:
|
||||
@( cd testing && make )
|
||||
|
||||
test-all: test
|
||||
test -d aux/broctl && ( cd aux/broctl && make test )
|
||||
|
||||
configured:
|
||||
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
||||
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
||||
|
|
17
NEWS
17
NEWS
|
@ -46,6 +46,19 @@ New Functionality
|
|||
have changed their signatures to work with opaques types rather
|
||||
than global state as it was before.
|
||||
|
||||
- The scripting language now supports a constructing sets, tables,
|
||||
vectors, and records by name:
|
||||
|
||||
type MyRecordType: record {
|
||||
c: count;
|
||||
s: string &optional;
|
||||
};
|
||||
|
||||
global r: MyRecordType = record($c = 7);
|
||||
|
||||
type MySet: set[MyRec];
|
||||
global s = MySet([$c=1], [$c=2]);
|
||||
|
||||
- Strings now support the subscript operator to extract individual
|
||||
characters and substrings (e.g., s[4], s[1,5]). The index expression
|
||||
can take up to two indices for the start and end index of the
|
||||
|
@ -55,6 +68,10 @@ 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
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.1-659
|
||||
2.1-741
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f86a3169b8d49189d264cbc1a7507260cd9ff51d
|
||||
Subproject commit c39bd478b9d0ecd05b1b83aa9d09a7887893977c
|
|
@ -1 +1 @@
|
|||
Subproject commit cfaf4eea788bdac4ebfe9e46e3de2cd74b0bc068
|
||||
Subproject commit a9942558c7d3dfd80148b8aaded64c82ade3d117
|
|
@ -1 +1 @@
|
|||
Subproject commit 8955807b0f4151f5f6aca2e68d353b9b341d9f86
|
||||
Subproject commit 889f9c65944ceac20ad9230efc39d33e6e1221c3
|
|
@ -1 +1 @@
|
|||
Subproject commit 4d0b75afadd6a3c6507e8ca18cb1913faa93a3b0
|
||||
Subproject commit cf7a1ca56f2b20f777542d912de0a9c8fdb0655d
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
broPolicies=${BRO_SCRIPT_SOURCE_PATH}:${BRO_SCRIPT_SOURCE_PATH}/policy:${BRO_SCRIPT_SOURCE_PATH}/site
|
||||
|
||||
broGenPolicies=${CMAKE_BINARY_DIR}/src
|
||||
broGenPolicies=${CMAKE_BINARY_DIR}/scripts
|
||||
|
||||
installedPolicies=${BRO_SCRIPT_INSTALL_PATH}:${BRO_SCRIPT_INSTALL_PATH}/site
|
||||
|
||||
|
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
|||
Subproject commit e1a7fd00a0a66d6831a239fe84f5fcfaa54e2c35
|
||||
Subproject commit 0187b33a29d5ec824f940feff60dc5d8c2fe314f
|
|
@ -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,7 +64,7 @@ macro(REST_TARGET srcDir broInput)
|
|||
|
||||
if (NOT "${ARGN}" STREQUAL "")
|
||||
set(group ${ARGN})
|
||||
elseif (${extension} STREQUAL ".bif.bro")
|
||||
elseif (${broInput} MATCHES "\\.bif\\.bro$")
|
||||
set(group bifs)
|
||||
elseif (relDstDir)
|
||||
set(group ${relDstDir}/index)
|
||||
|
|
|
@ -16,15 +16,63 @@ 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_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 +194,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)
|
||||
|
|
|
@ -246,6 +246,31 @@ The Bro scripting language supports the following built-in types.
|
|||
[5] = "five",
|
||||
};
|
||||
|
||||
A table constructor (equivalent to above example) can also be used
|
||||
to create a table:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
global t2: table[count] of string = table(
|
||||
[11] = "eleven",
|
||||
[5] = "five"
|
||||
);
|
||||
|
||||
Table constructors can also be explicitly named by a type, which is
|
||||
useful for when a more complex index type could otherwise be
|
||||
ambiguous:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
type MyRec: record {
|
||||
a: count &optional;
|
||||
b: count;
|
||||
};
|
||||
|
||||
type MyTable: table[MyRec] of string;
|
||||
|
||||
global t3 = MyTable([[$b=5]] = "b5", [[$b=7]] = "b7");
|
||||
|
||||
Accessing table elements if provided by enclosing values within square
|
||||
brackets (``[]``), for example:
|
||||
|
||||
|
@ -308,6 +333,28 @@ The Bro scripting language supports the following built-in types.
|
|||
The types are explicitly shown in the example above, but they could
|
||||
have been left to type inference.
|
||||
|
||||
A set constructor (equivalent to above example) can also be used to
|
||||
create a set:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
global s3: set[port] = set(21/tcp, 23/tcp, 80/tcp, 443/tcp);
|
||||
|
||||
Set constructors can also be explicitly named by a type, which is
|
||||
useful for when a more complex index type could otherwise be
|
||||
ambiguous:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
type MyRec: record {
|
||||
a: count &optional;
|
||||
b: count;
|
||||
};
|
||||
|
||||
type MySet: set[MyRec];
|
||||
|
||||
global s4 = MySet([$b=1], [$b=2]);
|
||||
|
||||
Set membership is tested with ``in``:
|
||||
|
||||
.. code:: bro
|
||||
|
@ -349,6 +396,21 @@ The Bro scripting language supports the following built-in types.
|
|||
|
||||
global v: vector of string = vector("one", "two", "three");
|
||||
|
||||
Vector constructors can also be explicitly named by a type, which
|
||||
is useful for when a more complex yield type could otherwise be
|
||||
ambiguous.
|
||||
|
||||
.. code:: bro
|
||||
|
||||
type MyRec: record {
|
||||
a: count &optional;
|
||||
b: count;
|
||||
};
|
||||
|
||||
type MyVec: vector of MyRec;
|
||||
|
||||
global v2 = MyVec([$b=1], [$b=2], [$b=3]);
|
||||
|
||||
Adding an element to a vector involves accessing/assigning it:
|
||||
|
||||
.. code:: bro
|
||||
|
@ -402,6 +464,19 @@ The Bro scripting language supports the following built-in types.
|
|||
if ( r?$s )
|
||||
...
|
||||
|
||||
Records can also be created using a constructor syntax:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
global r2: MyRecordType = record($c = 7);
|
||||
|
||||
And the constructor can be explicitly named by type, too, which
|
||||
is arguably more readable code:
|
||||
|
||||
.. code:: bro
|
||||
|
||||
global r3 = MyRecordType($c = 42);
|
||||
|
||||
.. bro:type:: opaque
|
||||
|
||||
A data type whose actual representation/implementation is
|
||||
|
|
|
@ -54,11 +54,11 @@ global example_ports = {
|
|||
443/tcp, 562/tcp,
|
||||
} &redef;
|
||||
|
||||
# redefinitions of "dpd_config" are self-documenting and
|
||||
# go into the generated doc's "Port Analysis" section
|
||||
redef dpd_config += {
|
||||
[ANALYZER_SSL] = [$ports = example_ports]
|
||||
};
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, example_ports);
|
||||
}
|
||||
|
||||
# redefinitions of "Notice::Type" are self-documenting, but
|
||||
# more information can be supplied in two different ways
|
||||
|
|
|
@ -67,12 +67,12 @@ sourcedir=${thisdir}/../..
|
|||
|
||||
echo "$statictext" > $outfile
|
||||
|
||||
bifs=`( cd ${sourcedir}/src && find . -name \*\.bif | sort )`
|
||||
bifs=`( cd ${sourcedir}/build/scripts/base && find . -name \*\.bif.bro | sort )`
|
||||
|
||||
for file in $bifs
|
||||
do
|
||||
f=${file:2}.bro
|
||||
echo "rest_target(\${CMAKE_BINARY_DIR}/src base/$f)" >> $outfile
|
||||
f=${file:2}
|
||||
echo "rest_target(\${CMAKE_BINARY_DIR}/scripts base/$f)" >> $outfile
|
||||
done
|
||||
|
||||
scriptfiles=`( cd ${sourcedir}/scripts && find . -name \*\.bro | sort )`
|
||||
|
|
1
scripts/base/frameworks/analyzer/__load__.bro
Normal file
1
scripts/base/frameworks/analyzer/__load__.bro
Normal file
|
@ -0,0 +1 @@
|
|||
@load ./main
|
181
scripts/base/frameworks/analyzer/main.bro
Normal file
181
scripts/base/frameworks/analyzer/main.bro
Normal file
|
@ -0,0 +1,181 @@
|
|||
##! 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.
|
||||
##!
|
||||
##! .. todo: ``The ANALYZER_*`` are in fact not yet documented, we need to
|
||||
##! add that to Broxygen.
|
||||
module Analyzer;
|
||||
|
||||
export {
|
||||
## If true, all available analyzers are initially disabled at startup. One
|
||||
## can then selectively enable them with
|
||||
## :bro:id:`Analyzer::enable_analyzer`.
|
||||
global disable_all = F &redef;
|
||||
|
||||
## Enables an analyzer. Once enabled, the analyzer may be used for analysis
|
||||
## of future connections as decided by Bro's dynamic protocol detection.
|
||||
##
|
||||
## tag: The tag of the analyzer to enable.
|
||||
##
|
||||
## Returns: True if the analyzer was successfully enabled.
|
||||
global enable_analyzer: function(tag: Analyzer::Tag) : bool;
|
||||
|
||||
## Disables an analyzer. Once disabled, the analyzer will not be used
|
||||
## further for analysis of future connections.
|
||||
##
|
||||
## tag: The tag of the analyzer to disable.
|
||||
##
|
||||
## Returns: True if the analyzer was successfully disabled.
|
||||
global disable_analyzer: function(tag: Analyzer::Tag) : bool;
|
||||
|
||||
## Registers a set of well-known ports for an analyzer. If a future
|
||||
## connection on one of these ports is seen, the analyzer will be
|
||||
## automatically assigned to parsing it. The function *adds* to all ports
|
||||
## already registered, it doesn't replace them.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## ports: The set of well-known ports to associate with the analyzer.
|
||||
##
|
||||
## Returns: True if the ports were sucessfully registered.
|
||||
global register_for_ports: function(tag: Analyzer::Tag, ports: set[port]) : bool;
|
||||
|
||||
## Registers an individual well-known port for an analyzer. If a future
|
||||
## connection on this port is seen, the analyzer will be automatically
|
||||
## assigned to parsing it. The function *adds* to all ports already
|
||||
## registered, it doesn't replace them.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## p: The well-known port to associate with the analyzer.
|
||||
##
|
||||
## Returns: True if the port was sucessfully registered.
|
||||
global register_for_port: function(tag: Analyzer::Tag, p: port) : bool;
|
||||
|
||||
## Returns a set of all well-known ports currently registered for a
|
||||
## specific analyzer.
|
||||
##
|
||||
## tag: The tag of the analyzer.
|
||||
##
|
||||
## Returns: The set of ports.
|
||||
global registered_ports: function(tag: Analyzer::Tag) : set[port];
|
||||
|
||||
## Returns a table of all ports-to-analyzer mappings currently registered.
|
||||
##
|
||||
## Returns: A table mapping each analyzer to the set of ports
|
||||
## registered for it.
|
||||
global all_registered_ports: function() : table[Analyzer::Tag] of set[port];
|
||||
|
||||
## Translates an analyzer type to a string with the analyzer's name.
|
||||
##
|
||||
## tag: The analyzer tag.
|
||||
##
|
||||
## Returns: The analyzer name corresponding to the tag.
|
||||
global name: function(tag: Analyzer::Tag) : string;
|
||||
|
||||
## Schedules an analyzer for a future connection originating from a given IP
|
||||
## address and port.
|
||||
##
|
||||
## orig: The IP address originating a connection in the future.
|
||||
## 0.0.0.0 can be used as a wildcard to match any originator address.
|
||||
##
|
||||
## resp: The IP address responding to a connection from *orig*.
|
||||
##
|
||||
## resp_p: The destination port at *resp*.
|
||||
##
|
||||
## analyzer: The analyzer ID.
|
||||
##
|
||||
## tout: A timeout interval after which the scheduling request will be
|
||||
## discarded if the connection has not yet been seen.
|
||||
##
|
||||
## Returns: True if succesful.
|
||||
global schedule_analyzer: function(orig: addr, resp: addr, resp_p: port,
|
||||
analyzer: Analyzer::Tag, tout: interval) : bool;
|
||||
|
||||
## A set of analyzers to disable by default at startup. The default set
|
||||
## contains legacy analyzers that are no longer supported.
|
||||
global disabled_analyzers: set[Analyzer::Tag] = {
|
||||
ANALYZER_INTERCONN,
|
||||
ANALYZER_STEPPINGSTONE,
|
||||
ANALYZER_BACKDOOR,
|
||||
ANALYZER_TCPSTATS,
|
||||
} &redef;
|
||||
}
|
||||
|
||||
@load base/bif/analyzer.bif
|
||||
|
||||
global ports: table[Analyzer::Tag] of set[port];
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
if ( disable_all )
|
||||
__disable_all_analyzers();
|
||||
|
||||
for ( a in disabled_analyzers )
|
||||
disable_analyzer(a);
|
||||
}
|
||||
|
||||
function enable_analyzer(tag: Analyzer::Tag) : bool
|
||||
{
|
||||
return __enable_analyzer(tag);
|
||||
}
|
||||
|
||||
function disable_analyzer(tag: Analyzer::Tag) : bool
|
||||
{
|
||||
return __disable_analyzer(tag);
|
||||
}
|
||||
|
||||
function register_for_ports(tag: Analyzer::Tag, ports: set[port]) : bool
|
||||
{
|
||||
local rc = T;
|
||||
|
||||
for ( p in ports )
|
||||
{
|
||||
if ( ! register_for_port(tag, p) )
|
||||
rc = F;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
function register_for_port(tag: Analyzer::Tag, p: port) : bool
|
||||
{
|
||||
if ( ! __register_for_port(tag, p) )
|
||||
return F;
|
||||
|
||||
if ( tag !in ports )
|
||||
ports[tag] = set();
|
||||
|
||||
add ports[tag][p];
|
||||
return T;
|
||||
}
|
||||
|
||||
function registered_ports(tag: Analyzer::Tag) : set[port]
|
||||
{
|
||||
return tag in ports ? ports[tag] : set();
|
||||
}
|
||||
|
||||
function all_registered_ports(): table[Analyzer::Tag] of set[port]
|
||||
{
|
||||
return ports;
|
||||
}
|
||||
|
||||
function name(atype: Analyzer::Tag) : string
|
||||
{
|
||||
return __name(atype);
|
||||
}
|
||||
|
||||
function schedule_analyzer(orig: addr, resp: addr, resp_p: port,
|
||||
analyzer: Analyzer::Tag, tout: interval) : bool
|
||||
{
|
||||
return __schedule_analyzer(orig, resp, resp_p, analyzer, tout);
|
||||
}
|
||||
|
|
@ -41,22 +41,11 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(DPD::LOG, [$columns=Info]);
|
||||
|
||||
# Populate the internal DPD analysis variable.
|
||||
for ( a in dpd_config )
|
||||
{
|
||||
for ( p in dpd_config[a]$ports )
|
||||
{
|
||||
if ( p !in dpd_analyzer_ports )
|
||||
dpd_analyzer_ports[p] = set();
|
||||
add dpd_analyzer_ports[p][a];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=10
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=10
|
||||
{
|
||||
local analyzer = analyzer_name(atype);
|
||||
local analyzer = Analyzer::name(atype);
|
||||
|
||||
if ( fmt("-%s",analyzer) in c$service )
|
||||
delete c$service[fmt("-%s", analyzer)];
|
||||
|
@ -64,10 +53,10 @@ event protocol_confirmation(c: connection, atype: count, aid: count) &priority=1
|
|||
add c$service[analyzer];
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=10
|
||||
{
|
||||
local analyzer = analyzer_name(atype);
|
||||
local analyzer = Analyzer::name(atype);
|
||||
# If the service hasn't been confirmed yet, don't generate a log message
|
||||
# for the protocol violation.
|
||||
if ( analyzer !in c$service )
|
||||
|
@ -86,7 +75,7 @@ event protocol_violation(c: connection, atype: count, aid: count,
|
|||
c$dpd = info;
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=5
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=5
|
||||
{
|
||||
if ( !c?$dpd || aid in c$dpd$disabled_aids )
|
||||
return;
|
||||
|
@ -100,7 +89,7 @@ event protocol_violation(c: connection, atype: count, aid: count, reason: string
|
|||
add c$dpd$disabled_aids[aid];
|
||||
}
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=-5
|
||||
{
|
||||
if ( c?$dpd )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
##! An interface for driving the analysis of files, possibly independent of
|
||||
##! any network protocol over which they're transported.
|
||||
|
||||
@load base/file_analysis.bif
|
||||
@load base/bif/file_analysis.bif
|
||||
@load base/frameworks/logging
|
||||
|
||||
module FileAnalysis;
|
||||
|
@ -104,7 +104,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;
|
||||
|
||||
## Event that can be handled to access the Info record as it is sent on
|
||||
## to the logging framework.
|
||||
|
|
|
@ -149,7 +149,7 @@ export {
|
|||
global end_of_data: event(name: string, source:string);
|
||||
}
|
||||
|
||||
@load base/input.bif
|
||||
@load base/bif/input.bif
|
||||
|
||||
|
||||
module Input;
|
||||
|
|
|
@ -366,7 +366,7 @@ export {
|
|||
# We keep a script-level copy of all filters so that we can manipulate them.
|
||||
global filters: table[ID, string] of Filter;
|
||||
|
||||
@load base/logging.bif # Needs Filter and Stream defined.
|
||||
@load base/bif/logging.bif # Needs Filter and Stream defined.
|
||||
|
||||
module Log;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
##! Note that this framework deals with the handling of internally generated
|
||||
##! reporter messages, for the interface in to actually creating interface
|
||||
##! into actually creating reporter messages from the scripting layer, use
|
||||
##! the built-in functions in :doc:`/scripts/base/reporter.bif`.
|
||||
##! the built-in functions in :doc:`/scripts/base/bif/reporter.bif`.
|
||||
|
||||
module Reporter;
|
||||
|
||||
|
|
|
@ -83,19 +83,17 @@ export {
|
|||
}
|
||||
|
||||
const ayiya_ports = { 5072/udp };
|
||||
redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] };
|
||||
|
||||
const teredo_ports = { 3544/udp };
|
||||
redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] };
|
||||
|
||||
const gtpv1_ports = { 2152/udp, 2123/udp };
|
||||
redef dpd_config += { [ANALYZER_GTPV1] = [$ports = gtpv1_ports] };
|
||||
|
||||
redef likely_server_ports += { ayiya_ports, teredo_ports, gtpv1_ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Tunnel::LOG, [$columns=Info]);
|
||||
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_AYIYA, ayiya_ports);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_TEREDO, teredo_ports);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_GTPV1, gtpv1_ports);
|
||||
}
|
||||
|
||||
function register_all(ecv: EncapsulatingConnVector)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@load base/const.bif
|
||||
@load base/types.bif
|
||||
@load base/bif/const.bif.bro
|
||||
@load base/bif/types.bif
|
||||
|
||||
# Type declarations
|
||||
|
||||
|
@ -226,7 +226,7 @@ type endpoint_stats: record {
|
|||
## 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
|
||||
## .. bro:see:: Analyzer::name Analyzer::disable_analyzer protocol_confirmation
|
||||
## protocol_violation
|
||||
##
|
||||
## .. todo::While we declare an alias for the type here, the events/functions still
|
||||
|
@ -713,9 +713,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 +2723,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 +2913,11 @@ const remote_trace_sync_peers = 0 &redef;
|
|||
## consistency check.
|
||||
const remote_check_sync_consistency = F &redef;
|
||||
|
||||
## Analyzer tags. The core automatically defines constants
|
||||
## ``ANALYZER_<analyzer-name>*``, e.g., ``ANALYZER_HTTP``.
|
||||
##
|
||||
## .. bro:see:: dpd_config
|
||||
##
|
||||
## .. todo::We should autodoc these automaticallty generated constants.
|
||||
type AnalyzerTag: count;
|
||||
|
||||
## Set of ports activating a particular protocol analysis.
|
||||
##
|
||||
## .. bro:see:: dpd_config
|
||||
type dpd_protocol_config: record {
|
||||
ports: set[port] &optional; ##< Set of ports.
|
||||
};
|
||||
|
||||
## Port configuration for Bro's "dynamic protocol detection". Protocol
|
||||
## analyzers can be activated via either well-known ports or content analysis.
|
||||
## This table defines the ports.
|
||||
##
|
||||
## .. bro:see:: dpd_reassemble_first_packets dpd_buffer_size
|
||||
## dpd_match_only_beginning dpd_ignore_ports
|
||||
const dpd_config: table[AnalyzerTag] of dpd_protocol_config = {} &redef;
|
||||
|
||||
## Reassemble the beginning of all TCP connections before doing
|
||||
## signature-matching. Enabling this provides more accurate matching at the
|
||||
## expensive of CPU cycles.
|
||||
##
|
||||
## .. bro:see:: dpd_config dpd_buffer_size
|
||||
## .. bro:see:: dpd_buffer_size
|
||||
## dpd_match_only_beginning dpd_ignore_ports
|
||||
##
|
||||
## .. note:: Despite the name, this option affects *all* signature matching, not
|
||||
|
@ -2955,24 +2932,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 +2957,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 +3065,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 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/file-analysis
|
||||
|
||||
# Load BiFs defined by plugins.
|
||||
@load base/bif/plugins
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
# loaded in base/init-bare.bro
|
||||
#@load base/frameworks/logging
|
||||
@load base/frameworks/notice
|
||||
@load base/frameworks/analyzer
|
||||
@load base/frameworks/dpd
|
||||
@load base/frameworks/signatures
|
||||
@load base/frameworks/packet-filter
|
||||
|
|
|
@ -6,9 +6,9 @@ module Conn;
|
|||
export {
|
||||
## Define inactivity timeouts by the service detected being used over
|
||||
## the connection.
|
||||
const analyzer_inactivity_timeouts: table[AnalyzerTag] of interval = {
|
||||
const analyzer_inactivity_timeouts: table[Analyzer::Tag] of interval = {
|
||||
# For interactive services, allow longer periods of inactivity.
|
||||
[[ANALYZER_SSH, ANALYZER_FTP]] = 1 hrs,
|
||||
[[Analyzer::ANALYZER_SSH, Analyzer::ANALYZER_FTP]] = 1 hrs,
|
||||
} &redef;
|
||||
|
||||
## Define inactivity timeouts based on common protocol ports.
|
||||
|
@ -18,7 +18,7 @@ export {
|
|||
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count)
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count)
|
||||
{
|
||||
if ( atype in analyzer_inactivity_timeouts )
|
||||
set_inactivity_timeout(c$id, analyzer_inactivity_timeouts[atype]);
|
||||
|
|
|
@ -130,19 +130,13 @@ redef capture_filters += {
|
|||
["netbios-ns"] = "udp port 137",
|
||||
};
|
||||
|
||||
const dns_ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
redef dpd_config += { [ANALYZER_DNS] = [$ports = dns_ports] };
|
||||
|
||||
const dns_udp_ports = { 53/udp, 137/udp, 5353/udp, 5355/udp };
|
||||
const dns_tcp_ports = { 53/tcp };
|
||||
redef dpd_config += { [ANALYZER_DNS_UDP_BINPAC] = [$ports = dns_udp_ports] };
|
||||
redef dpd_config += { [ANALYZER_DNS_TCP_BINPAC] = [$ports = dns_tcp_ports] };
|
||||
|
||||
redef likely_server_ports += { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
const ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(DNS::LOG, [$columns=Info, $ev=log_dns]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, ports);
|
||||
}
|
||||
|
||||
function new_session(c: connection, trans_id: count): Info
|
||||
|
|
|
@ -11,7 +11,7 @@ export {
|
|||
|
||||
function get_handle_string(c: connection): string
|
||||
{
|
||||
return cat(ANALYZER_FTP_DATA, " ", c$start_time, " ", id_string(c$id));
|
||||
return cat(Analyzer::ANALYZER_FTP_DATA, " ", c$start_time, " ", id_string(c$id));
|
||||
}
|
||||
|
||||
function get_file_handle(c: connection, is_orig: bool): string
|
||||
|
@ -40,8 +40,8 @@ function get_file_handle(c: connection, is_orig: bool): string
|
|||
|
||||
module GLOBAL;
|
||||
|
||||
event get_file_handle(tag: AnalyzerTag, c: connection, is_orig: bool)
|
||||
event get_file_handle(tag: Analyzer::Tag, c: connection, is_orig: bool)
|
||||
{
|
||||
if ( tag != ANALYZER_FTP_DATA ) return;
|
||||
if ( tag != Analyzer::ANALYZER_FTP_DATA ) return;
|
||||
set_file_handle(FTP::get_file_handle(c, is_orig));
|
||||
}
|
||||
|
|
|
@ -111,11 +111,10 @@ redef record connection += {
|
|||
};
|
||||
|
||||
# Configure DPD
|
||||
const ports = { 21/tcp, 2811/tcp } &redef; # 2811/tcp is GridFTP.
|
||||
redef capture_filters += { ["ftp"] = "port 21 and port 2811" };
|
||||
redef dpd_config += { [ANALYZER_FTP] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 21/tcp, 2811/tcp };
|
||||
const ports = { 21/tcp, 2811/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
# Establish the variable for tracking expected connections.
|
||||
global ftp_data_expected: table[addr, port] of Info &read_expire=5mins;
|
||||
|
@ -123,6 +122,7 @@ global ftp_data_expected: table[addr, port] of Info &read_expire=5mins;
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(FTP::LOG, [$columns=Info, $ev=log_ftp]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_FTP, ports);
|
||||
}
|
||||
|
||||
## A set of commands where the argument can be expected to refer
|
||||
|
@ -221,7 +221,7 @@ function add_expected_data_channel(s: Info, chan: ExpectedDataChannel)
|
|||
s$passive = chan$passive;
|
||||
s$data_channel = chan;
|
||||
ftp_data_expected[chan$resp_h, chan$resp_p] = s;
|
||||
expect_connection(chan$orig_h, chan$resp_h, chan$resp_p, ANALYZER_FTP_DATA,
|
||||
Analyzer::schedule_analyzer(chan$orig_h, chan$resp_h, chan$resp_p, Analyzer::ANALYZER_FTP_DATA,
|
||||
5mins);
|
||||
}
|
||||
|
||||
|
@ -338,7 +338,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
|||
}
|
||||
}
|
||||
|
||||
event expected_connection_seen(c: connection, a: count) &priority=10
|
||||
event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10
|
||||
{
|
||||
local id = c$id;
|
||||
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
||||
|
|
|
@ -15,17 +15,17 @@ function get_file_handle(c: connection, is_orig: bool): string
|
|||
if ( ! c?$http ) return "";
|
||||
|
||||
if ( c$http$range_request )
|
||||
return cat(ANALYZER_HTTP, " ", is_orig, " ", c$id$orig_h, " ",
|
||||
return cat(Analyzer::ANALYZER_HTTP, " ", is_orig, " ", c$id$orig_h, " ",
|
||||
build_url(c$http));
|
||||
|
||||
return cat(ANALYZER_HTTP, " ", c$start_time, " ", is_orig, " ",
|
||||
return cat(Analyzer::ANALYZER_HTTP, " ", c$start_time, " ", is_orig, " ",
|
||||
c$http$trans_depth, " ", id_string(c$id));
|
||||
}
|
||||
|
||||
module GLOBAL;
|
||||
|
||||
event get_file_handle(tag: AnalyzerTag, c: connection, is_orig: bool)
|
||||
event get_file_handle(tag: Analyzer::Tag, c: connection, is_orig: bool)
|
||||
{
|
||||
if ( tag != ANALYZER_HTTP ) return;
|
||||
if ( tag != Analyzer::ANALYZER_HTTP ) return;
|
||||
set_file_handle(HTTP::get_file_handle(c, is_orig));
|
||||
}
|
||||
|
|
|
@ -123,29 +123,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;
|
||||
|
|
|
@ -175,11 +175,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 )
|
||||
|
|
|
@ -12,13 +12,13 @@ export {
|
|||
function get_file_handle(c: connection, is_orig: bool): string
|
||||
{
|
||||
if ( is_orig ) return "";
|
||||
return cat(ANALYZER_IRC_DATA, " ", c$start_time, " ", id_string(c$id));
|
||||
return cat(Analyzer::ANALYZER_IRC_DATA, " ", c$start_time, " ", id_string(c$id));
|
||||
}
|
||||
|
||||
module GLOBAL;
|
||||
|
||||
event get_file_handle(tag: AnalyzerTag, c: connection, is_orig: bool)
|
||||
event get_file_handle(tag: Analyzer::Tag, c: connection, is_orig: bool)
|
||||
{
|
||||
if ( tag != ANALYZER_IRC_DATA ) return;
|
||||
if ( tag != Analyzer::ANALYZER_IRC_DATA ) return;
|
||||
set_file_handle(IRC::get_file_handle(c, is_orig));
|
||||
}
|
||||
|
|
|
@ -45,14 +45,13 @@ redef capture_filters += { ["irc-6668"] = "port 6668" };
|
|||
redef capture_filters += { ["irc-6669"] = "port 6669" };
|
||||
|
||||
# DPD configuration.
|
||||
const irc_ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
redef dpd_config += { [ANALYZER_IRC] = [$ports = irc_ports] };
|
||||
|
||||
redef likely_server_ports += { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
const ports = { 6666/tcp, 6667/tcp, 6668/tcp, 6669/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(IRC::LOG, [$columns=Info, $ev=irc_log]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_IRC, ports);
|
||||
}
|
||||
|
||||
function new_session(c: connection): Info
|
||||
|
|
|
@ -31,12 +31,14 @@ redef record connection += {
|
|||
|
||||
# Configure DPD and the packet filter.
|
||||
redef capture_filters += { ["modbus"] = "tcp port 502" };
|
||||
redef dpd_config += { [ANALYZER_MODBUS] = [$ports = set(502/tcp)] };
|
||||
redef likely_server_ports += { 502/tcp };
|
||||
|
||||
const ports = { 502/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Modbus::LOG, [$columns=Info, $ev=log_modbus]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_MODBUS, ports);
|
||||
}
|
||||
|
||||
event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool) &priority=5
|
||||
|
|
|
@ -13,14 +13,14 @@ export {
|
|||
function get_file_handle(c: connection, is_orig: bool): string
|
||||
{
|
||||
if ( ! c?$smtp ) return "";
|
||||
return cat(ANALYZER_SMTP, " ", c$start_time, " ", c$smtp$trans_depth, " ",
|
||||
return cat(Analyzer::ANALYZER_SMTP, " ", c$start_time, " ", c$smtp$trans_depth, " ",
|
||||
c$smtp_state$mime_level);
|
||||
}
|
||||
|
||||
module GLOBAL;
|
||||
|
||||
event get_file_handle(tag: AnalyzerTag, c: connection, is_orig: bool)
|
||||
event get_file_handle(tag: Analyzer::Tag, c: connection, is_orig: bool)
|
||||
{
|
||||
if ( tag != ANALYZER_SMTP ) return;
|
||||
if ( tag != Analyzer::ANALYZER_SMTP ) return;
|
||||
set_file_handle(SMTP::get_file_handle(c, is_orig));
|
||||
}
|
||||
|
|
|
@ -74,9 +74,6 @@ export {
|
|||
const mail_path_capture = ALL_HOSTS &redef;
|
||||
|
||||
global log_smtp: event(rec: Info);
|
||||
|
||||
## Configure the default ports for SMTP analysis.
|
||||
const ports = { 25/tcp, 587/tcp } &redef;
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
|
@ -86,13 +83,14 @@ redef record connection += {
|
|||
|
||||
# Configure DPD
|
||||
redef capture_filters += { ["smtp"] = "tcp port 25 or tcp port 587" };
|
||||
redef dpd_config += { [ANALYZER_SMTP] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 25/tcp, 587/tcp };
|
||||
const ports = { 25/tcp, 587/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SMTP::LOG, [$columns=SMTP::Info, $ev=log_smtp]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SMTP, ports);
|
||||
}
|
||||
|
||||
function find_address_in_smtp_header(header: string): string
|
||||
|
|
|
@ -34,9 +34,13 @@ export {
|
|||
global log_socks: event(rec: Info);
|
||||
}
|
||||
|
||||
const ports = { 1080/tcp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SOCKS, ports);
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
|
@ -45,7 +49,6 @@ redef record connection += {
|
|||
|
||||
# Configure DPD
|
||||
redef capture_filters += { ["socks"] = "tcp port 1080" };
|
||||
redef dpd_config += { [ANALYZER_SOCKS] = [$ports = set(1080/tcp)] };
|
||||
redef likely_server_ports += { 1080/tcp };
|
||||
|
||||
function set_session(c: connection, version: count)
|
||||
|
|
|
@ -71,10 +71,11 @@ export {
|
|||
}
|
||||
|
||||
# Configure DPD and the packet filter
|
||||
redef capture_filters += { ["ssh"] = "tcp port 22" };
|
||||
redef dpd_config += { [ANALYZER_SSH] = [$ports = set(22/tcp)] };
|
||||
|
||||
redef likely_server_ports += { 22/tcp };
|
||||
const ports = { 22/tcp };
|
||||
|
||||
redef capture_filters += { ["ssh"] = "tcp port 22" };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
redef record connection += {
|
||||
ssh: Info &optional;
|
||||
|
@ -83,6 +84,7 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports);
|
||||
}
|
||||
|
||||
function set_session(c: connection)
|
||||
|
|
|
@ -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,16 +112,9 @@ 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 += {
|
||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
||||
};
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
# A queue that buffers log records.
|
||||
global log_delay_queue: table[count] of Info;
|
||||
|
@ -135,6 +123,12 @@ 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)
|
||||
{
|
||||
if ( ! c?$ssl )
|
||||
|
@ -288,14 +282,14 @@ 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 )
|
||||
|
|
|
@ -27,10 +27,9 @@ export {
|
|||
}
|
||||
|
||||
redef capture_filters += { ["syslog"] = "port 514" };
|
||||
const ports = { 514/udp } &redef;
|
||||
redef dpd_config += { [ANALYZER_SYSLOG_BINPAC] = [$ports = ports] };
|
||||
|
||||
redef likely_server_ports += { 514/udp };
|
||||
const ports = { 514/udp };
|
||||
redef likely_server_ports += { ports };
|
||||
|
||||
redef record connection += {
|
||||
syslog: Info &optional;
|
||||
|
@ -39,6 +38,7 @@ redef record connection += {
|
|||
event bro_init() &priority=5
|
||||
{
|
||||
Log::create_stream(Syslog::LOG, [$columns=Info]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, ports);
|
||||
}
|
||||
|
||||
event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=5
|
||||
|
|
|
@ -21,22 +21,22 @@ export {
|
|||
|
||||
type dir: enum { NONE, INCOMING, OUTGOING, BOTH };
|
||||
|
||||
const valids: table[count, addr, port] of dir = {
|
||||
const valids: table[Analyzer::Tag, addr, port] of dir = {
|
||||
# A couple of ports commonly used for benign HTTP servers.
|
||||
|
||||
# For now we want to see everything.
|
||||
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING,
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 81/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 82/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 83/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 88/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8001/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8090/tcp] = OUTGOING,
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 8081/tcp] = OUTGOING,
|
||||
#
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella
|
||||
# [ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6346/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6347/tcp] = BOTH, # Gnutella
|
||||
# [Analyzer::ANALYZER_HTTP, 0.0.0.0, 6348/tcp] = BOTH, # Gnutella
|
||||
} &redef;
|
||||
|
||||
# Set of analyzers for which we suppress Server_Found notices
|
||||
|
@ -44,8 +44,8 @@ export {
|
|||
# log files, this also saves memory because for these we don't
|
||||
# need to remember which servers we already have reported, which
|
||||
# for some can be a lot.
|
||||
const suppress_servers: set [count] = {
|
||||
# ANALYZER_HTTP
|
||||
const suppress_servers: set [Analyzer::Tag] = {
|
||||
# Analyzer::ANALYZER_HTTP
|
||||
} &redef;
|
||||
|
||||
# We consider a connection to use a protocol X if the analyzer for X
|
||||
|
@ -60,7 +60,7 @@ export {
|
|||
|
||||
# Entry point for other analyzers to report that they recognized
|
||||
# a certain (sub-)protocol.
|
||||
global found_protocol: function(c: connection, analyzer: count,
|
||||
global found_protocol: function(c: connection, analyzer: Analyzer::Tag,
|
||||
protocol: string);
|
||||
|
||||
# Table keeping reported (server, port, analyzer) tuples (and their
|
||||
|
@ -70,7 +70,7 @@ export {
|
|||
}
|
||||
|
||||
# Table that tracks currently active dynamic analyzers per connection.
|
||||
global conns: table[conn_id] of set[count];
|
||||
global conns: table[conn_id] of set[Analyzer::Tag];
|
||||
|
||||
# Table of reports by other analyzers about the protocol used in a connection.
|
||||
global protocols: table[conn_id] of set[string];
|
||||
|
@ -80,7 +80,7 @@ type protocol : record {
|
|||
sub: string; # "sub-protocols" reported by other sources
|
||||
};
|
||||
|
||||
function get_protocol(c: connection, a: count) : protocol
|
||||
function get_protocol(c: connection, a: Analyzer::Tag) : protocol
|
||||
{
|
||||
local str = "";
|
||||
if ( c$id in protocols )
|
||||
|
@ -89,7 +89,7 @@ function get_protocol(c: connection, a: count) : protocol
|
|||
str = |str| > 0 ? fmt("%s/%s", str, p) : p;
|
||||
}
|
||||
|
||||
return [$a=analyzer_name(a), $sub=str];
|
||||
return [$a=Analyzer::name(a), $sub=str];
|
||||
}
|
||||
|
||||
function fmt_protocol(p: protocol) : string
|
||||
|
@ -97,7 +97,7 @@ function fmt_protocol(p: protocol) : string
|
|||
return p$sub != "" ? fmt("%s (via %s)", p$sub, p$a) : p$a;
|
||||
}
|
||||
|
||||
function do_notice(c: connection, a: count, d: dir)
|
||||
function do_notice(c: connection, a: Analyzer::Tag, d: dir)
|
||||
{
|
||||
if ( d == BOTH )
|
||||
return;
|
||||
|
@ -113,7 +113,7 @@ function do_notice(c: connection, a: count, d: dir)
|
|||
|
||||
NOTICE([$note=Protocol_Found,
|
||||
$msg=fmt("%s %s on port %s", id_string(c$id), s, c$id$resp_p),
|
||||
$sub=s, $conn=c, $n=a]);
|
||||
$sub=s, $conn=c]);
|
||||
|
||||
# We report multiple Server_Found's per host if we find a new
|
||||
# sub-protocol.
|
||||
|
@ -129,7 +129,7 @@ function do_notice(c: connection, a: count, d: dir)
|
|||
NOTICE([$note=Server_Found,
|
||||
$msg=fmt("%s: %s server on port %s%s", c$id$resp_h, s,
|
||||
c$id$resp_p, (known ? " (update)" : "")),
|
||||
$p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h, $n=a]);
|
||||
$p=c$id$resp_p, $sub=s, $conn=c, $src=c$id$resp_h]);
|
||||
|
||||
if ( ! known )
|
||||
servers[c$id$resp_h, c$id$resp_p, p$a] = set();
|
||||
|
@ -194,10 +194,10 @@ event connection_state_remove(c: connection)
|
|||
report_protocols(c);
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count)
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count)
|
||||
{
|
||||
# Don't report anything running on a well-known port.
|
||||
if ( atype in dpd_config && c$id$resp_p in dpd_config[atype]$ports )
|
||||
if ( c$id$resp_p in Analyzer::registered_ports(atype) )
|
||||
return;
|
||||
|
||||
if ( c$id in conns )
|
||||
|
@ -214,11 +214,10 @@ event protocol_confirmation(c: connection, atype: count, aid: count)
|
|||
}
|
||||
}
|
||||
|
||||
function found_protocol(c: connection, analyzer: count, protocol: string)
|
||||
function found_protocol(c: connection, atype: Analyzer::Tag, protocol: string)
|
||||
{
|
||||
# Don't report anything running on a well-known port.
|
||||
if ( analyzer in dpd_config &&
|
||||
c$id$resp_p in dpd_config[analyzer]$ports )
|
||||
if ( c$id$resp_p in Analyzer::registered_ports(atype) )
|
||||
return;
|
||||
|
||||
if ( c$id !in protocols )
|
||||
|
|
|
@ -20,7 +20,7 @@ export {
|
|||
}
|
||||
|
||||
|
||||
event protocol_violation(c: connection, atype: count, aid: count,
|
||||
event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count,
|
||||
reason: string) &priority=4
|
||||
{
|
||||
if ( ! c?$dpd ) return;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
##! This script gives the capability to selectively enable and disable event
|
||||
##! groups at runtime. No events will be raised for all members of a disabled
|
||||
##! event group.
|
||||
|
||||
module AnalysisGroups;
|
||||
|
||||
export {
|
||||
## By default, all event groups are enabled.
|
||||
## We disable all groups in this table.
|
||||
const disabled: set[string] &redef;
|
||||
}
|
||||
|
||||
# Set to remember all groups which were disabled by the last update.
|
||||
global currently_disabled: set[string];
|
||||
|
||||
# This is the event that the control framework uses when it needs to indicate
|
||||
# that an update control action happened.
|
||||
event Control::configuration_update()
|
||||
{
|
||||
# Reenable those which are not to be disabled anymore.
|
||||
for ( g in currently_disabled )
|
||||
if ( g !in disabled )
|
||||
enable_event_group(g);
|
||||
|
||||
# Disable those which are not already disabled.
|
||||
for ( g in disabled )
|
||||
if ( g !in currently_disabled )
|
||||
disable_event_group(g);
|
||||
|
||||
currently_disabled = copy(disabled);
|
||||
}
|
|
@ -87,7 +87,7 @@ function known_services_done(c: connection)
|
|||
event log_it(network_time(), id$resp_h, id$resp_p, c$service);
|
||||
}
|
||||
|
||||
event protocol_confirmation(c: connection, atype: count, aid: count) &priority=-5
|
||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=-5
|
||||
{
|
||||
known_services_done(c);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
@load integration/barnyard2/types.bro
|
||||
@load integration/collective-intel/__load__.bro
|
||||
@load integration/collective-intel/main.bro
|
||||
@load misc/analysis-groups.bro
|
||||
@load misc/app-metrics.bro
|
||||
@load misc/capture-loss.bro
|
||||
@load misc/detect-traceroute/__load__.bro
|
||||
|
|
403
src/Analyzer.h
403
src/Analyzer.h
|
@ -1,403 +0,0 @@
|
|||
// Main analyzer interface.
|
||||
|
||||
#ifndef ANALYZER_H
|
||||
#define ANALYZER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "AnalyzerTags.h"
|
||||
#include "Conn.h"
|
||||
#include "Obj.h"
|
||||
|
||||
class DPM;
|
||||
class PIA;
|
||||
class Analyzer;
|
||||
typedef list<Analyzer*> analyzer_list;
|
||||
|
||||
typedef void (Analyzer::*analyzer_timer_func)(double t);
|
||||
|
||||
// FIXME: This is a copy of ConnectionTimer, which we may eventually be
|
||||
// able to get rid of.
|
||||
class AnalyzerTimer : public Timer {
|
||||
public:
|
||||
AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type)
|
||||
: Timer(arg_t, arg_type)
|
||||
{ Init(arg_analyzer, arg_timer, arg_do_expire); }
|
||||
virtual ~AnalyzerTimer();
|
||||
|
||||
void Dispatch(double t, int is_expire);
|
||||
|
||||
protected:
|
||||
AnalyzerTimer() {}
|
||||
|
||||
void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
|
||||
|
||||
Analyzer* analyzer;
|
||||
analyzer_timer_func timer;
|
||||
int do_expire;
|
||||
};
|
||||
|
||||
|
||||
// Main analyzer interface.
|
||||
//
|
||||
// Each analyzer is part of a tree, having a parent analyzer and an
|
||||
// arbitrary number of child analyzers. Each analyzer also has a list of
|
||||
// *suppport analyzers*. All its input first passes through this list of
|
||||
// support analyzers, which can perform arbitrary preprocessing. Support
|
||||
// analyzers share the same interface as regular analyzers, except that
|
||||
// they are unidirectional, i.e., they see only one side of a connection.
|
||||
//
|
||||
// When overiding any of these methods, always make sure to call the
|
||||
// base-class version first.
|
||||
|
||||
class SupportAnalyzer;
|
||||
class OutputHandler;
|
||||
|
||||
class Analyzer {
|
||||
public:
|
||||
Analyzer(AnalyzerTag::Tag tag, Connection* conn);
|
||||
virtual ~Analyzer();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Done();
|
||||
|
||||
// Pass data to the analyzer (it's automatically passed through its
|
||||
// support analyzers first). We have packet-wise and stream-wise
|
||||
// interfaces. For the packet-interface, some analyzers may require
|
||||
// more information than others, so IP/caplen and seq may or may
|
||||
// not be set.
|
||||
void NextPacket(int len, const u_char* data, bool orig,
|
||||
int seq = -1, const IP_Hdr* ip = 0, int caplen = 0);
|
||||
void NextStream(int len, const u_char* data, bool is_orig);
|
||||
|
||||
// Used for data that can't be delivered (e.g., due to a previous
|
||||
// sequence hole/gap).
|
||||
void NextUndelivered(int seq, int len, bool is_orig);
|
||||
|
||||
// Report message boundary. (See EndOfData() below.)
|
||||
void NextEndOfData(bool orig);
|
||||
|
||||
// Pass data on to all child analyzer(s). For SupportAnalyzers (see
|
||||
// below), this is overridden to pass it on to the next sibling (or
|
||||
// finally to the parent, if it's the last support analyzer).
|
||||
//
|
||||
// If we have an associated OutputHandler (see below), the data is
|
||||
// additionally passed to that, too. For SupportAnalyzers, it is *only*
|
||||
// delivered to the OutputHandler.
|
||||
virtual void ForwardPacket(int len, const u_char* data,
|
||||
bool orig, int seq,
|
||||
const IP_Hdr* ip, int caplen);
|
||||
virtual void ForwardStream(int len, const u_char* data, bool orig);
|
||||
virtual void ForwardUndelivered(int seq, int len, bool orig);
|
||||
|
||||
// Report a message boundary to all child analyzers
|
||||
virtual void ForwardEndOfData(bool orig);
|
||||
|
||||
AnalyzerID GetID() const { return id; }
|
||||
Connection* Conn() const { return conn; }
|
||||
|
||||
// An OutputHandler can be used to get access to data extracted by this
|
||||
// analyzer (i.e., all data which is passed to
|
||||
// Forward{Packet,Stream,Undelivered}). We take the ownership of
|
||||
// the handler.
|
||||
class OutputHandler {
|
||||
public:
|
||||
virtual ~OutputHandler() { }
|
||||
|
||||
virtual void DeliverPacket(int len, const u_char* data,
|
||||
bool orig, int seq,
|
||||
const IP_Hdr* ip, int caplen)
|
||||
{ }
|
||||
virtual void DeliverStream(int len, const u_char* data,
|
||||
bool orig) { }
|
||||
virtual void Undelivered(int seq, int len, bool orig) { }
|
||||
};
|
||||
|
||||
OutputHandler* GetOutputHandler() const { return output_handler; }
|
||||
void SetOutputHandler(OutputHandler* handler)
|
||||
{ output_handler = handler; }
|
||||
|
||||
// If an analyzer was triggered by a signature match, this returns the
|
||||
// name of the signature; nil if not.
|
||||
const Rule* Signature() const { return signature; }
|
||||
void SetSignature(const Rule* sig) { signature = sig; }
|
||||
|
||||
void SetSkip(bool do_skip) { skip = do_skip; }
|
||||
bool Skipping() const { return skip; }
|
||||
|
||||
bool IsFinished() const { return finished; }
|
||||
|
||||
AnalyzerTag::Tag GetTag() const { return tag; }
|
||||
const char* GetTagName() const;
|
||||
static AnalyzerTag::Tag GetTag(const char* tag);
|
||||
static const char* GetTagName(AnalyzerTag::Tag tag);
|
||||
static bool IsAvailable(AnalyzerTag::Tag tag)
|
||||
{ return analyzer_configs[tag].available(); }
|
||||
|
||||
// Management of the tree.
|
||||
//
|
||||
// We immediately discard an added analyzer if there's already a child
|
||||
// of the same type.
|
||||
void AddChildAnalyzer(Analyzer* analyzer)
|
||||
{ AddChildAnalyzer(analyzer, true); }
|
||||
Analyzer* AddChildAnalyzer(AnalyzerTag::Tag tag);
|
||||
|
||||
void RemoveChildAnalyzer(Analyzer* analyzer);
|
||||
void RemoveChildAnalyzer(AnalyzerID id);
|
||||
|
||||
bool HasChildAnalyzer(AnalyzerTag::Tag tag);
|
||||
|
||||
// Recursive; returns nil if not found.
|
||||
Analyzer* FindChild(AnalyzerID id);
|
||||
|
||||
// Recursive; returns first found, or nil.
|
||||
Analyzer* FindChild(AnalyzerTag::Tag tag);
|
||||
|
||||
const analyzer_list& GetChildren() { return children; }
|
||||
|
||||
Analyzer* Parent() const { return parent; }
|
||||
void SetParent(Analyzer* p) { parent = p; }
|
||||
|
||||
// Remove this child analyzer from the parent's list.
|
||||
void Remove() { assert(parent); parent->RemoveChildAnalyzer(this); }
|
||||
|
||||
// Management of support analyzers. Support analyzers are associated
|
||||
// with a direction, and will only see data in the corresponding flow.
|
||||
//
|
||||
// We immediately discard an added analyzer if there's already a child
|
||||
// of the same type for the same direction.
|
||||
|
||||
// Adds to tail of list.
|
||||
void AddSupportAnalyzer(SupportAnalyzer* analyzer);
|
||||
|
||||
void RemoveSupportAnalyzer(SupportAnalyzer* analyzer);
|
||||
|
||||
// These are the methods where the analyzer actually gets its input.
|
||||
// Each analyzer has only to implement the schemes it supports.
|
||||
|
||||
// Packet-wise (or more generally chunk-wise) input. "data" points
|
||||
// to the payload that the analyzer is supposed to examine. If it's
|
||||
// part of a full packet, "ip" points to its IP header. An analyzer
|
||||
// may or may not require to be given the full packet (and its caplen)
|
||||
// as well.
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
// Stream-wise payload input.
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
// If a parent analyzer can't turn a sequence of packets into a stream
|
||||
// (e.g., due to holes), it can pass the remaining data through this
|
||||
// method to the child.
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
|
||||
// Report a message boundary. This is a generic method that can be used
|
||||
// by specific Analyzers if all data of a message has been delivered,
|
||||
// e.g., to report that HTTP body has been delivered completely by the
|
||||
// HTTP analyzer before it starts with the next body. EndOfData() is
|
||||
// automatically generated by the analyzer's Done() method.
|
||||
virtual void EndOfData(bool is_orig);
|
||||
|
||||
// Occasionally we may find during analysis that we got the direction
|
||||
// of the connection wrong. In these cases, this method is called
|
||||
// to swap state if necessary. This will not happen after payload
|
||||
// has already been passed on, so most analyzers don't need to care.
|
||||
virtual void FlipRoles();
|
||||
|
||||
// Feedback about protocol conformance, to be called by the
|
||||
// analyzer's processing. The methods raise the correspondiong
|
||||
// protocol_confirmation and protocol_violation events.
|
||||
|
||||
// Report that we believe we're parsing the right protocol. This
|
||||
// should be called as early as possible during a connection's
|
||||
// life-time. The protocol_confirmed event is only raised once per
|
||||
// analyzer, even if the method is called multiple times.
|
||||
virtual void ProtocolConfirmation();
|
||||
|
||||
// Return whether the analyzer previously called ProtocolConfirmation()
|
||||
// at least once before.
|
||||
bool ProtocolConfirmed() const
|
||||
{ return protocol_confirmed; }
|
||||
|
||||
// Report that we found a significant protocol violation which might
|
||||
// indicate that the analyzed data is in fact not the expected
|
||||
// protocol. The protocol_violation event is raised once per call to
|
||||
// this method so that the script-level may build up some notion of
|
||||
// how "severely" protocol semantics are violated.
|
||||
virtual void ProtocolViolation(const char* reason,
|
||||
const char* data = 0, int len = 0);
|
||||
|
||||
virtual unsigned int MemoryAllocation() const;
|
||||
|
||||
// Called whenever the connection value needs to be updated. Per
|
||||
// default, this method will be called for each analyzer in the tree.
|
||||
// Analyzers can use this method to attach additional data to the
|
||||
// connections. A call to BuildConnVal will in turn trigger a call to
|
||||
// UpdateConnVal.
|
||||
virtual void UpdateConnVal(RecordVal *conn_val);
|
||||
|
||||
// The following methods are proxies: calls are directly forwarded
|
||||
// to the connection instance. These are for convenience only,
|
||||
// allowing us to reuse more of the old analyzer code unchanged.
|
||||
RecordVal* BuildConnVal()
|
||||
{ return conn->BuildConnVal(); }
|
||||
void Event(EventHandlerPtr f, const char* name = 0)
|
||||
{ conn->Event(f, this, name); }
|
||||
void Event(EventHandlerPtr f, Val* v1, Val* v2 = 0)
|
||||
{ conn->Event(f, this, v1, v2); }
|
||||
void ConnectionEvent(EventHandlerPtr f, val_list* vl)
|
||||
{ conn->ConnectionEvent(f, this, vl); }
|
||||
void Weird(const char* name, const char* addl = "")
|
||||
{ conn->Weird(name, addl); }
|
||||
|
||||
// Factory function to instantiate new analyzers.
|
||||
static Analyzer* InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c);
|
||||
|
||||
protected:
|
||||
friend class DPM;
|
||||
friend class Connection;
|
||||
friend class AnalyzerTimer;
|
||||
friend class TCP_ApplicationAnalyzer;
|
||||
|
||||
Analyzer() { }
|
||||
|
||||
// Associates a connection with this analyzer. Must be called if
|
||||
// we're using the default ctor.
|
||||
void SetConnection(Connection* c) { conn = c; }
|
||||
|
||||
// Creates the given timer to expire at time t. If do_expire
|
||||
// is true, then the timer is also evaluated when Bro terminates,
|
||||
// otherwise not.
|
||||
void AddTimer(analyzer_timer_func timer, double t, int do_expire,
|
||||
TimerType type);
|
||||
|
||||
void RemoveTimer(Timer* t);
|
||||
void CancelTimers();
|
||||
|
||||
bool HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig);
|
||||
|
||||
void AddChildAnalyzer(Analyzer* analyzer, bool init);
|
||||
void InitChildren();
|
||||
void AppendNewChildren();
|
||||
|
||||
private:
|
||||
// Internal method to eventually delete a child analyzer that's
|
||||
// already Done().
|
||||
void DeleteChild(analyzer_list::iterator i);
|
||||
|
||||
AnalyzerTag::Tag tag;
|
||||
AnalyzerID id;
|
||||
|
||||
Connection* conn;
|
||||
Analyzer* parent;
|
||||
const Rule* signature;
|
||||
OutputHandler* output_handler;
|
||||
|
||||
analyzer_list children;
|
||||
SupportAnalyzer* orig_supporters;
|
||||
SupportAnalyzer* resp_supporters;
|
||||
|
||||
analyzer_list new_children;
|
||||
|
||||
bool protocol_confirmed;
|
||||
|
||||
timer_list timers;
|
||||
bool timers_canceled;
|
||||
bool skip;
|
||||
bool finished;
|
||||
bool removing;
|
||||
|
||||
static AnalyzerID id_counter;
|
||||
|
||||
typedef bool (*available_callback)();
|
||||
typedef Analyzer* (*factory_callback)(Connection* conn);
|
||||
typedef bool (*match_callback)(Connection*);
|
||||
|
||||
struct Config {
|
||||
AnalyzerTag::Tag tag;
|
||||
const char* name;
|
||||
factory_callback factory;
|
||||
available_callback available;
|
||||
match_callback match;
|
||||
bool partial;
|
||||
};
|
||||
|
||||
// Table of analyzers.
|
||||
static const Config analyzer_configs[];
|
||||
|
||||
};
|
||||
|
||||
#define ADD_ANALYZER_TIMER(timer, t, do_expire, type) \
|
||||
AddTimer(analyzer_timer_func(timer), (t), (do_expire), (type))
|
||||
|
||||
#define LOOP_OVER_CHILDREN(var) \
|
||||
for ( analyzer_list::iterator var = children.begin(); \
|
||||
var != children.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_CONST_CHILDREN(var) \
|
||||
for ( analyzer_list::const_iterator var = children.begin(); \
|
||||
var != children.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_GIVEN_CHILDREN(var, the_kids) \
|
||||
for ( analyzer_list::iterator var = the_kids.begin(); \
|
||||
var != the_kids.end(); var++ )
|
||||
|
||||
#define LOOP_OVER_GIVEN_CONST_CHILDREN(var, the_kids) \
|
||||
for ( analyzer_list::const_iterator var = the_kids.begin(); \
|
||||
var != the_kids.end(); var++ )
|
||||
|
||||
class SupportAnalyzer : public Analyzer {
|
||||
public:
|
||||
SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
|
||||
: Analyzer(tag, conn) { orig = arg_orig; sibling = 0; }
|
||||
|
||||
virtual ~SupportAnalyzer() {}
|
||||
|
||||
bool IsOrig() const { return orig; }
|
||||
|
||||
virtual void ForwardPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
virtual void ForwardStream(int len, const u_char* data, bool orig);
|
||||
virtual void ForwardUndelivered(int seq, int len, bool orig);
|
||||
|
||||
SupportAnalyzer* Sibling() const { return sibling; }
|
||||
|
||||
protected:
|
||||
friend class Analyzer;
|
||||
|
||||
SupportAnalyzer() { }
|
||||
private:
|
||||
bool orig;
|
||||
|
||||
// Points to next support analyzer in chain. The list is managed by
|
||||
// parent analyzer.
|
||||
SupportAnalyzer* sibling;
|
||||
};
|
||||
|
||||
|
||||
class TransportLayerAnalyzer : public Analyzer {
|
||||
public:
|
||||
TransportLayerAnalyzer(AnalyzerTag::Tag tag, Connection* conn)
|
||||
: Analyzer(tag, conn) { pia = 0; }
|
||||
|
||||
virtual void Done();
|
||||
virtual bool IsReuse(double t, const u_char* pkt) = 0;
|
||||
|
||||
virtual void SetContentsFile(unsigned int direction, BroFile* f);
|
||||
virtual BroFile* GetContentsFile(unsigned int direction) const;
|
||||
|
||||
void SetPIA(PIA* arg_PIA) { pia = arg_PIA; }
|
||||
PIA* GetPIA() const { return pia; }
|
||||
|
||||
// Raises packet_contents event.
|
||||
void PacketContents(const u_char* data, int len);
|
||||
|
||||
protected:
|
||||
TransportLayerAnalyzer() { }
|
||||
|
||||
private:
|
||||
PIA* pia;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,57 +0,0 @@
|
|||
#ifndef ANALYZERTAGS_H
|
||||
#define ANALYZERTAGS_H
|
||||
|
||||
// Each kind of analyzer gets a tag. When adding an analyzer here, also adapt
|
||||
// the table of analyzers in Analyzer.cc.
|
||||
//
|
||||
// Using a namespace here is kind of a hack: ideally this would be in "class
|
||||
// Analyzer {...}". But then we'd have circular dependencies across the header
|
||||
// files.
|
||||
|
||||
#include "util.h"
|
||||
|
||||
typedef uint32 AnalyzerID;
|
||||
|
||||
namespace AnalyzerTag {
|
||||
enum Tag {
|
||||
Error = 0, // used as error code
|
||||
|
||||
// Analyzer in charge of protocol detection.
|
||||
PIA_TCP, PIA_UDP,
|
||||
|
||||
// Transport-layer analyzers.
|
||||
ICMP, TCP, UDP,
|
||||
|
||||
// Application-layer analyzers (hand-written).
|
||||
BitTorrent, BitTorrentTracker,
|
||||
DCE_RPC, DNS, Finger, FTP, Gnutella, HTTP, Ident, IRC,
|
||||
Login, NCP, NetbiosSSN, NFS, NTP, POP3, Portmapper, Rlogin,
|
||||
RPC, Rsh, SMB, SMTP, SSH,
|
||||
Telnet,
|
||||
|
||||
// Application-layer analyzers, binpac-generated.
|
||||
DHCP_BINPAC, DNS_TCP_BINPAC, DNS_UDP_BINPAC,
|
||||
HTTP_BINPAC, SSL, SYSLOG_BINPAC,
|
||||
Modbus,
|
||||
|
||||
// Decapsulation analyzers.
|
||||
AYIYA,
|
||||
SOCKS,
|
||||
Teredo,
|
||||
GTPv1,
|
||||
|
||||
// Other
|
||||
File, IRC_Data, FTP_Data, Backdoor, InterConn, SteppingStone, TCPStats,
|
||||
ConnSize,
|
||||
|
||||
// Support-analyzers
|
||||
Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP,
|
||||
Contents_NetbiosSSN, Contents_Rlogin, Contents_Rsh,
|
||||
Contents_DCE_RPC, Contents_SMB, Contents_RPC, Contents_NFS,
|
||||
FTP_ADAT,
|
||||
// End-marker.
|
||||
LastAnalyzer
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -82,9 +82,7 @@ int* Base64Converter::InitBase64Table(const string& alphabet)
|
|||
return base64_table;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Base64Converter::Base64Converter(Analyzer* arg_analyzer, const string& arg_alphabet)
|
||||
Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& arg_alphabet)
|
||||
{
|
||||
if ( arg_alphabet.size() > 0 )
|
||||
{
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "BroString.h"
|
||||
#include "Analyzer.h"
|
||||
#include "Reporter.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
// Maybe we should have a base class for generic decoders?
|
||||
class Base64Converter {
|
||||
|
@ -15,7 +16,7 @@ public:
|
|||
// <analyzer> is used for error reporting, and it should be zero when
|
||||
// the decoder is called by the built-in function decode_base64() or encode_base64().
|
||||
// Empty alphabet indicates the default base64 alphabet.
|
||||
Base64Converter(Analyzer* analyzer, const string& alphabet = "");
|
||||
Base64Converter(analyzer::Analyzer* analyzer, const string& alphabet = "");
|
||||
~Base64Converter();
|
||||
|
||||
// A note on Decode():
|
||||
|
@ -62,7 +63,7 @@ protected:
|
|||
int base64_after_padding;
|
||||
int* base64_table;
|
||||
int errored; // if true, we encountered an error - skip further processing
|
||||
Analyzer* analyzer;
|
||||
analyzer::Analyzer* analyzer;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -35,12 +35,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";
|
||||
|
|
|
@ -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,45 +107,7 @@ 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
|
||||
|
@ -153,74 +122,53 @@ set(BIF_SRCS
|
|||
)
|
||||
|
||||
foreach (bift ${BIF_SRCS})
|
||||
bif_target(${bift})
|
||||
bif_target(${bift} "standard")
|
||||
endforeach ()
|
||||
|
||||
########################################################################
|
||||
## BinPAC-dependent targets
|
||||
|
||||
set(BINPAC_AUXSRC
|
||||
binpac.pac
|
||||
bro.pac
|
||||
binpac_bro.h
|
||||
)
|
||||
include(BinPAC)
|
||||
|
||||
# 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}"
|
||||
set(BINPAC_AUXSRC
|
||||
${CMAKE_SOURCE_DIR}/src/binpac.pac
|
||||
${CMAKE_SOURCE_DIR}/src/bro.pac
|
||||
${CMAKE_SOURCE_DIR}/src/binpac_bro.h
|
||||
)
|
||||
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)
|
||||
|
||||
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
|
||||
|
@ -473,18 +367,41 @@ set(bro_SRCS
|
|||
|
||||
3rdparty/sqlite3.c
|
||||
|
||||
plugin/Component.cc
|
||||
plugin/Manager.cc
|
||||
plugin/Plugin.cc
|
||||
|
||||
nb_dns.c
|
||||
digest.h
|
||||
)
|
||||
|
||||
collect_headers(bro_HEADERS ${bro_SRCS})
|
||||
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
|
||||
|
||||
if ( bro_HAVE_OBJECT_LIBRARIES )
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_SUBDIRS})
|
||||
target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
||||
else ()
|
||||
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
|
||||
target_link_libraries(bro ${bro_SUBDIRS} ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
||||
endif ()
|
||||
|
||||
install(TARGETS bro DESTINATION bin)
|
||||
install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base)
|
||||
|
||||
set(BRO_EXE bro
|
||||
CACHE STRING "Bro executable binary" FORCE)
|
||||
|
||||
# Target to create all the autogenerated files.
|
||||
add_custom_target(generate_outputs)
|
||||
add_dependencies(generate_outputs ${bro_ALL_GENERATED_OUTPUTS})
|
||||
|
||||
# Build __load__.bro files for plugins/*.bif.bro.
|
||||
bro_bif_create_loader(bif_loader_plugins ${CMAKE_BINARY_DIR}/scripts/base/bif/plugins)
|
||||
add_dependencies(bif_loader_plugins ${bro_SUBDIRS})
|
||||
add_dependencies(bro bif_loader_plugins)
|
||||
|
||||
# Install *.bif.bro.
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/scripts/base/bif DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base)
|
||||
|
||||
# Make clean removes the bif directory.
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/scripts/base/bif)
|
||||
|
||||
|
|
24
src/Conn.cc
24
src/Conn.cc
|
@ -11,9 +11,10 @@
|
|||
#include "Sessions.h"
|
||||
#include "Reporter.h"
|
||||
#include "Timer.h"
|
||||
#include "PIA.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
#include "binpac.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
|
||||
int arg_do_expire)
|
||||
|
@ -402,16 +403,21 @@ RecordVal* Connection::BuildConnVal()
|
|||
return conn_val;
|
||||
}
|
||||
|
||||
Analyzer* Connection::FindAnalyzer(AnalyzerID id)
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id)
|
||||
{
|
||||
return root_analyzer ? root_analyzer->FindChild(id) : 0;
|
||||
}
|
||||
|
||||
Analyzer* Connection::FindAnalyzer(AnalyzerTag::Tag tag)
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::Tag tag)
|
||||
{
|
||||
return root_analyzer ? root_analyzer->FindChild(tag) : 0;
|
||||
}
|
||||
|
||||
analyzer::Analyzer* Connection::FindAnalyzer(const char* name)
|
||||
{
|
||||
return root_analyzer->FindChild(name);
|
||||
}
|
||||
|
||||
void Connection::AppendAddl(const char* str)
|
||||
{
|
||||
Unref(BuildConnVal());
|
||||
|
@ -540,7 +546,7 @@ Val* Connection::BuildVersionVal(const char* s, int len)
|
|||
}
|
||||
|
||||
int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||
Analyzer* analyzer)
|
||||
analyzer::Analyzer* analyzer)
|
||||
{
|
||||
if ( ! software_version_found && ! software_parse_error )
|
||||
return 1;
|
||||
|
@ -578,7 +584,7 @@ int Connection::VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
|||
}
|
||||
|
||||
int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
||||
const char* full, int len, Analyzer* analyzer)
|
||||
const char* full, int len, analyzer::Analyzer* analyzer)
|
||||
{
|
||||
// Skip leading white space.
|
||||
while ( len && isspace(*full) )
|
||||
|
@ -602,7 +608,7 @@ int Connection::UnparsedVersionFoundEvent(const IPAddr& addr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
|
||||
void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name)
|
||||
{
|
||||
if ( ! f )
|
||||
return;
|
||||
|
@ -615,7 +621,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
|
|||
ConnectionEvent(f, analyzer, vl);
|
||||
}
|
||||
|
||||
void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
|
||||
void Connection::Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2)
|
||||
{
|
||||
if ( ! f )
|
||||
{
|
||||
|
@ -634,7 +640,7 @@ void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
|
|||
ConnectionEvent(f, analyzer, vl);
|
||||
}
|
||||
|
||||
void Connection::ConnectionEvent(EventHandlerPtr f, Analyzer* a, val_list* vl)
|
||||
void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_list* vl)
|
||||
{
|
||||
if ( ! f )
|
||||
{
|
||||
|
@ -929,7 +935,7 @@ error:
|
|||
return false;
|
||||
}
|
||||
|
||||
void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
|
||||
void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia)
|
||||
{
|
||||
root_analyzer = analyzer;
|
||||
primary_PIA = pia;
|
||||
|
|
34
src/Conn.h
34
src/Conn.h
|
@ -11,19 +11,22 @@
|
|||
#include "Serializer.h"
|
||||
#include "PersistenceSerializer.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "AnalyzerTags.h"
|
||||
#include "IPAddr.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
class Connection;
|
||||
class ConnectionTimer;
|
||||
class NetSessions;
|
||||
class LoginConn;
|
||||
class RuleHdrTest;
|
||||
class Specific_RE_Matcher;
|
||||
class TransportLayerAnalyzer;
|
||||
class RuleEndpointState;
|
||||
|
||||
namespace analyzer { class TransportLayerAnalyzer; }
|
||||
|
||||
typedef enum {
|
||||
NUL_IN_LINE,
|
||||
SINGULAR_CR,
|
||||
|
@ -47,7 +50,7 @@ static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1,
|
|||
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
|
||||
}
|
||||
|
||||
class Analyzer;
|
||||
namespace analyzer { class Analyzer; }
|
||||
|
||||
class Connection : public BroObj {
|
||||
public:
|
||||
|
@ -102,8 +105,9 @@ public:
|
|||
|
||||
void FlipRoles();
|
||||
|
||||
Analyzer* FindAnalyzer(AnalyzerID id);
|
||||
Analyzer* FindAnalyzer(AnalyzerTag::Tag tag); // find first in tree.
|
||||
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
|
||||
analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree.
|
||||
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
|
||||
|
||||
TransportProto ConnTransport() const { return proto; }
|
||||
|
||||
|
@ -161,15 +165,15 @@ public:
|
|||
// Raises a software_version_found event based on the
|
||||
// given string (returns false if it's not parseable).
|
||||
int VersionFoundEvent(const IPAddr& addr, const char* s, int len,
|
||||
Analyzer* analyzer = 0);
|
||||
analyzer::Analyzer* analyzer = 0);
|
||||
|
||||
// Raises a software_unparsed_version_found event.
|
||||
int UnparsedVersionFoundEvent(const IPAddr& addr,
|
||||
const char* full_descr, int len, Analyzer* analyzer);
|
||||
const char* full_descr, int len, analyzer::Analyzer* analyzer);
|
||||
|
||||
void Event(EventHandlerPtr f, Analyzer* analyzer, const char* name = 0);
|
||||
void Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
||||
void ConnectionEvent(EventHandlerPtr f, Analyzer* analyzer,
|
||||
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name = 0);
|
||||
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2 = 0);
|
||||
void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer,
|
||||
val_list* vl);
|
||||
|
||||
void Weird(const char* name, const char* addl = "");
|
||||
|
@ -241,9 +245,9 @@ public:
|
|||
void DeleteTimer(double t);
|
||||
|
||||
// Sets the root of the analyzer tree as well as the primary PIA.
|
||||
void SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia);
|
||||
TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
||||
PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||
void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia);
|
||||
analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
||||
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||
|
||||
// Sets the transport protocol in use.
|
||||
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
|
||||
|
@ -314,8 +318,8 @@ protected:
|
|||
string history;
|
||||
uint32 hist_seen;
|
||||
|
||||
TransportLayerAnalyzer* root_analyzer;
|
||||
PIA* primary_PIA;
|
||||
analyzer::TransportLayerAnalyzer* root_analyzer;
|
||||
analyzer::pia::PIA* primary_PIA;
|
||||
|
||||
uint64 uid; // Globally unique connection ID.
|
||||
};
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include "DHCP-binpac.h"
|
||||
|
||||
DHCP_Analyzer_binpac::DHCP_Analyzer_binpac(Connection* conn)
|
||||
: Analyzer(AnalyzerTag::DHCP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DHCP::DHCP_Conn(this);
|
||||
}
|
||||
|
||||
DHCP_Analyzer_binpac::~DHCP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DHCP_Analyzer_binpac::Done()
|
||||
{
|
||||
Analyzer::Done();
|
||||
}
|
||||
|
||||
void DHCP_Analyzer_binpac::DeliverPacket(int len, const u_char* data,
|
||||
bool orig, int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef dhcp_binpac_h
|
||||
#define dhcp_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
|
||||
#include "dhcp_pac.h"
|
||||
|
||||
|
||||
class DHCP_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
DHCP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DHCP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DHCP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return dhcp_request && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::DHCP::DHCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,90 +0,0 @@
|
|||
#include "DNS-binpac.h"
|
||||
#include "TCP_Reassembler.h"
|
||||
|
||||
DNS_UDP_Analyzer_binpac::DNS_UDP_Analyzer_binpac(Connection* conn)
|
||||
: Analyzer(AnalyzerTag::DNS_UDP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DNS::DNS_Conn(this);
|
||||
did_session_done = 0;
|
||||
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
|
||||
network_time + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
|
||||
}
|
||||
|
||||
DNS_UDP_Analyzer_binpac::~DNS_UDP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::Done()
|
||||
{
|
||||
Analyzer::Done();
|
||||
|
||||
if ( ! did_session_done )
|
||||
Event(udp_session_done);
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void DNS_UDP_Analyzer_binpac::ExpireTimer(double t)
|
||||
{
|
||||
// The - 1.0 in the following is to allow 1 second for the
|
||||
// common case of a single request followed by a single reply,
|
||||
// so we don't needlessly set the timer twice in that case.
|
||||
if ( t - Conn()->LastTime() >= dns_session_timeout - 1.0 || terminating )
|
||||
{
|
||||
Event(connection_timeout);
|
||||
sessions->Remove(Conn());
|
||||
}
|
||||
else
|
||||
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
|
||||
t + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
|
||||
}
|
||||
|
||||
DNS_TCP_Analyzer_binpac::DNS_TCP_Analyzer_binpac(Connection* conn)
|
||||
: TCP_ApplicationAnalyzer(AnalyzerTag::DNS_TCP_BINPAC, conn)
|
||||
{
|
||||
interp = new binpac::DNS_on_TCP::DNS_TCP_Conn(this);
|
||||
}
|
||||
|
||||
DNS_TCP_Analyzer_binpac::~DNS_TCP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::Done()
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Done();
|
||||
|
||||
interp->FlowEOF(true);
|
||||
interp->FlowEOF(false);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::EndpointEOF(bool is_orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||
interp->FlowEOF(is_orig);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data,
|
||||
bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||
|
||||
assert(TCP());
|
||||
|
||||
if ( TCP()->IsPartial() || TCP()->HadGap(orig) )
|
||||
// punt-on-partial or stop-on-gap.
|
||||
return;
|
||||
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void DNS_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||
interp->NewGap(orig, len);
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef dns_binpac_h
|
||||
#define dns_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
|
||||
#include "dns_pac.h"
|
||||
|
||||
// FIXME: As the binpac analyer for DNS-TCP and DNS-UDP are currently
|
||||
// structured, we cannot directly combine them into one analyzer. Can we
|
||||
// change that easily? (Ideally, the TCP preprocessing would become a
|
||||
// support-analyzer as it is done for the traditional DNS analyzer.)
|
||||
|
||||
class DNS_UDP_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
DNS_UDP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DNS_UDP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DNS_UDP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
friend class AnalyzerTimer;
|
||||
void ExpireTimer(double t);
|
||||
|
||||
int did_session_done;
|
||||
|
||||
binpac::DNS::DNS_Conn* interp;
|
||||
};
|
||||
|
||||
#include "dns_tcp_pac.h"
|
||||
|
||||
class DNS_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
DNS_TCP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~DNS_TCP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new DNS_TCP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::DNS_on_TCP::DNS_TCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
407
src/DPM.cc
407
src/DPM.cc
|
@ -1,407 +0,0 @@
|
|||
#include "DPM.h"
|
||||
#include "PIA.h"
|
||||
#include "Hash.h"
|
||||
#include "ICMP.h"
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
#include "Val.h"
|
||||
#include "BackDoor.h"
|
||||
#include "InterConn.h"
|
||||
#include "SteppingStone.h"
|
||||
#include "ConnSizeAnalyzer.h"
|
||||
|
||||
|
||||
ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
||||
uint16 _resp_p, uint16 _proto)
|
||||
{
|
||||
if ( _orig == IPAddr(string("0.0.0.0")) )
|
||||
// don't use the IPv4 mapping, use the literal unspecified address
|
||||
// to indicate a wildcard
|
||||
orig = IPAddr(string("::"));
|
||||
else
|
||||
orig = _orig;
|
||||
resp = _resp;
|
||||
resp_p = _resp_p;
|
||||
proto = _proto;
|
||||
}
|
||||
|
||||
ExpectedConn::ExpectedConn(const ExpectedConn& c)
|
||||
{
|
||||
orig = c.orig;
|
||||
resp = c.resp;
|
||||
resp_p = c.resp_p;
|
||||
proto = c.proto;
|
||||
}
|
||||
|
||||
DPM::DPM()
|
||||
: active_analyzers(0), expected_conns_queue(AssignedAnalyzer::compare)
|
||||
{
|
||||
}
|
||||
|
||||
DPM::~DPM()
|
||||
{
|
||||
delete [] active_analyzers;
|
||||
}
|
||||
|
||||
void DPM::PreScriptInit()
|
||||
{
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
{
|
||||
// Create IDs ANALYZER_*.
|
||||
ID* id = install_ID(fmt("ANALYZER_%s",
|
||||
Analyzer::analyzer_configs[i].name),
|
||||
GLOBAL_MODULE_NAME, true, false);
|
||||
assert(id);
|
||||
id->SetVal(new Val(i, TYPE_COUNT));
|
||||
id->SetType(id->ID_Val()->Type()->Ref());
|
||||
}
|
||||
}
|
||||
|
||||
void DPM::PostScriptInit()
|
||||
{
|
||||
active_analyzers = new bool[int(AnalyzerTag::LastAnalyzer)];
|
||||
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
{
|
||||
if ( ! Analyzer::analyzer_configs[i].available )
|
||||
continue;
|
||||
|
||||
active_analyzers[i] = Analyzer::analyzer_configs[i].available();
|
||||
if ( active_analyzers[i] )
|
||||
AddConfig(Analyzer::analyzer_configs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void DPM::AddConfig(const Analyzer::Config& cfg)
|
||||
{
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
HeapLeakChecker::Disabler disabler;
|
||||
#endif
|
||||
|
||||
Val* index = new Val(cfg.tag, TYPE_COUNT);
|
||||
Val* v = dpd_config->Lookup(index);
|
||||
|
||||
#ifdef DEBUG
|
||||
ODesc desc;
|
||||
#endif
|
||||
if ( v )
|
||||
{
|
||||
RecordVal* cfg_record = v->AsRecordVal();
|
||||
Val* ports = cfg_record->Lookup(0);
|
||||
|
||||
if ( ports )
|
||||
{
|
||||
ListVal* plist = ports->AsTableVal()->ConvertToPureList();
|
||||
|
||||
for ( int i = 0; i< plist->Length(); ++i )
|
||||
{
|
||||
PortVal* port = plist->Index(i)->AsPortVal();
|
||||
|
||||
analyzer_map* ports =
|
||||
port->IsTCP() ? &tcp_ports : &udp_ports;
|
||||
|
||||
analyzer_map::iterator j =
|
||||
ports->find(port->Port());
|
||||
|
||||
if ( j == ports->end() )
|
||||
{
|
||||
tag_list* analyzers = new tag_list;
|
||||
analyzers->push_back(cfg.tag);
|
||||
ports->insert(analyzer_map::value_type(port->Port(), analyzers));
|
||||
}
|
||||
else
|
||||
j->second->push_back(cfg.tag);
|
||||
|
||||
#ifdef DEBUG
|
||||
port->Describe(&desc);
|
||||
desc.SP();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s analyzer active on port(s) %s", cfg.name, desc.Description());
|
||||
|
||||
Unref(index);
|
||||
}
|
||||
|
||||
AnalyzerTag::Tag DPM::GetExpected(int proto, const Connection* conn)
|
||||
{
|
||||
if ( ! expected_conns.Length() )
|
||||
return AnalyzerTag::Error;
|
||||
|
||||
ExpectedConn c(conn->OrigAddr(), conn->RespAddr(),
|
||||
ntohs(conn->RespPort()), proto);
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
|
||||
if ( ! a )
|
||||
{
|
||||
// Wildcard for originator.
|
||||
c.orig = IPAddr(string("::"));
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
a = expected_conns.Lookup(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
if ( ! a )
|
||||
return AnalyzerTag::Error;
|
||||
|
||||
// We don't delete it here. It will be expired eventually.
|
||||
return a->analyzer;
|
||||
}
|
||||
|
||||
bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||
const u_char* data)
|
||||
{
|
||||
TCP_Analyzer* tcp = 0;
|
||||
UDP_Analyzer* udp = 0;
|
||||
ICMP_Analyzer* icmp = 0;
|
||||
TransportLayerAnalyzer* root = 0;
|
||||
AnalyzerTag::Tag expected = AnalyzerTag::Error;
|
||||
analyzer_map* ports = 0;
|
||||
PIA* pia = 0;
|
||||
bool analyzed = false;
|
||||
|
||||
switch ( proto ) {
|
||||
|
||||
case TRANSPORT_TCP:
|
||||
root = tcp = new TCP_Analyzer(conn);
|
||||
pia = new PIA_TCP(conn);
|
||||
expected = GetExpected(proto, conn);
|
||||
ports = &tcp_ports;
|
||||
DBG_DPD(conn, "activated TCP analyzer");
|
||||
break;
|
||||
|
||||
case TRANSPORT_UDP:
|
||||
root = udp = new UDP_Analyzer(conn);
|
||||
pia = new PIA_UDP(conn);
|
||||
expected = GetExpected(proto, conn);
|
||||
ports = &udp_ports;
|
||||
DBG_DPD(conn, "activated UDP analyzer");
|
||||
break;
|
||||
|
||||
case TRANSPORT_ICMP: {
|
||||
root = icmp = new ICMP_Analyzer(conn);
|
||||
DBG_DPD(conn, "activated ICMP analyzer");
|
||||
analyzed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reporter->InternalError("unknown protocol");
|
||||
}
|
||||
|
||||
if ( ! root )
|
||||
{
|
||||
DBG_DPD(conn, "cannot build analyzer tree");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Any scheduled analyzer?
|
||||
if ( expected != AnalyzerTag::Error )
|
||||
{
|
||||
Analyzer* analyzer =
|
||||
Analyzer::InstantiateAnalyzer(expected, conn);
|
||||
root->AddChildAnalyzer(analyzer, false);
|
||||
DBG_DPD_ARGS(conn, "activated %s analyzer as scheduled",
|
||||
Analyzer::GetTagName(expected));
|
||||
|
||||
// Hmm... Do we want *just* the expected analyzer, or all
|
||||
// other potential analyzers as well? For now we only take
|
||||
// the scheduled one.
|
||||
}
|
||||
|
||||
else
|
||||
{ // Let's see if it's a port we know.
|
||||
if ( ports && ! dpd_ignore_ports )
|
||||
{
|
||||
analyzer_map::const_iterator i =
|
||||
ports->find(ntohs(conn->RespPort()));
|
||||
|
||||
if ( i != ports->end() )
|
||||
{
|
||||
tag_list* analyzers = i->second;
|
||||
for ( tag_list::const_iterator j = analyzers->begin();
|
||||
j != analyzers->end(); j++ )
|
||||
{
|
||||
Analyzer* analyzer =
|
||||
Analyzer::InstantiateAnalyzer(*j, conn);
|
||||
|
||||
root->AddChildAnalyzer(analyzer, false);
|
||||
DBG_DPD_ARGS(conn, "activated %s analyzer due to port %d", Analyzer::GetTagName(*j), conn->RespPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( tcp )
|
||||
{
|
||||
// We have to decide whether to reassamble the stream.
|
||||
// We turn it on right away if we already have an app-layer
|
||||
// analyzer, reassemble_first_packets is true, or the user
|
||||
// asks us to do so. In all other cases, reassembly may
|
||||
// be turned on later by the TCP PIA.
|
||||
|
||||
bool reass = root->GetChildren().size() ||
|
||||
dpd_reassemble_first_packets ||
|
||||
tcp_content_deliver_all_orig ||
|
||||
tcp_content_deliver_all_resp;
|
||||
|
||||
if ( tcp_contents && ! reass )
|
||||
{
|
||||
PortVal dport(ntohs(conn->RespPort()), TRANSPORT_TCP);
|
||||
Val* result;
|
||||
|
||||
if ( ! reass )
|
||||
reass = tcp_content_delivery_ports_orig->Lookup(&dport);
|
||||
|
||||
if ( ! reass )
|
||||
reass = tcp_content_delivery_ports_resp->Lookup(&dport);
|
||||
}
|
||||
|
||||
if ( reass )
|
||||
tcp->EnableReassembly();
|
||||
|
||||
// Add a BackDoor analyzer if requested. This analyzer
|
||||
// can handle both reassembled and non-reassembled input.
|
||||
if ( BackDoor_Analyzer::Available() )
|
||||
{
|
||||
BackDoor_Analyzer* bd = new BackDoor_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
|
||||
// Add a InterConn analyzer if requested. This analyzer
|
||||
// can handle both reassembled and non-reassembled input.
|
||||
if ( InterConn_Analyzer::Available() )
|
||||
{
|
||||
InterConn_Analyzer* bd = new InterConn_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
|
||||
// Add a SteppingStone analyzer if requested. The port
|
||||
// should really not be hardcoded here, but as it can
|
||||
// handle non-reassembled data, it doesn't really fit into
|
||||
// our general framing ... Better would be to turn it
|
||||
// on *after* we discover we have interactive traffic.
|
||||
uint16 resp_port = ntohs(conn->RespPort());
|
||||
if ( SteppingStone_Analyzer::Available() &&
|
||||
(resp_port == 22 || resp_port == 23 || resp_port == 513) )
|
||||
{
|
||||
AddrVal src(conn->OrigAddr());
|
||||
if ( ! stp_skip_src->Lookup(&src) )
|
||||
{
|
||||
SteppingStone_Analyzer* bd =
|
||||
new SteppingStone_Analyzer(conn);
|
||||
tcp->AddChildAnalyzer(bd, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Add TCPStats analyzer. This needs to see packets so
|
||||
// we cannot add it as a normal child.
|
||||
if ( TCPStats_Analyzer::Available() )
|
||||
tcp->AddChildPacketAnalyzer(new TCPStats_Analyzer(conn));
|
||||
|
||||
// Add ConnSize analyzer. Needs to see packets, not stream.
|
||||
if ( ConnSize_Analyzer::Available() )
|
||||
tcp->AddChildPacketAnalyzer(new ConnSize_Analyzer(conn));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( ConnSize_Analyzer::Available() )
|
||||
root->AddChildAnalyzer(new ConnSize_Analyzer(conn), false);
|
||||
}
|
||||
|
||||
if ( pia )
|
||||
root->AddChildAnalyzer(pia->AsAnalyzer(), false);
|
||||
|
||||
if ( root->GetChildren().size() )
|
||||
analyzed = true;
|
||||
|
||||
conn->SetRootAnalyzer(root, pia);
|
||||
root->Init();
|
||||
root->InitChildren();
|
||||
|
||||
if ( ! analyzed )
|
||||
conn->SetLifetime(non_analyzed_lifetime);
|
||||
|
||||
if ( expected != AnalyzerTag::Error )
|
||||
conn->Event(expected_connection_seen, 0,
|
||||
new Val(expected, TYPE_COUNT));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DPM::ExpectConnection(const IPAddr& orig, const IPAddr& resp,
|
||||
uint16 resp_p,
|
||||
TransportProto proto, AnalyzerTag::Tag analyzer,
|
||||
double timeout, void* cookie)
|
||||
{
|
||||
// Use the chance to see if the oldest entry is already expired.
|
||||
if ( expected_conns_queue.size() )
|
||||
{
|
||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
||||
if ( a->timeout < network_time )
|
||||
{
|
||||
if ( ! a->deleted )
|
||||
{
|
||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
expected_conns_queue.pop();
|
||||
|
||||
DBG_LOG(DBG_DPD, "Expired expected %s analyzer for %s",
|
||||
Analyzer::GetTagName(analyzer),
|
||||
fmt_conn_id(a->conn.orig, 0,
|
||||
a->conn.resp,
|
||||
a->conn.resp_p));
|
||||
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedConn c(orig, resp, resp_p, proto);
|
||||
|
||||
HashKey* key = BuildExpectedConnHashKey(c);
|
||||
|
||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
||||
|
||||
if ( a )
|
||||
a->deleted = true;
|
||||
|
||||
a = new AssignedAnalyzer(c);
|
||||
|
||||
a->analyzer = analyzer;
|
||||
a->cookie = cookie;
|
||||
a->timeout = network_time + timeout;
|
||||
a->deleted = false;
|
||||
|
||||
expected_conns.Insert(key, a);
|
||||
expected_conns_queue.push(a);
|
||||
delete key;
|
||||
}
|
||||
|
||||
void DPM::Done()
|
||||
{
|
||||
// Clean up expected-connection table.
|
||||
while ( expected_conns_queue.size() )
|
||||
{
|
||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
||||
if ( ! a->deleted )
|
||||
{
|
||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
||||
expected_conns.Remove(key);
|
||||
delete key;
|
||||
}
|
||||
|
||||
expected_conns_queue.pop();
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
131
src/DPM.h
131
src/DPM.h
|
@ -1,131 +0,0 @@
|
|||
// The central management unit for dynamic analyzer selection.
|
||||
|
||||
#ifndef DPM_H
|
||||
#define DPM_H
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "Dict.h"
|
||||
#include "net_util.h"
|
||||
|
||||
// DPM debug logging, which includes the connection id into the message.
|
||||
#ifdef DEBUG
|
||||
# define DBG_DPD(conn, txt) \
|
||||
DBG_LOG(DBG_DPD, "%s " txt, \
|
||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||
conn->RespAddr(), ntohs(conn->RespPort())));
|
||||
# define DBG_DPD_ARGS(conn, fmt, args...) \
|
||||
DBG_LOG(DBG_DPD, "%s " fmt, \
|
||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||
conn->RespAddr(), ntohs(conn->RespPort())), ##args);
|
||||
#else
|
||||
# define DBG_DPD(conn, txt)
|
||||
# define DBG_DPD_ARGS(conn, fmt, args...)
|
||||
#endif
|
||||
|
||||
// Map to assign expected connections to analyzers.
|
||||
class ExpectedConn {
|
||||
public:
|
||||
ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
||||
uint16 _resp_p, uint16 _proto);
|
||||
|
||||
ExpectedConn(const ExpectedConn& c);
|
||||
|
||||
IPAddr orig;
|
||||
IPAddr resp;
|
||||
uint16 resp_p;
|
||||
uint16 proto;
|
||||
};
|
||||
|
||||
// Associates an analyzer for an expected future connection.
|
||||
class AssignedAnalyzer {
|
||||
public:
|
||||
AssignedAnalyzer(const ExpectedConn& c)
|
||||
: conn(c)
|
||||
{
|
||||
}
|
||||
|
||||
ExpectedConn conn;
|
||||
AnalyzerTag::Tag analyzer;
|
||||
double timeout;
|
||||
void* cookie;
|
||||
bool deleted;
|
||||
|
||||
static bool compare(const AssignedAnalyzer* a1, const AssignedAnalyzer* a2)
|
||||
{ return a1->timeout > a2->timeout; }
|
||||
};
|
||||
|
||||
declare(PDict, AssignedAnalyzer);
|
||||
|
||||
class DPM {
|
||||
public:
|
||||
DPM();
|
||||
~DPM();
|
||||
|
||||
// Setup analyzer config.
|
||||
void PreScriptInit(); // To be called before scripts are parsed ...
|
||||
void PostScriptInit(); // ... and after.
|
||||
|
||||
// Given info about the first packet, build initial analyzer tree.
|
||||
//
|
||||
// It would be more flexible if we simply pass in the IP header
|
||||
// and then extract the information we need. However, when this
|
||||
// method is called from the session management, protocol and ports
|
||||
// have already been extracted there and it would be a waste to do
|
||||
// it again.
|
||||
//
|
||||
// Returns 0 if we can't build a tree (e.g., because the necessary
|
||||
// analyzers have not been converted to the DPM framework yet...)
|
||||
|
||||
bool BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||
const u_char* data);
|
||||
|
||||
// Schedules a particular analyzer for an upcoming connection.
|
||||
// 0 acts as a wildcard for orig. (Cookie is currently unused.
|
||||
// Eventually, we may pass it on to the analyzer).
|
||||
void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
||||
TransportProto proto, AnalyzerTag::Tag analyzer,
|
||||
double timeout, void* cookie);
|
||||
|
||||
// Activates signature matching for protocol detection. (Called when an
|
||||
// DPM signatures is found.)
|
||||
void ActivateSigs() { sigs_activated = true; }
|
||||
bool SigsActivated() const { return sigs_activated; }
|
||||
|
||||
void Done();
|
||||
|
||||
private:
|
||||
// Convert script-level config into internal data structures.
|
||||
void AddConfig(const Analyzer::Config& tag);
|
||||
|
||||
// Return analyzer if any has been scheduled with ExpectConnection()
|
||||
// AnalyzerTag::::Error if none.
|
||||
AnalyzerTag::Tag GetExpected(int proto, const Connection* conn);
|
||||
|
||||
// Mappings of destination port to analyzer.
|
||||
typedef list<AnalyzerTag::Tag> tag_list;
|
||||
typedef map<uint32, tag_list*> analyzer_map;
|
||||
analyzer_map tcp_ports;
|
||||
analyzer_map udp_ports;
|
||||
|
||||
// Array of bools indicating whether an analyzer is activated,
|
||||
// indexed by AnalyzerTag::Tag.
|
||||
bool* active_analyzers;
|
||||
|
||||
// True if signature-matching has been activated.
|
||||
bool sigs_activated;
|
||||
|
||||
PDict(AssignedAnalyzer) expected_conns;
|
||||
|
||||
typedef priority_queue<
|
||||
AssignedAnalyzer*,
|
||||
vector<AssignedAnalyzer*>,
|
||||
bool (*)(const AssignedAnalyzer*,
|
||||
const AssignedAnalyzer*)> conn_queue;
|
||||
conn_queue expected_conns_queue;
|
||||
};
|
||||
|
||||
extern DPM* dpm;
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@ enum DebugStream {
|
|||
DBG_STRING, // String code
|
||||
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
||||
DBG_MAINLOOP, // Main IOSource loop
|
||||
DBG_DPD, // Dynamic application detection framework
|
||||
DBG_ANALYZER, // Analyzer framework
|
||||
DBG_TM, // Time-machine packet input via Brocolli
|
||||
DBG_LOGGING, // Logging streams
|
||||
DBG_INPUT, // Input streams
|
||||
|
|
|
@ -13,7 +13,7 @@ int num_events_queued = 0;
|
|||
int num_events_dispatched = 0;
|
||||
|
||||
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
||||
SourceID arg_src, AnalyzerID arg_aid, TimerMgr* arg_mgr,
|
||||
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
||||
BroObj* arg_obj)
|
||||
{
|
||||
handler = arg_handler;
|
||||
|
|
16
src/Event.h
16
src/Event.h
|
@ -5,14 +5,16 @@
|
|||
|
||||
#include "EventRegistry.h"
|
||||
#include "Serializer.h"
|
||||
#include "AnalyzerTags.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
|
||||
class EventMgr;
|
||||
|
||||
class Event : public BroObj {
|
||||
public:
|
||||
Event(EventHandlerPtr handler, val_list* args,
|
||||
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||
~Event();
|
||||
|
||||
|
@ -20,7 +22,7 @@ public:
|
|||
Event* NextEvent() const { return next_event; }
|
||||
|
||||
SourceID Source() const { return src; }
|
||||
AnalyzerID Analyzer() const { return aid; }
|
||||
analyzer::ID Analyzer() const { return aid; }
|
||||
TimerMgr* Mgr() const { return mgr; }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
|
@ -62,7 +64,7 @@ protected:
|
|||
EventHandlerPtr handler;
|
||||
val_list* args;
|
||||
SourceID src;
|
||||
AnalyzerID aid;
|
||||
analyzer::ID aid;
|
||||
TimerMgr* mgr;
|
||||
BroObj* obj;
|
||||
Event* next_event;
|
||||
|
@ -77,7 +79,7 @@ public:
|
|||
~EventMgr();
|
||||
|
||||
void QueueEvent(EventHandlerPtr h, val_list* vl,
|
||||
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0)
|
||||
{
|
||||
if ( h )
|
||||
|
@ -105,7 +107,7 @@ public:
|
|||
|
||||
// Returns the ID of the analyzer which raised the last event, or 0 if
|
||||
// non-analyzer event.
|
||||
AnalyzerID CurrentAnalyzer() const { return current_aid; }
|
||||
analyzer::ID CurrentAnalyzer() const { return current_aid; }
|
||||
|
||||
// Returns the timer mgr associated with the last raised event.
|
||||
TimerMgr* CurrentTimerMgr() const { return current_mgr; }
|
||||
|
@ -124,7 +126,7 @@ protected:
|
|||
Event* head;
|
||||
Event* tail;
|
||||
SourceID current_src;
|
||||
AnalyzerID current_aid;
|
||||
analyzer::ID current_aid;
|
||||
TimerMgr* current_mgr;
|
||||
RecordVal* src_val;
|
||||
bool draining;
|
||||
|
|
|
@ -10,7 +10,6 @@ EventHandler::EventHandler(const char* arg_name)
|
|||
used = false;
|
||||
local = 0;
|
||||
type = 0;
|
||||
group = 0;
|
||||
error_handler = false;
|
||||
enabled = true;
|
||||
}
|
||||
|
@ -19,7 +18,6 @@ EventHandler::~EventHandler()
|
|||
{
|
||||
Unref(local);
|
||||
delete [] name;
|
||||
delete [] group;
|
||||
}
|
||||
|
||||
EventHandler::operator bool() const
|
||||
|
|
|
@ -41,10 +41,6 @@ public:
|
|||
void SetErrorHandler() { error_handler = true; }
|
||||
bool ErrorHandler() { return error_handler; }
|
||||
|
||||
const char* Group() { return group; }
|
||||
void SetGroup(const char* arg_group)
|
||||
{ group = copy_string(arg_group); }
|
||||
|
||||
void SetEnable(bool arg_enable) { enabled = arg_enable; }
|
||||
|
||||
// We don't serialize the handler(s) itself here, but
|
||||
|
@ -54,7 +50,6 @@ public:
|
|||
|
||||
private:
|
||||
const char* name;
|
||||
const char* group;
|
||||
Func* local;
|
||||
FuncType* type;
|
||||
bool used; // this handler is indeed used somewhere
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "Val.h"
|
||||
#include "Analyzer.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
#include "EventLauncher.h"
|
||||
#include "Event.h"
|
||||
#include "NetVar.h"
|
||||
#include "Conn.h"
|
||||
|
||||
#include "event.bif.func_def"
|
||||
|
|
|
@ -80,20 +80,13 @@ void EventRegistry::PrintDebug()
|
|||
while ( (v = handlers.NextEntry(k, c)) )
|
||||
{
|
||||
delete k;
|
||||
fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(),
|
||||
v->LocalHandler()? "local" : "no");
|
||||
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
|
||||
v->LocalHandler()? "local" : "no",
|
||||
*v ? "active" : "not active"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void EventRegistry::SetGroup(const char* name, const char* group)
|
||||
{
|
||||
EventHandler* eh = Lookup(name);
|
||||
if ( ! eh )
|
||||
reporter->InternalError("unknown event handler in SetGroup()");
|
||||
|
||||
eh->SetGroup(group);
|
||||
}
|
||||
|
||||
void EventRegistry::SetErrorHandler(const char* name)
|
||||
{
|
||||
EventHandler* eh = Lookup(name);
|
||||
|
@ -103,18 +96,3 @@ void EventRegistry::SetErrorHandler(const char* name)
|
|||
eh->SetErrorHandler();
|
||||
}
|
||||
|
||||
void EventRegistry::EnableGroup(const char* group, bool enable)
|
||||
{
|
||||
IterCookie* c = handlers.InitForIteration();
|
||||
|
||||
HashKey* k;
|
||||
EventHandler* v;
|
||||
while ( (v = handlers.NextEntry(k, c)) )
|
||||
{
|
||||
delete k;
|
||||
|
||||
if ( v->Group() && strcmp(v->Group(), group) == 0 )
|
||||
v->SetEnable(enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,17 +26,11 @@ public:
|
|||
typedef PList(constchar) string_list;
|
||||
string_list* Match(RE_Matcher* pattern);
|
||||
|
||||
// Associates a group with the given event.
|
||||
void SetGroup(const char* name, const char* group);
|
||||
|
||||
// Marks a handler as handling errors. Error handler will not be called
|
||||
// recursively to avoid infinite loops in case they trigger an error
|
||||
// themselves.
|
||||
void SetErrorHandler(const char* name);
|
||||
|
||||
// Enable/disable all members of the group.
|
||||
void EnableGroup(const char* group, bool enable);
|
||||
|
||||
string_list* UnusedHandlers();
|
||||
string_list* UsedHandlers();
|
||||
void PrintDebug();
|
||||
|
|
167
src/Expr.cc
167
src/Expr.cc
|
@ -3320,12 +3320,20 @@ bool HasFieldExpr::DoUnserialize(UnserialInfo* info)
|
|||
return UNSERIALIZE(¬_used) && UNSERIALIZE_STR(&field_name, 0) && UNSERIALIZE(&field);
|
||||
}
|
||||
|
||||
RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list)
|
||||
RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list,
|
||||
BroType* arg_type)
|
||||
: UnaryExpr(EXPR_RECORD_CONSTRUCTOR, constructor_list)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( arg_type && arg_type->Tag() != TYPE_RECORD )
|
||||
{
|
||||
Error("bad record constructor type", arg_type);
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
// Spin through the list, which should be comprised of
|
||||
// either record's or record-field-assign, and build up a
|
||||
// record type to associate with this constructor.
|
||||
|
@ -3365,7 +3373,17 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list)
|
|||
}
|
||||
}
|
||||
|
||||
SetType(new RecordType(record_types));
|
||||
ctor_type = new RecordType(record_types);
|
||||
|
||||
if ( arg_type )
|
||||
SetType(arg_type->Ref());
|
||||
else
|
||||
SetType(ctor_type->Ref());
|
||||
}
|
||||
|
||||
RecordConstructorExpr::~RecordConstructorExpr()
|
||||
{
|
||||
Unref(ctor_type);
|
||||
}
|
||||
|
||||
Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
||||
|
@ -3391,7 +3409,7 @@ Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
|||
Val* RecordConstructorExpr::Fold(Val* v) const
|
||||
{
|
||||
ListVal* lv = v->AsListVal();
|
||||
RecordType* rt = type->AsRecordType();
|
||||
RecordType* rt = ctor_type->AsRecordType();
|
||||
|
||||
if ( lv->Length() != rt->NumFields() )
|
||||
Internal("inconsistency evaluating record constructor");
|
||||
|
@ -3401,6 +3419,19 @@ Val* RecordConstructorExpr::Fold(Val* v) const
|
|||
for ( int i = 0; i < lv->Length(); ++i )
|
||||
rv->Assign(i, lv->Index(i)->Ref());
|
||||
|
||||
if ( ! same_type(rt, type) )
|
||||
{
|
||||
RecordVal* new_val = rv->CoerceTo(type->AsRecordType());
|
||||
|
||||
if ( new_val )
|
||||
{
|
||||
Unref(rv);
|
||||
rv = new_val;
|
||||
}
|
||||
else
|
||||
Internal("record constructor coercion failed");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -3416,22 +3447,39 @@ IMPLEMENT_SERIAL(RecordConstructorExpr, SER_RECORD_CONSTRUCTOR_EXPR);
|
|||
bool RecordConstructorExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_RECORD_CONSTRUCTOR_EXPR, UnaryExpr);
|
||||
SERIALIZE_OPTIONAL(ctor_type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecordConstructorExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
BroType* t = 0;
|
||||
UNSERIALIZE_OPTIONAL(t, RecordType::Unserialize(info));
|
||||
ctor_type = t->AsRecordType();
|
||||
return true;
|
||||
}
|
||||
|
||||
TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
||||
attr_list* arg_attrs)
|
||||
attr_list* arg_attrs, BroType* arg_type)
|
||||
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, constructor_list)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( arg_type )
|
||||
{
|
||||
if ( ! arg_type->IsTable() )
|
||||
{
|
||||
Error("bad table constructor type", arg_type);
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
SetType(arg_type->Ref());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( constructor_list->Exprs().length() == 0 )
|
||||
SetType(new TableType(new TypeList(base_type(TYPE_ANY)), 0));
|
||||
else
|
||||
|
@ -3445,8 +3493,43 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
|||
type->AsTableType()->IsSet() )
|
||||
SetError("values in table(...) constructor do not specify a table");
|
||||
}
|
||||
}
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
|
||||
type_list* indices = type->AsTableType()->Indices()->Types();
|
||||
const expr_list& cle = constructor_list->Exprs();
|
||||
|
||||
// check and promote all index expressions in ctor list
|
||||
loop_over_list(cle, i)
|
||||
{
|
||||
if ( cle[i]->Tag() != EXPR_ASSIGN )
|
||||
continue;
|
||||
|
||||
Expr* idx_expr = cle[i]->AsAssignExpr()->Op1();
|
||||
|
||||
if ( idx_expr->Tag() != EXPR_LIST )
|
||||
continue;
|
||||
|
||||
expr_list& idx_exprs = idx_expr->AsListExpr()->Exprs();
|
||||
|
||||
if ( idx_exprs.length() != indices->length() )
|
||||
continue;
|
||||
|
||||
loop_over_list(idx_exprs, j)
|
||||
{
|
||||
Expr* idx = idx_exprs[j];
|
||||
|
||||
if ( check_and_promote_expr(idx, (*indices)[j]) )
|
||||
{
|
||||
if ( idx != idx_exprs[j] )
|
||||
idx_exprs.replace(j, idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
ExprError("inconsistent types in table constructor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Val* TableConstructorExpr::Eval(Frame* f) const
|
||||
|
@ -3502,16 +3585,30 @@ bool TableConstructorExpr::DoUnserialize(UnserialInfo* info)
|
|||
}
|
||||
|
||||
SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
||||
attr_list* arg_attrs)
|
||||
attr_list* arg_attrs, BroType* arg_type)
|
||||
: UnaryExpr(EXPR_SET_CONSTRUCTOR, constructor_list)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( arg_type )
|
||||
{
|
||||
if ( ! arg_type->IsSet() )
|
||||
{
|
||||
Error("bad set constructor type", arg_type);
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
SetType(arg_type->Ref());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( constructor_list->Exprs().length() == 0 )
|
||||
SetType(new ::SetType(new TypeList(base_type(TYPE_ANY)), 0));
|
||||
else
|
||||
SetType(init_type(constructor_list));
|
||||
}
|
||||
|
||||
if ( ! type )
|
||||
SetError();
|
||||
|
@ -3520,6 +3617,37 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
|||
SetError("values in set(...) constructor do not specify a set");
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
|
||||
type_list* indices = type->AsTableType()->Indices()->Types();
|
||||
expr_list& cle = constructor_list->Exprs();
|
||||
|
||||
if ( indices->length() == 1 )
|
||||
{
|
||||
if ( ! check_and_promote_exprs_to_type(constructor_list,
|
||||
(*indices)[0]) )
|
||||
ExprError("inconsistent type in set constructor");
|
||||
}
|
||||
|
||||
else if ( indices->length() > 1 )
|
||||
{
|
||||
// Check/promote each expression in composite index.
|
||||
loop_over_list(cle, i)
|
||||
{
|
||||
Expr* ce = cle[i];
|
||||
ListExpr* le = ce->AsListExpr();
|
||||
|
||||
if ( ce->Tag() == EXPR_LIST &&
|
||||
check_and_promote_exprs(le, type->AsTableType()->Indices()) )
|
||||
{
|
||||
if ( le != cle[i] )
|
||||
cle.replace(i, le);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ExprError("inconsistent types in set constructor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Val* SetConstructorExpr::Eval(Frame* f) const
|
||||
|
@ -3590,12 +3718,26 @@ bool SetConstructorExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list)
|
||||
VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list,
|
||||
BroType* arg_type)
|
||||
: UnaryExpr(EXPR_VECTOR_CONSTRUCTOR, constructor_list)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( arg_type )
|
||||
{
|
||||
if ( arg_type->Tag() != TYPE_VECTOR )
|
||||
{
|
||||
Error("bad vector constructor type", arg_type);
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
SetType(arg_type->Ref());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( constructor_list->Exprs().length() == 0 )
|
||||
{
|
||||
// vector().
|
||||
|
@ -3604,17 +3746,22 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list)
|
|||
}
|
||||
|
||||
BroType* t = merge_type_list(constructor_list);
|
||||
|
||||
if ( t )
|
||||
{
|
||||
SetType(new VectorType(t->Ref()));
|
||||
|
||||
if ( ! check_and_promote_exprs_to_type(constructor_list, t) )
|
||||
ExprError("inconsistent types in vector constructor");
|
||||
|
||||
Unref(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! check_and_promote_exprs_to_type(constructor_list,
|
||||
type->AsVectorType()->YieldType()) )
|
||||
ExprError("inconsistent types in vector constructor");
|
||||
}
|
||||
|
||||
Val* VectorConstructorExpr::Eval(Frame* f) const
|
||||
|
|
40
src/Expr.h
40
src/Expr.h
|
@ -57,6 +57,8 @@ extern const char* expr_name(BroExprTag t);
|
|||
class Stmt;
|
||||
class Frame;
|
||||
class ListExpr;
|
||||
class NameExpr;
|
||||
class AssignExpr;
|
||||
class CallExpr;
|
||||
class EventExpr;
|
||||
|
||||
|
@ -159,12 +161,37 @@ public:
|
|||
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
|
||||
return (const ListExpr*) this;
|
||||
}
|
||||
|
||||
ListExpr* AsListExpr()
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
|
||||
return (ListExpr*) this;
|
||||
}
|
||||
|
||||
const NameExpr* AsNameExpr() const
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_NAME, "ExprVal::AsNameExpr", expr_name)
|
||||
return (const NameExpr*) this;
|
||||
}
|
||||
|
||||
NameExpr* AsNameExpr()
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_NAME, "ExprVal::AsNameExpr", expr_name)
|
||||
return (NameExpr*) this;
|
||||
}
|
||||
|
||||
const AssignExpr* AsAssignExpr() const
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
||||
return (const AssignExpr*) this;
|
||||
}
|
||||
|
||||
AssignExpr* AsAssignExpr()
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
||||
return (AssignExpr*) this;
|
||||
}
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
|
||||
bool Serialize(SerialInfo* info) const;
|
||||
|
@ -729,7 +756,8 @@ protected:
|
|||
|
||||
class RecordConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
RecordConstructorExpr(ListExpr* constructor_list);
|
||||
RecordConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
||||
~RecordConstructorExpr();
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -741,11 +769,14 @@ protected:
|
|||
void ExprDescribe(ODesc* d) const;
|
||||
|
||||
DECLARE_SERIAL(RecordConstructorExpr);
|
||||
|
||||
RecordType* ctor_type; // type inferred from the ctor expression list args
|
||||
};
|
||||
|
||||
class TableConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
||||
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||
BroType* arg_type = 0);
|
||||
~TableConstructorExpr() { Unref(attrs); }
|
||||
|
||||
Attributes* Attrs() { return attrs; }
|
||||
|
@ -767,7 +798,8 @@ protected:
|
|||
|
||||
class SetConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
||||
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||
BroType* arg_type = 0);
|
||||
~SetConstructorExpr() { Unref(attrs); }
|
||||
|
||||
Attributes* Attrs() { return attrs; }
|
||||
|
@ -789,7 +821,7 @@ protected:
|
|||
|
||||
class VectorConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
VectorConstructorExpr(ListExpr* constructor_list);
|
||||
VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
||||
|
||||
Val* Eval(Frame* f) const;
|
||||
|
||||
|
|
30
src/Finger.h
30
src/Finger.h
|
@ -1,30 +0,0 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef finger_h
|
||||
#define finger_h
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
class ContentLine_Analyzer;
|
||||
|
||||
class Finger_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
Finger_Analyzer(Connection* conn);
|
||||
virtual ~Finger_Analyzer() {}
|
||||
|
||||
virtual void Done();
|
||||
// Line-based input.
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new Finger_Analyzer(conn); }
|
||||
|
||||
static bool Available() { return finger_request || finger_reply; }
|
||||
|
||||
protected:
|
||||
ContentLine_Analyzer* content_line_orig;
|
||||
ContentLine_Analyzer* content_line_resp;
|
||||
int did_deliver;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "FlowSrc.h"
|
||||
#include "Net.h"
|
||||
#include "netflow_pac.h"
|
||||
#include "analyzer/protocol/netflow/netflow_pac.h"
|
||||
#include <errno.h>
|
||||
|
||||
FlowSrc::FlowSrc()
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "Func.h"
|
||||
#include "Frame.h"
|
||||
#include "Var.h"
|
||||
#include "Login.h"
|
||||
#include "analyzer/protocol/login/Login.h"
|
||||
#include "Sessions.h"
|
||||
#include "RE.h"
|
||||
#include "Serializer.h"
|
||||
|
@ -564,7 +564,6 @@ void builtin_error(const char* msg, BroObj* arg)
|
|||
|
||||
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();
|
||||
|
|
1
src/H3.h
1
src/H3.h
|
@ -66,7 +66,6 @@ template<class T, int N> class H3 {
|
|||
T byte_lookup[N][H3_BYTE_RANGE];
|
||||
public:
|
||||
H3();
|
||||
~H3() { free(byte_lookup); }
|
||||
T operator()(const void* data, size_t size, size_t offset = 0) const
|
||||
{
|
||||
const unsigned char *p = static_cast<const unsigned char*>(data);
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
#include "HTTP-binpac.h"
|
||||
#include "TCP_Reassembler.h"
|
||||
|
||||
HTTP_Analyzer_binpac::HTTP_Analyzer_binpac(Connection *c)
|
||||
: TCP_ApplicationAnalyzer(AnalyzerTag::HTTP_BINPAC, c)
|
||||
{
|
||||
interp = new binpac::HTTP::HTTP_Conn(this);
|
||||
}
|
||||
|
||||
HTTP_Analyzer_binpac::~HTTP_Analyzer_binpac()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::Done()
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Done();
|
||||
|
||||
interp->FlowEOF(true);
|
||||
interp->FlowEOF(false);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::EndpointEOF(bool is_orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||
interp->FlowEOF(is_orig);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||
|
||||
assert(TCP());
|
||||
|
||||
if ( TCP()->IsPartial() )
|
||||
// punt on partial.
|
||||
return;
|
||||
|
||||
interp->NewData(orig, data, data + len);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||
interp->NewGap(orig, len);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef http_binpac_h
|
||||
#define http_binpac_h
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
#include "http_pac.h"
|
||||
|
||||
class HTTP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
HTTP_Analyzer_binpac(Connection* conn);
|
||||
virtual ~HTTP_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new HTTP_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return (http_request || http_reply) && FLAGS_use_binpac; }
|
||||
|
||||
protected:
|
||||
binpac::HTTP::HTTP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
16
src/ID.cc
16
src/ID.cc
|
@ -221,21 +221,7 @@ void ID::UpdateValAttrs()
|
|||
|
||||
if ( Type()->Tag() == TYPE_FUNC )
|
||||
{
|
||||
Attr* attr = attrs->FindAttr(ATTR_GROUP);
|
||||
|
||||
if ( attr )
|
||||
{
|
||||
Val* group = attr->AttrExpr()->ExprVal();
|
||||
if ( group )
|
||||
{
|
||||
if ( group->Type()->Tag() == TYPE_STRING )
|
||||
event_registry->SetGroup(Name(), group->AsString()->CheckString());
|
||||
else
|
||||
Error("&group attribute takes string");
|
||||
}
|
||||
}
|
||||
|
||||
attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
|
||||
Attr* attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
|
||||
|
||||
if ( attr )
|
||||
event_registry->SetErrorHandler(Name());
|
||||
|
|
1
src/ID.h
1
src/ID.h
|
@ -26,6 +26,7 @@ public:
|
|||
bool IsGlobal() const { return scope != SCOPE_FUNCTION; }
|
||||
|
||||
bool IsExport() const { return is_export; }
|
||||
void SetExport() { is_export = true; }
|
||||
|
||||
string ModuleName() const;
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include "IPAddr.h"
|
||||
#include "Reporter.h"
|
||||
#include "Conn.h"
|
||||
#include "DPM.h"
|
||||
#include "bro_inet_ntop.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0xff, 0xff };
|
||||
|
@ -44,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id)
|
|||
return new HashKey(&key, sizeof(key));
|
||||
}
|
||||
|
||||
HashKey* BuildExpectedConnHashKey(const ExpectedConn& c)
|
||||
{
|
||||
struct {
|
||||
in6_addr orig;
|
||||
in6_addr resp;
|
||||
uint16 resp_p;
|
||||
uint16 proto;
|
||||
} key;
|
||||
|
||||
key.orig = c.orig.in6;
|
||||
key.resp = c.resp.in6;
|
||||
key.resp_p = c.resp_p;
|
||||
key.proto = c.proto;
|
||||
|
||||
return new HashKey(&key, sizeof(key));
|
||||
}
|
||||
|
||||
void IPAddr::Mask(int top_bits_to_keep)
|
||||
{
|
||||
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "threading/SerialTypes.h"
|
||||
|
||||
struct ConnID;
|
||||
class ExpectedConn;
|
||||
namespace analyzer { class ExpectedConn; }
|
||||
|
||||
typedef in_addr in4_addr;
|
||||
|
||||
|
@ -363,7 +363,6 @@ public:
|
|||
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
||||
|
||||
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||
friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
|
||||
|
||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
||||
|
||||
|
@ -452,11 +451,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
|
|||
*/
|
||||
HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||
|
||||
/**
|
||||
* Returns a hash key for a given ExpectedConn instance. Passes ownership to caller.
|
||||
*/
|
||||
HashKey* BuildExpectedConnHashKey(const ExpectedConn& c);
|
||||
|
||||
/**
|
||||
* Class storing both IPv4 and IPv6 prefixes
|
||||
* (i.e., \c 192.168.1.1/16 and \c FD00::/8.
|
||||
|
|
58
src/Modbus.h
58
src/Modbus.h
|
@ -1,58 +0,0 @@
|
|||
#ifndef MODBUS_H
|
||||
#define MODBUS_H
|
||||
|
||||
#include "TCP.h"
|
||||
#include "modbus_pac.h"
|
||||
|
||||
class ModbusTCP_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
ModbusTCP_Analyzer(Connection* conn);
|
||||
virtual ~ModbusTCP_Analyzer();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
virtual void Undelivered(int seq, int len, bool orig);
|
||||
virtual void EndpointEOF(bool is_orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new ModbusTCP_Analyzer(conn); }
|
||||
|
||||
// Put event names in this function
|
||||
static bool Available()
|
||||
{
|
||||
return modbus_message
|
||||
| modbus_exception
|
||||
| modbus_read_coils_request
|
||||
| modbus_read_coils_response
|
||||
| modbus_read_discrete_inputs_request
|
||||
| modbus_read_discrete_inputs_response
|
||||
| modbus_read_holding_registers_request
|
||||
| modbus_read_holding_registers_response
|
||||
| modbus_read_input_registers_request
|
||||
| modbus_read_input_registers_response
|
||||
| modbus_write_single_coil_request
|
||||
| modbus_write_single_coil_response
|
||||
| modbus_write_single_register_request
|
||||
| modbus_write_single_register_response
|
||||
| modbus_write_multiple_coils_request
|
||||
| modbus_write_multiple_coils_response
|
||||
| modbus_write_multiple_registers_request
|
||||
| modbus_write_multiple_registers_response
|
||||
| modbus_read_file_record_request
|
||||
| modbus_read_file_record_response
|
||||
| modbus_write_file_record_request
|
||||
| modbus_write_file_record_response
|
||||
| modbus_mask_write_register_request
|
||||
| modbus_mask_write_register_response
|
||||
| modbus_read_write_multiple_registers_request
|
||||
| modbus_read_write_multiple_registers_response
|
||||
| modbus_read_fifo_queue_request
|
||||
| modbus_read_fifo_queue_response;
|
||||
}
|
||||
|
||||
protected:
|
||||
binpac::ModbusTCP::ModbusTCP_Conn* interp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -94,7 +94,6 @@ RecordType* http_stats_rec;
|
|||
RecordType* http_message_stat;
|
||||
int truncate_http_URI;
|
||||
|
||||
int pm_request;
|
||||
RecordType* pm_mapping;
|
||||
TableType* pm_mappings;
|
||||
RecordType* pm_port_request;
|
||||
|
@ -209,7 +208,6 @@ TableType* irc_join_list;
|
|||
RecordType* irc_join_info;
|
||||
TableVal* irc_servers;
|
||||
|
||||
TableVal* dpd_config;
|
||||
int dpd_reassemble_first_packets;
|
||||
int dpd_buffer_size;
|
||||
int dpd_match_only_beginning;
|
||||
|
@ -423,14 +421,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 +516,6 @@ void init_net_var()
|
|||
opt_internal_double("remote_trace_sync_interval");
|
||||
remote_trace_sync_peers = opt_internal_int("remote_trace_sync_peers");
|
||||
|
||||
dpd_config = internal_val("dpd_config")->AsTableVal();
|
||||
dpd_reassemble_first_packets =
|
||||
opt_internal_int("dpd_reassemble_first_packets");
|
||||
dpd_buffer_size = opt_internal_int("dpd_buffer_size");
|
||||
|
|
|
@ -97,7 +97,6 @@ extern RecordType* http_stats_rec;
|
|||
extern RecordType* http_message_stat;
|
||||
extern int truncate_http_URI;
|
||||
|
||||
extern int pm_request;
|
||||
extern RecordType* pm_mapping;
|
||||
extern TableType* pm_mappings;
|
||||
extern RecordType* pm_port_request;
|
||||
|
@ -213,7 +212,6 @@ extern TableType* irc_join_list;
|
|||
extern RecordType* irc_join_info;
|
||||
extern TableVal* irc_servers;
|
||||
|
||||
extern TableVal* dpd_config;
|
||||
extern int dpd_reassemble_first_packets;
|
||||
extern int dpd_buffer_size;
|
||||
extern int dpd_match_only_beginning;
|
||||
|
|
|
@ -351,10 +351,12 @@ public:
|
|||
}
|
||||
|
||||
char Type() { return buffer[0]; }
|
||||
|
||||
RemoteSerializer::PeerID Peer()
|
||||
{
|
||||
// Wow, is this ugly...
|
||||
return ntohl(*(uint32*)(buffer + 4));
|
||||
uint32 tmp;
|
||||
memcpy(&tmp, buffer + 4, sizeof(tmp));
|
||||
return ntohl(tmp);
|
||||
}
|
||||
|
||||
const char* Raw() { return buffer; }
|
||||
|
|
|
@ -8,8 +8,9 @@ using std::string;
|
|||
#include "Conn.h"
|
||||
#include "Event.h"
|
||||
#include "NetVar.h"
|
||||
#include "DPM.h"
|
||||
#include "PIA.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
void RuleActionEvent::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
|
@ -34,42 +35,45 @@ void RuleActionEvent::PrintDebug()
|
|||
fprintf(stderr, " RuleActionEvent: |%s|\n", msg);
|
||||
}
|
||||
|
||||
RuleActionDPM::RuleActionDPM(const char* arg_analyzer)
|
||||
RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
|
||||
{
|
||||
string str(arg_analyzer);
|
||||
string::size_type pos = str.find(':');
|
||||
string arg = str.substr(0, pos);
|
||||
analyzer = Analyzer::GetTag(arg.c_str());
|
||||
analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
|
||||
|
||||
if ( ! analyzer )
|
||||
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
||||
|
||||
if ( pos != string::npos )
|
||||
{
|
||||
arg = str.substr(pos + 1);
|
||||
child_analyzer = Analyzer::GetTag(arg.c_str());
|
||||
child_analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
|
||||
|
||||
if ( ! child_analyzer )
|
||||
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
||||
}
|
||||
else
|
||||
child_analyzer = AnalyzerTag::Error;
|
||||
|
||||
if ( analyzer != AnalyzerTag::Error )
|
||||
dpm->ActivateSigs();
|
||||
child_analyzer = analyzer::Tag();
|
||||
}
|
||||
|
||||
void RuleActionDPM::PrintDebug()
|
||||
void RuleActionAnalyzer::PrintDebug()
|
||||
{
|
||||
if ( child_analyzer == AnalyzerTag::Error )
|
||||
fprintf(stderr, "|%s|\n", Analyzer::GetTagName(analyzer));
|
||||
if ( ! child_analyzer )
|
||||
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer));
|
||||
else
|
||||
fprintf(stderr, "|%s:%s|\n",
|
||||
Analyzer::GetTagName(analyzer),
|
||||
Analyzer::GetTagName(child_analyzer));
|
||||
analyzer_mgr->GetAnalyzerName(analyzer),
|
||||
analyzer_mgr->GetAnalyzerName(child_analyzer));
|
||||
}
|
||||
|
||||
|
||||
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
||||
if ( ! ChildAnalyzer() )
|
||||
{
|
||||
if ( ! Analyzer::IsAvailable(Analyzer()) )
|
||||
if ( ! analyzer_mgr->IsEnabled(Analyzer()) )
|
||||
return;
|
||||
|
||||
if ( state->PIA() )
|
||||
|
@ -77,7 +81,7 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( ! Analyzer::IsAvailable(ChildAnalyzer()) )
|
||||
if ( ! analyzer_mgr->IsEnabled(ChildAnalyzer()) )
|
||||
return;
|
||||
|
||||
// This is ugly and works only if there exists only one
|
||||
|
@ -90,13 +94,13 @@ void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
void RuleActionEnable::PrintDebug()
|
||||
{
|
||||
fprintf(stderr, " RuleActionEnable: ");
|
||||
RuleActionDPM::PrintDebug();
|
||||
RuleActionAnalyzer::PrintDebug();
|
||||
}
|
||||
|
||||
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
if ( ChildAnalyzer() == AnalyzerTag::Error )
|
||||
if ( ! ChildAnalyzer() )
|
||||
{
|
||||
if ( state->PIA() )
|
||||
state->PIA()->DeactivateAnalyzer(Analyzer());
|
||||
|
@ -109,5 +113,5 @@ void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
|||
void RuleActionDisable::PrintDebug()
|
||||
{
|
||||
fprintf(stderr, " RuleActionDisable: ");
|
||||
RuleActionDPM::PrintDebug();
|
||||
RuleActionAnalyzer::PrintDebug();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef ruleaction_h
|
||||
#define ruleaction_h
|
||||
|
||||
#include "AnalyzerTags.h"
|
||||
#include "BroString.h"
|
||||
#include "List.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "analyzer/Tag.h"
|
||||
|
||||
class Rule;
|
||||
class RuleEndpointState;
|
||||
|
||||
|
@ -35,29 +36,27 @@ private:
|
|||
const char* msg;
|
||||
};
|
||||
|
||||
// Base class for DPM enable/disable actions.
|
||||
class RuleActionDPM : public RuleAction {
|
||||
// Base class for enable/disable actions.
|
||||
class RuleActionAnalyzer : public RuleAction {
|
||||
public:
|
||||
RuleActionDPM(const char* analyzer);
|
||||
RuleActionAnalyzer(const char* analyzer);
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) = 0;
|
||||
|
||||
virtual void PrintDebug();
|
||||
|
||||
AnalyzerTag::Tag Analyzer() const { return analyzer; }
|
||||
AnalyzerTag::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||
analyzer::Tag Analyzer() const { return analyzer; }
|
||||
analyzer::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||
|
||||
private:
|
||||
// FIXME: This is in fact an AnalyzerID but we can't include "Analyzer.h"
|
||||
// at this point due to circular dependenides. Fix that!
|
||||
AnalyzerTag::Tag analyzer;
|
||||
AnalyzerTag::Tag child_analyzer;
|
||||
analyzer::Tag analyzer;
|
||||
analyzer::Tag child_analyzer;
|
||||
};
|
||||
|
||||
class RuleActionEnable : public RuleActionDPM {
|
||||
class RuleActionEnable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionEnable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
||||
RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
|
@ -65,9 +64,9 @@ public:
|
|||
virtual void PrintDebug();
|
||||
};
|
||||
|
||||
class RuleActionDisable : public RuleActionDPM {
|
||||
class RuleActionDisable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionDisable(const char* analyzer) : RuleActionDPM(analyzer) {}
|
||||
RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "RuleCondition.h"
|
||||
#include "TCP.h"
|
||||
#include "analyzer/protocol/tcp/TCP.h"
|
||||
#include "Scope.h"
|
||||
|
||||
static inline bool is_established(const TCP_Endpoint* e)
|
||||
static inline bool is_established(const analyzer::tcp::TCP_Endpoint* e)
|
||||
{
|
||||
// We more or less follow Snort here: an established session
|
||||
// is one for which the initial handshake has succeded (but we
|
||||
// add partial connections). The connection tear-down is part
|
||||
// of the connection.
|
||||
return e->state != TCP_ENDPOINT_INACTIVE &&
|
||||
e->state != TCP_ENDPOINT_SYN_SENT &&
|
||||
e->state != TCP_ENDPOINT_SYN_ACK_SENT;
|
||||
return e->state != analyzer::tcp::TCP_ENDPOINT_INACTIVE &&
|
||||
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_SENT &&
|
||||
e->state != analyzer::tcp::TCP_ENDPOINT_SYN_ACK_SENT;
|
||||
}
|
||||
|
||||
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
{
|
||||
Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
||||
analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
||||
|
||||
if ( ! root || root->GetTag() != AnalyzerTag::TCP )
|
||||
if ( ! root || ! root->IsAnalyzer("TCP") )
|
||||
return false;
|
||||
|
||||
TCP_Analyzer* ta = static_cast<TCP_Analyzer*>(root);
|
||||
analyzer::tcp::TCP_Analyzer* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(root);
|
||||
|
||||
if ( tcpstates & STATE_STATELESS )
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "analyzer/Analyzer.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "DFA.h"
|
||||
#include "NetVar.h"
|
||||
|
@ -159,9 +159,9 @@ void RuleHdrTest::PrintDebug()
|
|||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
RuleEndpointState::RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState::RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite,
|
||||
::PIA* arg_PIA)
|
||||
analyzer::pia::PIA* arg_PIA)
|
||||
{
|
||||
payload_size = -1;
|
||||
analyzer = arg_analyzer;
|
||||
|
@ -562,10 +562,10 @@ static inline bool compare(const vector<IPPrefix>& prefixes, const IPAddr& a,
|
|||
return false;
|
||||
}
|
||||
|
||||
RuleEndpointState* RuleMatcher::InitEndpoint(Analyzer* analyzer,
|
||||
RuleEndpointState* RuleMatcher::InitEndpoint(analyzer::Analyzer* analyzer,
|
||||
const IP_Hdr* ip, int caplen,
|
||||
RuleEndpointState* opposite,
|
||||
bool from_orig, PIA* pia)
|
||||
bool from_orig, analyzer::pia::PIA* pia)
|
||||
{
|
||||
RuleEndpointState* state =
|
||||
new RuleEndpointState(analyzer, from_orig, opposite, pia);
|
||||
|
@ -1300,8 +1300,8 @@ uint32 id_to_uint(const char* id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void RuleMatcherState::InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, PIA* pia)
|
||||
void RuleMatcherState::InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, analyzer::pia::PIA* pia)
|
||||
{
|
||||
if ( ! rule_matcher )
|
||||
return;
|
||||
|
|
|
@ -35,8 +35,10 @@ extern const char* current_rule_file;
|
|||
class RuleMatcher;
|
||||
extern RuleMatcher* rule_matcher;
|
||||
|
||||
namespace analyzer {
|
||||
namespace pia { class PIA; }
|
||||
class Analyzer;
|
||||
class PIA;
|
||||
}
|
||||
|
||||
// RuleHdrTest and associated things:
|
||||
|
||||
|
@ -140,7 +142,7 @@ class RuleEndpointState {
|
|||
public:
|
||||
~RuleEndpointState();
|
||||
|
||||
Analyzer* GetAnalyzer() const { return analyzer; }
|
||||
analyzer::Analyzer* GetAnalyzer() const { return analyzer; }
|
||||
bool IsOrig() { return is_orig; }
|
||||
|
||||
// For flipping roles.
|
||||
|
@ -152,15 +154,15 @@ public:
|
|||
// Returns -1 if no chunk has been fed yet at all.
|
||||
int PayloadSize() { return payload_size; }
|
||||
|
||||
::PIA* PIA() const { return pia; }
|
||||
analyzer::pia::PIA* PIA() const { return pia; }
|
||||
|
||||
private:
|
||||
friend class RuleMatcher;
|
||||
|
||||
// Constructor is private; use RuleMatcher::InitEndpoint()
|
||||
// for creating an instance.
|
||||
RuleEndpointState(Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite, ::PIA* arg_PIA);
|
||||
RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
|
||||
RuleEndpointState* arg_opposite, analyzer::pia::PIA* arg_PIA);
|
||||
|
||||
struct Matcher {
|
||||
RE_Match_State* state;
|
||||
|
@ -171,9 +173,9 @@ private:
|
|||
typedef PList(Matcher) matcher_list;
|
||||
|
||||
bool is_orig;
|
||||
Analyzer* analyzer;
|
||||
analyzer::Analyzer* analyzer;
|
||||
RuleEndpointState* opposite;
|
||||
::PIA* pia;
|
||||
analyzer::pia::PIA* pia;
|
||||
|
||||
matcher_list matchers;
|
||||
rule_hdr_test_list hdr_tests;
|
||||
|
@ -207,8 +209,8 @@ public:
|
|||
// the given packet (which should be the first packet encountered for
|
||||
// this endpoint). If the matching is triggered by an PIA, a pointer to
|
||||
// it needs to be given.
|
||||
RuleEndpointState* InitEndpoint(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, RuleEndpointState* opposite, bool is_orig, PIA* pia);
|
||||
RuleEndpointState* InitEndpoint(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, RuleEndpointState* opposite, bool is_orig, analyzer::pia::PIA* pia);
|
||||
|
||||
// Finish matching for this stream.
|
||||
void FinishEndpoint(RuleEndpointState* state);
|
||||
|
@ -310,8 +312,8 @@ public:
|
|||
{ delete orig_match_state; delete resp_match_state; }
|
||||
|
||||
// ip may be nil.
|
||||
void InitEndpointMatcher(Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, PIA* pia = 0);
|
||||
void InitEndpointMatcher(analyzer::Analyzer* analyzer, const IP_Hdr* ip,
|
||||
int caplen, bool from_orig, analyzer::pia::PIA* pia = 0);
|
||||
|
||||
// bol/eol should be set to false for type Rule::PAYLOAD; they're
|
||||
// deduced automatically.
|
||||
|
|
26
src/SSH.h
26
src/SSH.h
|
@ -1,26 +0,0 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef ssh_h
|
||||
#define ssh_h
|
||||
|
||||
#include "TCP.h"
|
||||
#include "ContentLine.h"
|
||||
|
||||
class SSH_Analyzer : public TCP_ApplicationAnalyzer {
|
||||
public:
|
||||
SSH_Analyzer(Connection* conn);
|
||||
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new SSH_Analyzer(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return ssh_client_version || ssh_server_version; }
|
||||
|
||||
private:
|
||||
ContentLine_Analyzer* orig;
|
||||
ContentLine_Analyzer* resp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,22 +16,25 @@
|
|||
#include "Reporter.h"
|
||||
#include "OSFinger.h"
|
||||
|
||||
#include "ICMP.h"
|
||||
#include "UDP.h"
|
||||
#include "analyzer/protocol/icmp/ICMP.h"
|
||||
#include "analyzer/protocol/udp/UDP.h"
|
||||
|
||||
#include "DNS-binpac.h"
|
||||
#include "HTTP-binpac.h"
|
||||
|
||||
#include "SteppingStone.h"
|
||||
#include "BackDoor.h"
|
||||
#include "InterConn.h"
|
||||
#include "analyzer/protocol/stepping-stone/SteppingStone.h"
|
||||
#include "analyzer/protocol/stepping-stone/events.bif.h"
|
||||
#include "analyzer/protocol/backdoor/BackDoor.h"
|
||||
#include "analyzer/protocol/backdoor/events.bif.h"
|
||||
#include "analyzer/protocol/interconn/InterConn.h"
|
||||
#include "analyzer/protocol/interconn/events.bif.h"
|
||||
#include "analyzer/protocol/arp/ARP.h"
|
||||
#include "analyzer/protocol/arp/events.bif.h"
|
||||
#include "Discard.h"
|
||||
#include "RuleMatcher.h"
|
||||
#include "DPM.h"
|
||||
|
||||
#include "PacketSort.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
|
||||
#include "analyzer/Manager.h"
|
||||
|
||||
// These represent NetBIOS services on ephemeral ports. They're numbered
|
||||
// so that we can use a single int to hold either an actual TCP/UDP server
|
||||
// port or one of these.
|
||||
|
@ -104,7 +107,7 @@ NetSessions::NetSessions()
|
|||
fragments.SetDeleteFunc(bro_obj_delete_func);
|
||||
|
||||
if ( stp_correlate_pair )
|
||||
stp_manager = new SteppingStoneManager();
|
||||
stp_manager = new analyzer::stepping_stone::SteppingStoneManager();
|
||||
else
|
||||
stp_manager = 0;
|
||||
|
||||
|
@ -143,7 +146,7 @@ NetSessions::NetSessions()
|
|||
pkt_profiler = 0;
|
||||
|
||||
if ( arp_request || arp_reply || bad_arp )
|
||||
arp_analyzer = new ARP_Analyzer();
|
||||
arp_analyzer = new analyzer::arp::ARP_Analyzer();
|
||||
else
|
||||
arp_analyzer = 0;
|
||||
}
|
||||
|
@ -256,7 +259,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0);
|
||||
}
|
||||
|
||||
else if ( ARP_Analyzer::IsARP(pkt, hdr_size) )
|
||||
else if ( analyzer::arp::ARP_Analyzer::IsARP(pkt, hdr_size) )
|
||||
{
|
||||
if ( arp_analyzer )
|
||||
arp_analyzer->NextPacket(t, hdr, pkt, hdr_size);
|
||||
|
@ -523,7 +526,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
const struct icmp* icmpp = (const struct icmp *) data;
|
||||
|
||||
id.src_port = icmpp->icmp_type;
|
||||
id.dst_port = ICMP4_counterpart(icmpp->icmp_type,
|
||||
id.dst_port = analyzer::icmp::ICMP4_counterpart(icmpp->icmp_type,
|
||||
icmpp->icmp_code,
|
||||
id.is_one_way);
|
||||
|
||||
|
@ -539,7 +542,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
const struct icmp* icmpp = (const struct icmp *) data;
|
||||
|
||||
id.src_port = icmpp->icmp_type;
|
||||
id.dst_port = ICMP6_counterpart(icmpp->icmp_type,
|
||||
id.dst_port = analyzer::icmp::ICMP6_counterpart(icmpp->icmp_type,
|
||||
icmpp->icmp_code,
|
||||
id.is_one_way);
|
||||
|
||||
|
@ -964,12 +967,12 @@ void NetSessions::Remove(Connection* c)
|
|||
{
|
||||
c->CancelTimers();
|
||||
|
||||
TCP_Analyzer* ta = (TCP_Analyzer*) c->GetRootAnalyzer();
|
||||
analyzer::tcp::TCP_Analyzer* ta = (analyzer::tcp::TCP_Analyzer*) c->GetRootAnalyzer();
|
||||
if ( ta && c->ConnTransport() == TRANSPORT_TCP )
|
||||
{
|
||||
assert(ta->GetTag() == AnalyzerTag::TCP);
|
||||
TCP_Endpoint* to = ta->Orig();
|
||||
TCP_Endpoint* tr = ta->Resp();
|
||||
assert(ta->IsAnalyzer("TCP"));
|
||||
analyzer::tcp::TCP_Endpoint* to = ta->Orig();
|
||||
analyzer::tcp::TCP_Endpoint* tr = ta->Resp();
|
||||
|
||||
tcp_stats.StateLeft(to->state, tr->state);
|
||||
}
|
||||
|
@ -1159,12 +1162,12 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
|||
if ( ! WantConnection(src_h, dst_h, tproto, flags, flip) )
|
||||
return 0;
|
||||
|
||||
ConnID flip_id = *id;
|
||||
|
||||
if ( flip )
|
||||
{
|
||||
// Make a guess that we're seeing the tail half of
|
||||
// an analyzable connection.
|
||||
ConnID flip_id = *id;
|
||||
|
||||
const IPAddr ta = flip_id.src_addr;
|
||||
flip_id.src_addr = flip_id.dst_addr;
|
||||
flip_id.dst_addr = ta;
|
||||
|
@ -1178,7 +1181,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
|||
|
||||
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
|
||||
conn->SetTransport(tproto);
|
||||
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
||||
analyzer_mgr->BuildInitialAnalyzerTree(conn);
|
||||
|
||||
bool external = conn->IsExternal();
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
#include "Dict.h"
|
||||
#include "CompHash.h"
|
||||
#include "IP.h"
|
||||
#include "ARP.h"
|
||||
#include "Frag.h"
|
||||
#include "PacketFilter.h"
|
||||
#include "Stats.h"
|
||||
#include "NetVar.h"
|
||||
#include "TunnelEncapsulation.h"
|
||||
#include "analyzer/protocol/tcp/Stats.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
struct pcap_pkthdr;
|
||||
|
@ -26,11 +27,12 @@ declare(PDict,Connection);
|
|||
declare(PDict,FragReassembler);
|
||||
|
||||
class Discarder;
|
||||
class SteppingStoneManager;
|
||||
class PacketFilter;
|
||||
|
||||
class PacketSortElement;
|
||||
|
||||
namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } }
|
||||
namespace analyzer { namespace arp { class ARP_Analyzer; } }
|
||||
|
||||
struct SessionStats {
|
||||
int num_TCP_conns;
|
||||
int num_UDP_conns;
|
||||
|
@ -127,7 +129,7 @@ public:
|
|||
|
||||
void ExpireTimerMgrs();
|
||||
|
||||
SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
||||
analyzer::stepping_stone::SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
||||
|
||||
unsigned int CurrentConnections()
|
||||
{
|
||||
|
@ -183,7 +185,7 @@ public:
|
|||
unsigned int ConnectionMemoryUsage();
|
||||
unsigned int ConnectionMemoryUsageConnVals();
|
||||
unsigned int MemoryAllocation();
|
||||
TCPStateStats tcp_stats; // keeps statistics on TCP states
|
||||
analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states
|
||||
|
||||
protected:
|
||||
friend class RemoteSerializer;
|
||||
|
@ -255,9 +257,9 @@ protected:
|
|||
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
|
||||
IPTunnelMap ip_tunnels;
|
||||
|
||||
ARP_Analyzer* arp_analyzer;
|
||||
analyzer::arp::ARP_Analyzer* arp_analyzer;
|
||||
|
||||
SteppingStoneManager* stp_manager;
|
||||
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
||||
Discarder* discarder;
|
||||
PacketFilter* packet_filter;
|
||||
OSFingerprint* SYN_OS_Fingerprinter;
|
||||
|
|
78
src/Stats.cc
78
src/Stats.cc
|
@ -389,84 +389,6 @@ void SegmentProfiler::Report()
|
|||
reporter->SegmentProfile(name, loc, dtime, dmem);
|
||||
}
|
||||
|
||||
|
||||
TCPStateStats::TCPStateStats()
|
||||
{
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j )
|
||||
state_cnt[i][j] = 0;
|
||||
}
|
||||
|
||||
void TCPStateStats::ChangeState(EndpointState o_prev, EndpointState o_now,
|
||||
EndpointState r_prev, EndpointState r_now)
|
||||
{
|
||||
--state_cnt[o_prev][r_prev];
|
||||
++state_cnt[o_now][r_now];
|
||||
}
|
||||
|
||||
void TCPStateStats::FlipState(EndpointState orig, EndpointState resp)
|
||||
{
|
||||
--state_cnt[orig][resp];
|
||||
++state_cnt[resp][orig];
|
||||
}
|
||||
|
||||
unsigned int TCPStateStats::NumStatePartial() const
|
||||
{
|
||||
unsigned int sum = 0;
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
{
|
||||
sum += state_cnt[TCP_ENDPOINT_PARTIAL][i];
|
||||
sum += state_cnt[i][TCP_ENDPOINT_PARTIAL];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void TCPStateStats::PrintStats(BroFile* file, const char* prefix)
|
||||
{
|
||||
file->Write(prefix);
|
||||
file->Write(" Inact. Syn. SA Part. Est. Fin. Rst.\n");
|
||||
|
||||
for ( int i = 0; i < TCP_ENDPOINT_RESET + 1; ++i )
|
||||
{
|
||||
file->Write(prefix);
|
||||
|
||||
switch ( i ) {
|
||||
#define STATE_STRING(state, str) \
|
||||
case state: \
|
||||
file->Write(str); \
|
||||
break;
|
||||
|
||||
STATE_STRING(TCP_ENDPOINT_INACTIVE, "Inact.");
|
||||
STATE_STRING(TCP_ENDPOINT_SYN_SENT, "Syn. ");
|
||||
STATE_STRING(TCP_ENDPOINT_SYN_ACK_SENT, "SA ");
|
||||
STATE_STRING(TCP_ENDPOINT_PARTIAL, "Part. ");
|
||||
STATE_STRING(TCP_ENDPOINT_ESTABLISHED, "Est. ");
|
||||
STATE_STRING(TCP_ENDPOINT_CLOSED, "Fin. ");
|
||||
STATE_STRING(TCP_ENDPOINT_RESET, "Rst. ");
|
||||
|
||||
}
|
||||
|
||||
file->Write(" ");
|
||||
|
||||
for ( int j = 0; j < TCP_ENDPOINT_RESET + 1; ++j )
|
||||
{
|
||||
unsigned int n = state_cnt[i][j];
|
||||
if ( n > 0 )
|
||||
{
|
||||
char buf[32];
|
||||
safe_snprintf(buf, sizeof(buf), "%-8d", state_cnt[i][j]);
|
||||
file->Write(buf);
|
||||
}
|
||||
else
|
||||
file->Write(" ");
|
||||
}
|
||||
|
||||
file->Write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PacketProfiler::PacketProfiler(unsigned int mode, double freq,
|
||||
BroFile* arg_file)
|
||||
{
|
||||
|
|
64
src/Stats.h
64
src/Stats.h
|
@ -7,9 +7,6 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "TCP_Endpoint.h"
|
||||
|
||||
|
||||
// Object called by SegmentProfiler when it is done and reports its
|
||||
// cumulative CPU/memory statistics.
|
||||
class SegmentStatsReporter {
|
||||
|
@ -121,67 +118,6 @@ extern uint64 tot_ack_bytes;
|
|||
extern uint64 tot_gap_events;
|
||||
extern uint64 tot_gap_bytes;
|
||||
|
||||
|
||||
// A TCPStateStats object tracks the distribution of TCP states for
|
||||
// the currently active connections.
|
||||
class TCPStateStats {
|
||||
public:
|
||||
TCPStateStats();
|
||||
~TCPStateStats() { }
|
||||
|
||||
void ChangeState(EndpointState o_prev, EndpointState o_now,
|
||||
EndpointState r_prev, EndpointState r_now);
|
||||
void FlipState(EndpointState orig, EndpointState resp);
|
||||
|
||||
void StateEntered (EndpointState o_state, EndpointState r_state)
|
||||
{ ++state_cnt[o_state][r_state]; }
|
||||
void StateLeft (EndpointState o_state, EndpointState r_state)
|
||||
{ --state_cnt[o_state][r_state]; }
|
||||
|
||||
unsigned int Cnt(EndpointState state) const
|
||||
{ return Cnt(state, state); }
|
||||
unsigned int Cnt(EndpointState state1, EndpointState state2) const
|
||||
{ return state_cnt[state1][state2]; }
|
||||
|
||||
unsigned int NumStateEstablished() const
|
||||
{ return Cnt(TCP_ENDPOINT_ESTABLISHED); }
|
||||
unsigned int NumStateHalfClose() const
|
||||
{ // corresponds to S2,S3
|
||||
return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_CLOSED) +
|
||||
Cnt(TCP_ENDPOINT_CLOSED, TCP_ENDPOINT_ESTABLISHED);
|
||||
}
|
||||
unsigned int NumStateHalfRst() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_ESTABLISHED, TCP_ENDPOINT_RESET) +
|
||||
Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_ESTABLISHED);
|
||||
}
|
||||
unsigned int NumStateClosed() const
|
||||
{ return Cnt(TCP_ENDPOINT_CLOSED); }
|
||||
unsigned int NumStateRequest() const
|
||||
{
|
||||
assert(Cnt(TCP_ENDPOINT_INACTIVE, TCP_ENDPOINT_SYN_SENT)==0);
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_INACTIVE);
|
||||
}
|
||||
unsigned int NumStateSuccRequest() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_SYN_ACK_SENT) +
|
||||
Cnt(TCP_ENDPOINT_SYN_ACK_SENT, TCP_ENDPOINT_SYN_SENT);
|
||||
}
|
||||
unsigned int NumStateRstRequest() const
|
||||
{
|
||||
return Cnt(TCP_ENDPOINT_SYN_SENT, TCP_ENDPOINT_RESET) +
|
||||
Cnt(TCP_ENDPOINT_RESET, TCP_ENDPOINT_SYN_SENT);
|
||||
}
|
||||
unsigned int NumStateInactive() const
|
||||
{ return Cnt(TCP_ENDPOINT_INACTIVE); }
|
||||
unsigned int NumStatePartial() const;
|
||||
|
||||
void PrintStats(BroFile* file, const char* prefix);
|
||||
|
||||
private:
|
||||
unsigned int state_cnt[TCP_ENDPOINT_RESET+1][TCP_ENDPOINT_RESET+1];
|
||||
};
|
||||
|
||||
class PacketProfiler {
|
||||
public:
|
||||
PacketProfiler(unsigned int mode, double freq, BroFile* arg_file);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef Syslog_binpac_h
|
||||
#define Syslog_binpac_h
|
||||
|
||||
#include "UDP.h"
|
||||
#include "TCP.h"
|
||||
|
||||
#include "syslog_pac.h"
|
||||
|
||||
class Syslog_Analyzer_binpac : public Analyzer {
|
||||
public:
|
||||
Syslog_Analyzer_binpac(Connection* conn);
|
||||
virtual ~Syslog_Analyzer_binpac();
|
||||
|
||||
virtual void Done();
|
||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
||||
int seq, const IP_Hdr* ip, int caplen);
|
||||
|
||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
{ return new Syslog_Analyzer_binpac(conn); }
|
||||
|
||||
static bool Available()
|
||||
{ return syslog_message; }
|
||||
|
||||
protected:
|
||||
friend class AnalyzerTimer;
|
||||
void ExpireTimer(double t);
|
||||
|
||||
int did_session_done;
|
||||
|
||||
binpac::Syslog::Syslog_Conn* interp;
|
||||
};
|
||||
|
||||
// #include "Syslog_tcp_pac.h"
|
||||
//
|
||||
//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
||||
//public:
|
||||
// Syslog_TCP_Analyzer_binpac(Connection* conn);
|
||||
// virtual ~Syslog_TCP_Analyzer_binpac();
|
||||
//
|
||||
// virtual void Done();
|
||||
// virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
// virtual void Undelivered(int seq, int len, bool orig);
|
||||
// virtual void EndpointEOF(TCP_Reassembler* endp);
|
||||
//
|
||||
// static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||
// { return new Syslog_TCP_Analyzer_binpac(conn); }
|
||||
//
|
||||
// static bool Available()
|
||||
// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; }
|
||||
//
|
||||
//protected:
|
||||
// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp;
|
||||
//};
|
||||
//
|
||||
#endif
|
|
@ -217,6 +217,11 @@ public:
|
|||
return tag == TYPE_TABLE && (YieldType() == 0);
|
||||
}
|
||||
|
||||
int IsTable() const
|
||||
{
|
||||
return tag == TYPE_TABLE && (YieldType() != 0);
|
||||
}
|
||||
|
||||
BroType* Ref() { ::Ref(this); return this; }
|
||||
|
||||
virtual void Describe(ODesc* d) const;
|
||||
|
|
|
@ -1049,6 +1049,11 @@ StringVal::StringVal(const char* s) : Val(TYPE_STRING)
|
|||
val.string_val = new BroString(s);
|
||||
}
|
||||
|
||||
StringVal::StringVal(const string& s) : Val(TYPE_STRING)
|
||||
{
|
||||
val.string_val = new BroString(s.c_str());
|
||||
}
|
||||
|
||||
StringVal* StringVal::ToUpper()
|
||||
{
|
||||
val.string_val->ToUpper();
|
||||
|
|
|
@ -608,6 +608,7 @@ class StringVal : public Val {
|
|||
public:
|
||||
StringVal(BroString* s);
|
||||
StringVal(const char* s);
|
||||
StringVal(const string& s);
|
||||
StringVal(int length, const char* s);
|
||||
|
||||
Val* SizeVal() const
|
||||
|
|
|
@ -1,191 +1,45 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "PIA.h"
|
||||
#include "Event.h"
|
||||
#include "Manager.h"
|
||||
|
||||
#include "AYIYA.h"
|
||||
#include "BackDoor.h"
|
||||
#include "BitTorrent.h"
|
||||
#include "BitTorrentTracker.h"
|
||||
#include "Finger.h"
|
||||
#include "InterConn.h"
|
||||
#include "NTP.h"
|
||||
#include "HTTP.h"
|
||||
#include "HTTP-binpac.h"
|
||||
#include "ICMP.h"
|
||||
#include "SteppingStone.h"
|
||||
#include "IRC.h"
|
||||
#include "SMTP.h"
|
||||
#include "FTP.h"
|
||||
#include "FileAnalyzer.h"
|
||||
#include "DNS.h"
|
||||
#include "DNS-binpac.h"
|
||||
#include "DHCP-binpac.h"
|
||||
#include "Telnet.h"
|
||||
#include "Rlogin.h"
|
||||
#include "RSH.h"
|
||||
#include "DCE_RPC.h"
|
||||
#include "Gnutella.h"
|
||||
#include "Ident.h"
|
||||
#include "Modbus.h"
|
||||
#include "NCP.h"
|
||||
#include "NetbiosSSN.h"
|
||||
#include "SMB.h"
|
||||
#include "NFS.h"
|
||||
#include "Portmap.h"
|
||||
#include "POP3.h"
|
||||
#include "SOCKS.h"
|
||||
#include "SSH.h"
|
||||
#include "SSL.h"
|
||||
#include "Syslog-binpac.h"
|
||||
#include "Teredo.h"
|
||||
#include "ConnSizeAnalyzer.h"
|
||||
#include "GTPv1.h"
|
||||
#include "analyzer/protocol/pia/PIA.h"
|
||||
#include "../Event.h"
|
||||
|
||||
// Keep same order here as in AnalyzerTag definition!
|
||||
const Analyzer::Config Analyzer::analyzer_configs[] = {
|
||||
{ AnalyzerTag::Error, "<ERROR>", 0, 0, 0, false },
|
||||
namespace analyzer {
|
||||
|
||||
{ AnalyzerTag::PIA_TCP, "PIA_TCP", PIA_TCP::InstantiateAnalyzer,
|
||||
PIA_TCP::Available, 0, false },
|
||||
{ AnalyzerTag::PIA_UDP, "PIA_UDP", PIA_UDP::InstantiateAnalyzer,
|
||||
PIA_UDP::Available, 0, false },
|
||||
class AnalyzerTimer : public Timer {
|
||||
public:
|
||||
AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type);
|
||||
|
||||
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
|
||||
ICMP_Analyzer::Available, 0, false },
|
||||
virtual ~AnalyzerTimer();
|
||||
|
||||
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
|
||||
TCP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::UDP, "UDP", UDP_Analyzer::InstantiateAnalyzer,
|
||||
UDP_Analyzer::Available, 0, false },
|
||||
void Dispatch(double t, int is_expire);
|
||||
|
||||
{ AnalyzerTag::BitTorrent, "BITTORRENT",
|
||||
BitTorrent_Analyzer::InstantiateAnalyzer,
|
||||
BitTorrent_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::BitTorrentTracker, "BITTORRENTTRACKER",
|
||||
BitTorrentTracker_Analyzer::InstantiateAnalyzer,
|
||||
BitTorrentTracker_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::DCE_RPC, "DCE_RPC",
|
||||
DCE_RPC_Analyzer::InstantiateAnalyzer,
|
||||
DCE_RPC_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::DNS, "DNS", DNS_Analyzer::InstantiateAnalyzer,
|
||||
DNS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Finger, "FINGER", Finger_Analyzer::InstantiateAnalyzer,
|
||||
Finger_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::FTP, "FTP", FTP_Analyzer::InstantiateAnalyzer,
|
||||
FTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Gnutella, "GNUTELLA",
|
||||
Gnutella_Analyzer::InstantiateAnalyzer,
|
||||
Gnutella_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::HTTP, "HTTP", HTTP_Analyzer::InstantiateAnalyzer,
|
||||
HTTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Ident, "IDENT", Ident_Analyzer::InstantiateAnalyzer,
|
||||
Ident_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::IRC, "IRC", IRC_Analyzer::InstantiateAnalyzer,
|
||||
IRC_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Login, "LOGIN", 0, 0, 0, false }, // just a base class
|
||||
{ AnalyzerTag::NCP, "NCP", NCP_Analyzer::InstantiateAnalyzer,
|
||||
NCP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NetbiosSSN, "NetbiosSSN",
|
||||
NetbiosSSN_Analyzer::InstantiateAnalyzer,
|
||||
NetbiosSSN_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NFS, "NFS", NFS_Analyzer::InstantiateAnalyzer,
|
||||
NFS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::NTP, "NTP", NTP_Analyzer::InstantiateAnalyzer,
|
||||
NTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::POP3, "POP3", POP3_Analyzer::InstantiateAnalyzer,
|
||||
POP3_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Portmapper, "PORTMAPPER",
|
||||
Portmapper_Analyzer::InstantiateAnalyzer,
|
||||
Portmapper_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Rlogin, "RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer,
|
||||
Rlogin_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::RPC, "RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Rsh, "RSH", Rsh_Analyzer::InstantiateAnalyzer,
|
||||
Rsh_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SMB, "SMB", SMB_Analyzer::InstantiateAnalyzer,
|
||||
SMB_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SMTP, "SMTP", SMTP_Analyzer::InstantiateAnalyzer,
|
||||
SMTP_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SSH, "SSH", SSH_Analyzer::InstantiateAnalyzer,
|
||||
SSH_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Telnet, "TELNET", Telnet_Analyzer::InstantiateAnalyzer,
|
||||
Telnet_Analyzer::Available, 0, false },
|
||||
protected:
|
||||
AnalyzerTimer() {}
|
||||
|
||||
{ AnalyzerTag::DHCP_BINPAC, "DHCP_BINPAC",
|
||||
DHCP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DHCP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::DNS_TCP_BINPAC, "DNS_TCP_BINPAC",
|
||||
DNS_TCP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DNS_TCP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::DNS_UDP_BINPAC, "DNS_UDP_BINPAC",
|
||||
DNS_UDP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
DNS_UDP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::HTTP_BINPAC, "HTTP_BINPAC",
|
||||
HTTP_Analyzer_binpac::InstantiateAnalyzer,
|
||||
HTTP_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::SSL, "SSL",
|
||||
SSL_Analyzer::InstantiateAnalyzer,
|
||||
SSL_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC",
|
||||
Syslog_Analyzer_binpac::InstantiateAnalyzer,
|
||||
Syslog_Analyzer_binpac::Available, 0, false },
|
||||
{ AnalyzerTag::Modbus, "MODBUS",
|
||||
ModbusTCP_Analyzer::InstantiateAnalyzer,
|
||||
ModbusTCP_Analyzer::Available, 0, false },
|
||||
void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
|
||||
|
||||
{ AnalyzerTag::AYIYA, "AYIYA",
|
||||
AYIYA_Analyzer::InstantiateAnalyzer,
|
||||
AYIYA_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SOCKS, "SOCKS",
|
||||
SOCKS_Analyzer::InstantiateAnalyzer,
|
||||
SOCKS_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::Teredo, "TEREDO",
|
||||
Teredo_Analyzer::InstantiateAnalyzer,
|
||||
Teredo_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::GTPv1, "GTPV1",
|
||||
GTPv1_Analyzer::InstantiateAnalyzer,
|
||||
GTPv1_Analyzer::Available, 0, false },
|
||||
|
||||
{ AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer,
|
||||
File_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::IRC_Data, "IRC_DATA", IRC_Data::InstantiateAnalyzer,
|
||||
IRC_Data::Available, 0, false },
|
||||
{ AnalyzerTag::FTP_Data, "FTP_DATA", FTP_Data::InstantiateAnalyzer,
|
||||
FTP_Data::Available, 0, false },
|
||||
{ AnalyzerTag::Backdoor, "BACKDOOR",
|
||||
BackDoor_Analyzer::InstantiateAnalyzer,
|
||||
BackDoor_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::InterConn, "INTERCONN",
|
||||
InterConn_Analyzer::InstantiateAnalyzer,
|
||||
InterConn_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::SteppingStone, "STEPPINGSTONE",
|
||||
SteppingStone_Analyzer::InstantiateAnalyzer,
|
||||
SteppingStone_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::TCPStats, "TCPSTATS",
|
||||
TCPStats_Analyzer::InstantiateAnalyzer,
|
||||
TCPStats_Analyzer::Available, 0, false },
|
||||
{ AnalyzerTag::ConnSize, "CONNSIZE",
|
||||
ConnSize_Analyzer::InstantiateAnalyzer,
|
||||
ConnSize_Analyzer::Available, 0, false },
|
||||
|
||||
{ AnalyzerTag::Contents, "CONTENTS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::ContentLine, "CONTENTLINE", 0, 0, 0, false },
|
||||
{ AnalyzerTag::NVT, "NVT", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Zip, "ZIP", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_DNS, "CONTENTS_DNS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NetbiosSSN, "CONTENTS_NETBIOSSSN", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NCP, "CONTENTS_NCP", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_Rlogin, "CONTENTS_Rlogin", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_Rsh, "CONTENTS_RSH", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_DCE_RPC, "CONTENTS_DCE_RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_SMB, "CONTENTS_SMB", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_RPC, "CONTENTS_RPC", 0, 0, 0, false },
|
||||
{ AnalyzerTag::Contents_NFS, "CONTENTS_NFS", 0, 0, 0, false },
|
||||
{ AnalyzerTag::FTP_ADAT, "FTP_ADAT", 0, 0, 0, false },
|
||||
Analyzer* analyzer;
|
||||
analyzer_timer_func timer;
|
||||
int do_expire;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using namespace analyzer;
|
||||
|
||||
AnalyzerTimer::AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
||||
double arg_t, int arg_do_expire, TimerType arg_type)
|
||||
: Timer(arg_t, arg_type)
|
||||
{
|
||||
Init(arg_analyzer, arg_timer, arg_do_expire);
|
||||
}
|
||||
|
||||
AnalyzerTimer::~AnalyzerTimer()
|
||||
{
|
||||
analyzer->RemoveTimer(this);
|
||||
|
@ -216,36 +70,53 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
|
|||
Ref(analyzer->Conn());
|
||||
}
|
||||
|
||||
AnalyzerID Analyzer::id_counter = 0;;
|
||||
analyzer::ID Analyzer::id_counter = 0;;
|
||||
|
||||
Analyzer* Analyzer::InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c)
|
||||
const char* Analyzer::GetAnalyzerName() const
|
||||
{
|
||||
Analyzer* a = analyzer_configs[tag].factory(c);
|
||||
assert(a);
|
||||
return a;
|
||||
assert(tag);
|
||||
return analyzer_mgr->GetAnalyzerName(tag);
|
||||
}
|
||||
|
||||
const char* Analyzer::GetTagName(AnalyzerTag::Tag tag)
|
||||
void Analyzer::SetAnalyzerTag(const Tag& arg_tag)
|
||||
{
|
||||
return analyzer_configs[tag].name;
|
||||
assert(! tag || tag == arg_tag);
|
||||
tag = arg_tag;
|
||||
}
|
||||
|
||||
AnalyzerTag::Tag Analyzer::GetTag(const char* name)
|
||||
bool Analyzer::IsAnalyzer(const char* name)
|
||||
{
|
||||
for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
|
||||
if ( strcasecmp(analyzer_configs[i].name, name) == 0 )
|
||||
return analyzer_configs[i].tag;
|
||||
|
||||
return AnalyzerTag::Error;
|
||||
assert(tag);
|
||||
return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0;
|
||||
}
|
||||
|
||||
// Used in debugging output.
|
||||
static string fmt_analyzer(Analyzer* a)
|
||||
{
|
||||
return string(a->GetTagName()) + fmt("[%d]", a->GetID());
|
||||
return string(a->GetAnalyzerName()) + fmt("[%d]", a->GetID());
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(AnalyzerTag::Tag arg_tag, Connection* arg_conn)
|
||||
Analyzer::Analyzer(const char* name, Connection* conn)
|
||||
{
|
||||
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
||||
|
||||
if ( ! tag )
|
||||
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name);
|
||||
|
||||
CtorInit(tag, conn);
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(const Tag& tag, Connection* conn)
|
||||
{
|
||||
CtorInit(tag, conn);
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(Connection* conn)
|
||||
{
|
||||
CtorInit(Tag(), conn);
|
||||
}
|
||||
|
||||
void Analyzer::CtorInit(const Tag& arg_tag, Connection* arg_conn)
|
||||
{
|
||||
// Don't Ref conn here to avoid circular ref'ing. It can't be deleted
|
||||
// before us.
|
||||
|
@ -355,11 +226,6 @@ void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq,
|
|||
}
|
||||
}
|
||||
|
||||
const char* Analyzer::GetTagName() const
|
||||
{
|
||||
return GetTagName(tag);
|
||||
}
|
||||
|
||||
void Analyzer::NextStream(int len, const u_char* data, bool is_orig)
|
||||
{
|
||||
if ( skip )
|
||||
|
@ -514,7 +380,7 @@ void Analyzer::ForwardEndOfData(bool orig)
|
|||
|
||||
void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
||||
{
|
||||
if ( HasChildAnalyzer(analyzer->GetTag()) )
|
||||
if ( HasChildAnalyzer(analyzer->GetAnalyzerTag()) )
|
||||
{
|
||||
analyzer->Done();
|
||||
delete analyzer;
|
||||
|
@ -533,16 +399,19 @@ void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
|||
if ( init )
|
||||
analyzer->Init();
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s added child %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s added child %s",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::AddChildAnalyzer(AnalyzerTag::Tag analyzer)
|
||||
Analyzer* Analyzer::AddChildAnalyzer(Tag analyzer)
|
||||
{
|
||||
if ( ! HasChildAnalyzer(analyzer) )
|
||||
{
|
||||
Analyzer* a = InstantiateAnalyzer(analyzer, conn);
|
||||
Analyzer* a = analyzer_mgr->InstantiateAnalyzer(analyzer, conn);
|
||||
|
||||
if ( a )
|
||||
AddChildAnalyzer(a);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -554,7 +423,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
|||
LOOP_OVER_CHILDREN(i)
|
||||
if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s disabling child %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s disabling child %s",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||
// We just flag it as being removed here but postpone
|
||||
// actually doing that to later. Otherwise, we'd need
|
||||
|
@ -567,12 +436,12 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
|||
}
|
||||
}
|
||||
|
||||
void Analyzer::RemoveChildAnalyzer(AnalyzerID id)
|
||||
void Analyzer::RemoveChildAnalyzer(ID id)
|
||||
{
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s disabling child %s", GetTagName(), id,
|
||||
DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName(), id,
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||
// See comment above.
|
||||
(*i)->removing = true;
|
||||
|
@ -580,7 +449,7 @@ void Analyzer::RemoveChildAnalyzer(AnalyzerID id)
|
|||
}
|
||||
}
|
||||
|
||||
bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
|
||||
bool Analyzer::HasChildAnalyzer(Tag tag)
|
||||
{
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
if ( (*i)->tag == tag )
|
||||
|
@ -593,7 +462,7 @@ bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
|
|||
return false;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
||||
Analyzer* Analyzer::FindChild(ID arg_id)
|
||||
{
|
||||
if ( id == arg_id )
|
||||
return this;
|
||||
|
@ -608,7 +477,7 @@ Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
||||
Analyzer* Analyzer::FindChild(Tag arg_tag)
|
||||
{
|
||||
if ( tag == arg_tag )
|
||||
return this;
|
||||
|
@ -623,6 +492,12 @@ Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Analyzer* Analyzer::FindChild(const char* name)
|
||||
{
|
||||
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
||||
return tag ? FindChild(tag) : 0;
|
||||
}
|
||||
|
||||
void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||
{
|
||||
Analyzer* child = *i;
|
||||
|
@ -636,7 +511,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
|||
child->removing = false;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s deleted child %s 3",
|
||||
DBG_LOG(DBG_ANALYZER, "%s deleted child %s 3",
|
||||
fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str());
|
||||
|
||||
children.erase(i);
|
||||
|
@ -645,9 +520,9 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
|||
|
||||
void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||
{
|
||||
if ( HasSupportAnalyzer(analyzer->GetTag(), analyzer->IsOrig()) )
|
||||
if ( HasSupportAnalyzer(analyzer->GetAnalyzerTag(), analyzer->IsOrig()) )
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s already has %s %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s already has %s %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -675,7 +550,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
|
||||
analyzer->Init();
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s added %s support %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s added %s support %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -699,7 +574,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
else
|
||||
*head = s->sibling;
|
||||
|
||||
DBG_LOG(DBG_DPD, "%s removed support %s",
|
||||
DBG_LOG(DBG_ANALYZER, "%s removed support %s",
|
||||
fmt_analyzer(this).c_str(),
|
||||
analyzer->IsOrig() ? "originator" : "responder",
|
||||
fmt_analyzer(analyzer).c_str());
|
||||
|
@ -711,7 +586,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
|||
return;
|
||||
}
|
||||
|
||||
bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
|
||||
bool Analyzer::HasSupportAnalyzer(Tag tag, bool orig)
|
||||
{
|
||||
SupportAnalyzer* s = orig ? orig_supporters : resp_supporters;
|
||||
for ( ; s; s = s->sibling )
|
||||
|
@ -724,33 +599,33 @@ bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
|
|||
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||
int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||
DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
|
||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||
}
|
||||
|
||||
void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s DeliverStream(%d, %s) [%s%s]",
|
||||
DBG_LOG(DBG_ANALYZER, "%s DeliverStream(%d, %s) [%s%s]",
|
||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F",
|
||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||
}
|
||||
|
||||
void Analyzer::Undelivered(int seq, int len, bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s Undelivered(%d, %d, %s)",
|
||||
DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)",
|
||||
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
|
||||
}
|
||||
|
||||
void Analyzer::EndOfData(bool is_orig)
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s EndOfData(%s)",
|
||||
DBG_LOG(DBG_ANALYZER, "%s EndOfData(%s)",
|
||||
fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
|
||||
}
|
||||
|
||||
void Analyzer::FlipRoles()
|
||||
{
|
||||
DBG_LOG(DBG_DPD, "%s FlipRoles()");
|
||||
DBG_LOG(DBG_ANALYZER, "%s FlipRoles()");
|
||||
|
||||
LOOP_OVER_CHILDREN(i)
|
||||
(*i)->FlipRoles();
|
||||
|
@ -774,9 +649,12 @@ void Analyzer::ProtocolConfirmation()
|
|||
if ( protocol_confirmed )
|
||||
return;
|
||||
|
||||
EnumVal* tval = tag.AsEnumVal();
|
||||
Ref(tval);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(tag, TYPE_COUNT));
|
||||
vl->append(tval);
|
||||
vl->append(new Val(id, TYPE_COUNT));
|
||||
|
||||
// We immediately raise the event so that the analyzer can quickly
|
||||
|
@ -802,9 +680,12 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
|
|||
else
|
||||
r = new StringVal(reason);
|
||||
|
||||
EnumVal* tval = tag.AsEnumVal();
|
||||
Ref(tval);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(tag, TYPE_COUNT));
|
||||
vl->append(tval);
|
||||
vl->append(new Val(id, TYPE_COUNT));
|
||||
vl->append(r);
|
||||
|
||||
|
@ -876,6 +757,31 @@ void Analyzer::UpdateConnVal(RecordVal *conn_val)
|
|||
(*i)->UpdateConnVal(conn_val);
|
||||
}
|
||||
|
||||
RecordVal* Analyzer::BuildConnVal()
|
||||
{
|
||||
return conn->BuildConnVal();
|
||||
}
|
||||
|
||||
void Analyzer::Event(EventHandlerPtr f, const char* name)
|
||||
{
|
||||
conn->Event(f, this, name);
|
||||
}
|
||||
|
||||
void Analyzer::Event(EventHandlerPtr f, Val* v1, Val* v2)
|
||||
{
|
||||
conn->Event(f, this, v1, v2);
|
||||
}
|
||||
|
||||
void Analyzer::ConnectionEvent(EventHandlerPtr f, val_list* vl)
|
||||
{
|
||||
conn->ConnectionEvent(f, this, vl);
|
||||
}
|
||||
|
||||
void Analyzer::Weird(const char* name, const char* addl)
|
||||
{
|
||||
conn->Weird(name, addl);
|
||||
}
|
||||
|
||||
void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
|
||||
int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
852
src/analyzer/Analyzer.h
Normal file
852
src/analyzer/Analyzer.h
Normal file
|
@ -0,0 +1,852 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef ANALYZER_ANALYZER_H
|
||||
#define ANALYZER_ANALYZER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#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*> 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
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue