From 78b5f6b94b2d78d642165101183cbd7d20a49f75 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Wed, 2 Apr 2014 23:03:24 -0400 Subject: [PATCH 001/256] BinPAC SSH analyzer basic functionality. --- scripts/base/protocols/ssh/README | 1 - scripts/base/protocols/ssh/__load__.bro | 2 +- scripts/base/protocols/ssh/main.bro | 212 +++++---------------- src/analyzer/protocol/CMakeLists.txt | 4 +- src/analyzer/protocol/ssh/CMakeLists.txt | 8 +- src/analyzer/protocol/ssh/Plugin.cc | 7 +- src/analyzer/protocol/ssh/SSH.cc | 198 +++++++++++-------- src/analyzer/protocol/ssh/SSH.h | 51 ++++- src/analyzer/protocol/ssh/events.bif | 51 ++--- src/analyzer/protocol/ssh/ssh-analyzer.pac | 25 +++ src/analyzer/protocol/ssh/ssh-protocol.pac | 175 +++++++++++++++++ src/analyzer/protocol/ssh/ssh.pac | 32 ++++ 12 files changed, 465 insertions(+), 301 deletions(-) delete mode 100644 scripts/base/protocols/ssh/README create mode 100644 src/analyzer/protocol/ssh/ssh-analyzer.pac create mode 100644 src/analyzer/protocol/ssh/ssh-protocol.pac create mode 100644 src/analyzer/protocol/ssh/ssh.pac diff --git a/scripts/base/protocols/ssh/README b/scripts/base/protocols/ssh/README deleted file mode 100644 index c3f68d543f..0000000000 --- a/scripts/base/protocols/ssh/README +++ /dev/null @@ -1 +0,0 @@ -Support for Secure Shell (SSH) protocol analysis. diff --git a/scripts/base/protocols/ssh/__load__.bro b/scripts/base/protocols/ssh/__load__.bro index 0f3cb011f8..9e43682d13 100644 --- a/scripts/base/protocols/ssh/__load__.bro +++ b/scripts/base/protocols/ssh/__load__.bro @@ -1,3 +1,3 @@ +# Generated by binpac_quickstart @load ./main - @load-sigs ./dpd.sig \ No newline at end of file diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 33b0c84147..c3f90ec332 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -1,66 +1,31 @@ -##! Base SSH analysis script. The heuristic to blindly determine success or -##! failure for SSH connections is implemented here. At this time, it only -##! uses the size of the data being returned from the server to make the -##! heuristic determination about success of the connection. -##! Requires that :bro:id:`use_conn_size_analyzer` is set to T! The heuristic -##! is not attempted if the connection size analyzer isn't enabled. +##! Implements base functionality for SSH analysis. Generates the ssh.log file. -@load base/protocols/conn -@load base/frameworks/notice -@load base/utils/site -@load base/utils/thresholds -@load base/utils/conn-ids -@load base/utils/directions-and-hosts +# Generated by binpac_quickstart module SSH; export { - ## The SSH protocol logging stream identifier. redef enum Log::ID += { LOG }; type Info: record { - ## Time when the SSH connection began. - ts: time &log; + ## Timestamp for when the event happened. + ts: time &log; ## Unique ID for the connection. - uid: string &log; + uid: string &log; ## The connection's 4-tuple of endpoint addresses/ports. - id: conn_id &log; - ## Indicates if the login was heuristically guessed to be - ## "success", "failure", or "undetermined". - status: string &log &default="undetermined"; - ## Direction of the connection. If the client was a local host - ## logging into an external host, this would be OUTBOUND. INBOUND - ## would be set for the opposite situation. - # TODO: handle local-local and remote-remote better. - direction: Direction &log &optional; - ## Software string from the client. - client: string &log &optional; - ## Software string from the server. - server: string &log &optional; - ## Indicate if the SSH session is done being watched. - done: bool &default=F; + id: conn_id &log; + ## The client's version string + client: string &log &optional; + ## The server's version string + server: string &log &optional; + ## Auth result + result: string &log &optional; + ## Auth method + method: string &log &optional; }; - ## The size in bytes of data sent by the server at which the SSH - ## connection is presumed to be successful. - const authentication_data_size = 4000 &redef; - - ## If true, we tell the event engine to not look at further data - ## packets after the initial SSH handshake. Helps with performance - ## (especially with large file transfers) but precludes some - ## kinds of analyses. - const skip_processing_after_detection = F &redef; - - ## Event that is generated when the heuristic thinks that a login - ## was successful. - global heuristic_successful_login: event(c: connection); - - ## Event that is generated when the heuristic thinks that a login - ## failed. - global heuristic_failed_login: event(c: connection); - - ## Event that can be handled to access the :bro:type:`SSH::Info` - ## record as it is sent on to the logging framework. + ## Event that can be handled to access the SSH record as it is sent on + ## to the loggin framework. global log_ssh: event(rec: Info); } @@ -69,136 +34,55 @@ redef record connection += { }; const ports = { 22/tcp }; -redef likely_server_ports += { ports }; 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) - { - if ( ! c?$ssh ) - { - local info: Info; - info$ts=network_time(); - info$uid=c$uid; - info$id=c$id; - c$ssh = info; - } } -function check_ssh_connection(c: connection, done: bool) + +event ssh_version(c: connection, is_orig: bool, version: string) { - # If already done watching this connection, just return. - if ( c$ssh$done ) - return; - - if ( done ) + if ( !c?$ssh ) { - # If this connection is done, then we can look to see if - # this matches the conditions for a failed login. Failed - # logins are only detected at connection state removal. - - if ( # Require originators and responders to have sent at least 50 bytes. - c$orig$size > 50 && c$resp$size > 50 && - # Responders must be below 4000 bytes. - c$resp$size < authentication_data_size && - # Responder must have sent fewer than 40 packets. - c$resp$num_pkts < 40 && - # If there was a content gap we can't reliably do this heuristic. - c?$conn && c$conn$missed_bytes == 0 )# && - # Only "normal" connections can count. - #c$conn?$conn_state && c$conn$conn_state in valid_states ) - { - c$ssh$status = "failure"; - event SSH::heuristic_failed_login(c); - } - - if ( c$resp$size >= authentication_data_size ) - { - c$ssh$status = "success"; - event SSH::heuristic_successful_login(c); - } + local s: SSH::Info; + s$ts = network_time(); + s$uid = c$uid; + s$id = c$id; + c$ssh = s; } + if ( is_orig ) + c$ssh$client = version; else - { - # If this connection is still being tracked, then it's possible - # to watch for it to be a successful connection. - if ( c$resp$size >= authentication_data_size ) - { - c$ssh$status = "success"; - event SSH::heuristic_successful_login(c); - } - else - # This connection must be tracked longer. Let the scheduled - # check happen again. - return; - } - - # Set the direction for the log. - c$ssh$direction = Site::is_local_addr(c$id$orig_h) ? OUTBOUND : INBOUND; - - # Set the "done" flag to prevent the watching event from rescheduling - # after detection is done. - c$ssh$done=T; - - if ( skip_processing_after_detection ) - { - # Stop watching this connection, we don't care about it anymore. - skip_further_processing(c$id); - set_record_packets(c$id, F); - } + c$ssh$server = version; +# print c$ssh; } - -event heuristic_successful_login(c: connection) &priority=-5 +event ssh_auth_successful(c: connection, method: string) { - Log::write(SSH::LOG, c$ssh); - } - -event heuristic_failed_login(c: connection) &priority=-5 - { - Log::write(SSH::LOG, c$ssh); - } - -event connection_state_remove(c: connection) &priority=-5 - { - if ( c?$ssh ) - { - check_ssh_connection(c, T); - if ( c$ssh$status == "undetermined" ) - Log::write(SSH::LOG, c$ssh); - } - } - -event ssh_watcher(c: connection) - { - local id = c$id; - # don't go any further if this connection is gone already! - if ( ! connection_exists(id) ) + if ( !c?$ssh ) return; - - lookup_connection(c$id); - check_ssh_connection(c, F); - if ( ! c$ssh$done ) - schedule +15secs { ssh_watcher(c) }; + c$ssh$result = "success"; + c$ssh$method = method; + Log::write(SSH::LOG, c$ssh); } -event ssh_server_version(c: connection, version: string) &priority=5 +event ssh_auth_failed(c: connection, method: string) { - set_session(c); - c$ssh$server = version; + if ( !c?$ssh ) + return; + c$ssh$result = "failure"; + c$ssh$method = method; + Log::write(SSH::LOG, c$ssh); } -event ssh_client_version(c: connection, version: string) &priority=5 +event connection_closed(c: connection) { - set_session(c); - c$ssh$client = version; - - # The heuristic detection for SSH relies on the ConnSize analyzer. - # Don't do the heuristics if it's disabled. - if ( use_conn_size_analyzer ) - schedule +15secs { ssh_watcher(c) }; - } + if ( c?$ssh && !c$ssh?$result ) + { + c$ssh$result = "unknown"; + c$ssh$method = "unknown"; + Log::write(SSH::LOG, c$ssh); + } + } \ No newline at end of file diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index fc63aa4b66..59e33843ac 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -19,11 +19,11 @@ add_subdirectory(ident) add_subdirectory(interconn) add_subdirectory(irc) add_subdirectory(login) -add_subdirectory(modbus) add_subdirectory(mime) +add_subdirectory(modbus) add_subdirectory(ncp) -add_subdirectory(netflow) add_subdirectory(netbios) +add_subdirectory(netflow) add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) diff --git a/src/analyzer/protocol/ssh/CMakeLists.txt b/src/analyzer/protocol/ssh/CMakeLists.txt index 505c89332e..1266e4f496 100644 --- a/src/analyzer/protocol/ssh/CMakeLists.txt +++ b/src/analyzer/protocol/ssh/CMakeLists.txt @@ -1,9 +1,11 @@ +# Generated by binpac_quickstart include(BroPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) bro_plugin_begin(Bro SSH) -bro_plugin_cc(SSH.cc Plugin.cc) -bro_plugin_bif(events.bif) -bro_plugin_end() + bro_plugin_cc(SSH.cc Plugin.cc) + bro_plugin_bif(events.bif) + bro_plugin_pac(ssh.pac ssh-analyzer.pac ssh-protocol.pac) +bro_plugin_end() \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/Plugin.cc b/src/analyzer/protocol/ssh/Plugin.cc index 53a0294a88..ddb01964f5 100644 --- a/src/analyzer/protocol/ssh/Plugin.cc +++ b/src/analyzer/protocol/ssh/Plugin.cc @@ -1,10 +1,11 @@ +// Generated by binpac_quickstart #include "plugin/Plugin.h" #include "SSH.h" BRO_PLUGIN_BEGIN(Bro, SSH) - BRO_PLUGIN_DESCRIPTION("SSH analyzer"); - BRO_PLUGIN_ANALYZER("SSH", ssh::SSH_Analyzer); + BRO_PLUGIN_DESCRIPTION("Secure Shell analyzer"); + BRO_PLUGIN_ANALYZER("SSH", SSH::SSH_Analyzer); BRO_PLUGIN_BIF_FILE(events); -BRO_PLUGIN_END +BRO_PLUGIN_END \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index ab3f6a5e5b..caeb5c4ca7 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -1,105 +1,135 @@ -// See the file "COPYING" in the main distribution directory for copyright. +// Generated by binpac_quickstart -#include "config.h" - -#include - -#include "NetVar.h" #include "SSH.h" -#include "Event.h" -#include "analyzer/protocol/tcp/ContentLine.h" + +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "Reporter.h" #include "events.bif.h" -using namespace analyzer::ssh; +using namespace analyzer::SSH; SSH_Analyzer::SSH_Analyzer(Connection* c) + : tcp::TCP_ApplicationAnalyzer("SSH", c) - { - orig = new tcp::ContentLine_Analyzer(c, true); - orig->SetSkipPartial(true); - orig->SetCRLFAsEOL(LF_as_EOL); - AddSupportAnalyzer(orig); - resp = new tcp::ContentLine_Analyzer(c, false); - resp->SetSkipPartial(true); - resp->SetCRLFAsEOL(LF_as_EOL); - AddSupportAnalyzer(resp); + { + interp = new binpac::SSH::SSH_Conn(this); + had_gap = false; + num_encrypted_packets_seen = 0; + } + +SSH_Analyzer::~SSH_Analyzer() + { + delete interp; } -void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) +void SSH_Analyzer::Done() { - tcp::TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig); + + tcp::TCP_ApplicationAnalyzer::Done(); - // We're all done processing this endpoint - flag it as such, - // before we even determine whether we have any event generation - // work to do, to make sure we don't do any further work on it. - if ( is_orig ) - orig->SetSkipDeliveries(true); - else - resp->SetSkipDeliveries(true); + interp->FlowEOF(true); + interp->FlowEOF(false); + + } - if ( TCP() ) +void SSH_Analyzer::EndpointEOF(bool is_orig) + { + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + interp->FlowEOF(is_orig); + } + +void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + + assert(TCP()); + if ( TCP()->IsPartial() ) + return; + + if ( had_gap ) + // If only one side had a content gap, we could still try to + // deliver data to the other side if the script layer can handle this. + return; + + if ( num_encrypted_packets_seen || interp->get_state(orig) == binpac::SSH::ENCRYPTED ) { - // Don't try to parse version if there has already been a gap. - tcp::TCP_Endpoint* endp = is_orig ? TCP()->Orig() : TCP()->Resp(); - if ( endp->HadGap() ) - return; - } - - const char* line = (const char*) data; - - // The SSH identification looks like this: - // - // SSH-.-\n - // - // We're interested in the "version" part here. - - if ( length < 4 || memcmp(line, "SSH-", 4) != 0 ) - { - Weird("malformed_ssh_identification"); - ProtocolViolation("malformed ssh identification", line, length); + ProcessEncrypted(len, orig); return; } - int i; - for ( i = 4; i < length && line[i] != '-'; ++i ) - ; - - if ( TCP() ) + try { - if ( length >= i ) - { - IPAddr dst; - - if ( is_orig ) - dst = TCP()->Orig()->dst_addr; - else - dst = TCP()->Resp()->dst_addr; - - if ( Conn()->VersionFoundEvent(dst, line + i, - length - i) ) - ProtocolConfirmation(); - else - ProtocolViolation("malformed ssh version", - line, length); - } - else - { - Weird("malformed_ssh_version"); - ProtocolViolation("malformed ssh version", line, length); - } + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + printf(" **** %s\n", e.c_msg()); + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); } - - // Generate SSH events. - EventHandlerPtr event = is_orig ? - ssh_client_version : ssh_server_version; - if ( ! event ) - return; - - val_list* vl = new val_list; - vl->append(BuildConnVal()); - vl->append(new StringVal(length, line)); - - ConnectionEvent(event, vl); + } + +void SSH_Analyzer::Undelivered(int seq, int len, bool orig) + { + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + had_gap = true; + interp->NewGap(orig, len); + } + +void SSH_Analyzer::ProcessEncrypted(int len, bool orig) + { + if (!num_encrypted_packets_seen) + { + initial_encrypted_packet_size = len; + } + // printf("Encrypted packet of size %d from %s.\n", len, orig?"client":"server"); + int relative_len = len - initial_encrypted_packet_size; + if ( num_encrypted_packets_seen >= 2 ) + { + int auth_result = AuthResult(relative_len, orig); + if ( auth_result > 0 ) + { + StringVal* method = new StringVal(AuthMethod(relative_len, orig)); + if ( auth_result == 1 ) + BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); + if ( auth_result == 2 ) + BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); + } + packet_n_2_is_orig = packet_n_1_is_orig; + packet_n_2_size = packet_n_1_size; + } + packet_n_1_is_orig = orig; + packet_n_1_size = relative_len; + num_encrypted_packets_seen++; + } + + +int SSH_Analyzer::AuthResult(int len, bool orig) + { + if ( orig && !packet_n_1_is_orig && packet_n_2_is_orig ) + { + if ( len == -16 ) + return 1; + else if ( len >= 16 && + len <= 32 ) + return 2; + return 0; + } + return -1; + } + +const char* SSH_Analyzer::AuthMethod(int len, bool orig) + { + if ( packet_n_1_size == 96 ) // Password auth + return "keyboard-interactive"; + if ( packet_n_1_size == 32 ) // Challenge-response auth + return "challenge-response"; + if ( packet_n_2_size >= 112 && + packet_n_2_size <= 432 ) // Public key auth + return "pubkey"; + if ( packet_n_2_size == 16 ) // Host-based auth + return "host-based"; + return fmt("unknown auth method: n-1=%d n-2=%d", packet_n_1_size, packet_n_2_size); } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 3878881693..7d391e8d66 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -1,25 +1,62 @@ -// See the file "COPYING" in the main distribution directory for copyright. +// Generated by binpac_quickstart #ifndef ANALYZER_PROTOCOL_SSH_SSH_H #define ANALYZER_PROTOCOL_SSH_SSH_H +#include "events.bif.h" + + #include "analyzer/protocol/tcp/TCP.h" -#include "analyzer/protocol/tcp/ContentLine.h" -namespace analyzer { namespace ssh { +#include "ssh_pac.h" + +namespace analyzer { namespace SSH { + +class SSH_Analyzer + +: public tcp::TCP_ApplicationAnalyzer { -class SSH_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SSH_Analyzer(Connection* conn); + virtual ~SSH_Analyzer(); + // Overriden from Analyzer. + virtual void Done(); + virtual void DeliverStream(int len, const u_char* data, bool orig); + virtual void Undelivered(int seq, int len, bool orig); + // Overriden from tcp::TCP_ApplicationAnalyzer. + virtual void EndpointEOF(bool is_orig); + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SSH_Analyzer(conn); } -private: - tcp::ContentLine_Analyzer* orig; - tcp::ContentLine_Analyzer* resp; + static bool Available() + { + // TODO: After you define your events, || them together here. + // See events.bif for more information + return ( ssh_event ); + } + +protected: + binpac::SSH::SSH_Conn* interp; + + void ProcessEncrypted(int len, bool orig); + int AuthResult(int len, bool orig); + const char* AuthMethod(int len, bool orig); + + bool had_gap; + + // Packet analysis stuff + int initial_encrypted_packet_size; + int num_encrypted_packets_seen; + + bool packet_n_1_is_orig; + int packet_n_1_size; + bool packet_n_2_is_orig; + int packet_n_2_size; + }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 9d73f5e483..f1fa16919d 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -1,38 +1,17 @@ -## Generated when seeing an SSH client's version identification. The SSH -## protocol starts with a clear-text handshake message that reports client and -## server protocol/software versions. This event provides access to what the -## client sent. -## -## -## See `Wikipedia `__ for more -## information about the SSH protocol. -## -## c: The connection. -## -## version: The version string the client sent (e.g., `SSH-2.0-libssh-0.11`). -## -## .. bro:see:: ssh_server_version -## -## .. note:: As everything after the initial version handshake proceeds -## encrypted, Bro cannot further analyze SSH sessions. -event ssh_client_version%(c: connection, version: string%); +# Generated by binpac_quickstart -## Generated when seeing an SSH server's version identification. The SSH -## protocol starts with a clear-text handshake message that reports client and -## server protocol/software versions. This event provides access to what the -## server sent. -## -## See `Wikipedia `__ for more -## information about the SSH protocol. -## -## c: The connection. -## -## version: The version string the server sent (e.g., -## ``SSH-1.99-OpenSSH_3.9p1``). -## -## .. bro:see:: ssh_client_version -## -## .. note:: As everything coming after the initial version handshake proceeds -## encrypted, Bro cannot further analyze SSH sessions. -event ssh_server_version%(c: connection, version: string%); +# In this file, you'll define the events that your analyzer will generate. A sample event is included. +## Generated for SSH connections +## +## See `Google `__ for more information about SSH +## +## c: The connection +##3 +event ssh_event%(c: connection%); + +event ssh_version%(c: connection, is_orig: bool, version: string%); + +event ssh_auth_successful%(c: connection, method: string%); + +event ssh_auth_failed%(c: connection, method: string%); \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac new file mode 100644 index 0000000000..5cde754521 --- /dev/null +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -0,0 +1,25 @@ +# Generated by binpac_quickstart + +refine flow SSH_Flow += { + function proc_ssh_version(msg: SSH_Version): bool + %{ + BifEvent::generate_ssh_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${msg.is_orig}, + bytestring_to_val(${msg.version})); + return true; + %} + + function proc_newkeys(): bool + %{ + connection()->bro_analyzer()->ProtocolConfirmation(); + return true; + %} + +}; + +refine typeattr SSH_Version += &let { + proc: bool = $context.flow.proc_ssh_version(this); +}; + +refine typeattr SSH_Message += &let { + proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_MSG_NEWKEYS); +}; diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac new file mode 100644 index 0000000000..84b1bc1f6a --- /dev/null +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -0,0 +1,175 @@ +enum state { + VERSION_EXCHANGE = 0, + KEY_EXCHANGE_CLEARTEXT = 1, + ENCRYPTED = 2, +}; + +enum message_id { + SSH_MSG_DISCONNECT = 1, + SSH_MSG_IGNORE = 2, + SSH_MSG_UNIMPLEMENTED = 3, + SSH_MSG_DEBUG = 4, + SSH_MSG_SERVICE_REQUEST = 5, + SSH_MSG_SERVICE_ACCEPT = 6, + SSH_MSG_KEXINIT = 20, + SSH_MSG_NEWKEYS = 21, + SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, + SSH_MSG_KEX_DH_GEX_GROUP = 31, + SSH_MSG_KEX_DH_GEX_INIT = 32, + SSH_MSG_KEX_DH_GEX_REPLY = 33, + SSH_MSG_KEX_DH_GEX_REQUEST = 34, + SSH_MSG_USERAUTH_REQUEST = 50, + SSH_MSG_USERAUTH_FAILURE = 51, + SSH_MSG_USERAUTH_SUCCESS = 52, + SSH_MSG_USERAUTH_BANNER = 53, + SSH_MSG_GLOBAL_REQUEST = 80, + SSH_MSG_REQUEST_SUCCESS = 81, + SSH_MSG_REQUEST_FAILURE = 82, + SSH_MSG_CHANNEL_OPEN = 90, + SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91, + SSH_MSG_CHANNEL_OPEN_FAILURE = 92, + SSH_MSG_CHANNEL_WINDOW_ADJUST = 93, + SSH_MSG_CHANNEL_DATA = 94, + SSH_MSG_CHANNEL_EXTENDED_DATA = 95, + SSH_MSG_CHANNEL_EOF = 96, + SSH_MSG_CHANNEL_CLOSE = 97, + SSH_MSG_CHANNEL_REQUEST = 98, + SSH_MSG_CHANNEL_SUCCESS = 99, + SSH_MSG_CHANNEL_FAILURE = 100, +}; + +type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { + VERSION_EXCHANGE -> version: SSH_Version(is_orig); + KEY_EXCHANGE_CLEARTEXT -> kex: SSH_Key_Exchange(is_orig); + ENCRYPTED -> unk: bytestring &length=100; +} &byteorder=bigendian; + +type SSH_Version(is_orig: bool) = record { + version: bytestring &oneline; +} &let { + update_state: bool = $context.connection.update_state(KEY_EXCHANGE_CLEARTEXT, is_orig); +}; + +type SSH_Key_Exchange_Header(is_orig: bool) = record { + packet_length: uint32; + padding_length: uint8; +} &length=5; + +type SSH_Key_Exchange(is_orig: bool) = record { + header : SSH_Key_Exchange_Header(is_orig); + payload: SSH_Payload(is_orig, header.packet_length - header.padding_length - 2); + pad : bytestring &length=header.padding_length; +}; + +type SSH_Payload_Header(length: uint32) = record { + message_type: uint8; +} &length=1; + +type SSH_Payload(is_orig: bool, packet_length: uint32) = record { + header: SSH_Payload_Header(packet_length); + message: SSH_Message(is_orig, header.message_type, packet_length); +}; + +type SSH_Message(is_orig: bool, msg_type: uint8, packet_length: uint32) = case msg_type of { + SSH_MSG_KEXINIT -> kexinit: SSH_KEXINIT(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(is_orig, packet_length); + default -> unknown: bytestring &length=packet_length; +} &let { + detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == SSH_MSG_NEWKEYS); +}; + +type SSH_KEXINIT(is_orig: bool, length: uint32) = record { + cookie : bytestring &length=16; + kex_algorithms_len : uint32; + kex_algorithms : bytestring &length=kex_algorithms_len; + server_host_key_algorithms_len : uint32; + server_host_key_algorithms : bytestring &length=server_host_key_algorithms_len; + encryption_algorithms_client_to_server_len : uint32; + encryption_algorithms_client_to_server : bytestring &length=encryption_algorithms_client_to_server_len; + encryption_algorithms_server_to_client_len : uint32; + encryption_algorithms_server_to_client : bytestring &length=encryption_algorithms_server_to_client_len; + mac_algorithms_client_to_server_len : uint32; + mac_algorithms_client_to_server : bytestring &length=mac_algorithms_client_to_server_len; + mac_algorithms_server_to_client_len : uint32; + mac_algorithms_server_to_client : bytestring &length=mac_algorithms_server_to_client_len; + compression_algorithms_client_to_server_len : uint32; + compression_algorithms_client_to_server : bytestring &length=compression_algorithms_client_to_server_len; + compression_algorithms_server_to_client_len : uint32; + compression_algorithms_server_to_client : bytestring &length=compression_algorithms_server_to_client_len; + languages_client_to_server_len : uint32; + languages_client_to_server : bytestring &length=languages_client_to_server_len; + languages_server_to_client_len : uint32; + languages_server_to_client : bytestring &length=languages_server_to_client_len; + first_kex_packet_follows : uint8; + reserved : uint32; +} &length=length; + +type SSH_DH_GEX_REQUEST(is_orig: bool, length: uint32) = record { + min: uint32; + n : uint32; + max: uint32; +} &length=12; + +type SSH_DH_GEX_GROUP(is_orig: bool, length: uint32) = record { + p: mpint; + g: mpint; +} &length=length; + +type SSH_DH_GEX_INIT(is_orig: bool, length: uint32) = record { + e: mpint; +} &length=length; + +type SSH_DH_GEX_REPLY(is_orig: bool, length: uint32) = record { + k_s : ssh_string; + f : mpint; + signature: ssh_string; +} &length=length; + +#type SSH_NEWKEYS(is_orig: bool, length: uint32) = record { +# blah: ; +#} &let { +# detach: bool = $context.connection.detach(); +#} &length=0; + +type mpint = record { + len: uint32; + val: bytestring &length=len; +}; + +type ssh_string = record { + len: uint32; + val: bytestring &length=len; +}; + +refine connection SSH_Conn += { + %member{ + int state_up_; + int state_down_; + %} + + %init{ + state_up_ = VERSION_EXCHANGE; + state_down_ = VERSION_EXCHANGE; + %} + + function get_state(is_orig: bool): int + %{ + if ( is_orig ) + return state_up_; + else + return state_down_; + %} + + function update_state(s: state, is_orig: bool): bool + %{ + if ( is_orig ) + state_up_ = s; + else + state_down_ = s; + return true; + %} + +}; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh.pac b/src/analyzer/protocol/ssh/ssh.pac new file mode 100644 index 0000000000..b3181c4fa1 --- /dev/null +++ b/src/analyzer/protocol/ssh/ssh.pac @@ -0,0 +1,32 @@ +# Generated by binpac_quickstart + +# Analyzer for Secure Shell +# - ssh-protocol.pac: describes the SSH protocol messages +# - ssh-analyzer.pac: describes the SSH analyzer code + +%include binpac.pac +%include bro.pac + +%extern{ + #include "events.bif.h" +%} + +analyzer SSH withcontext { + connection: SSH_Conn; + flow: SSH_Flow; +}; + +# Our connection consists of two flows, one in each direction. +connection SSH_Conn(bro_analyzer: BroAnalyzer) { + upflow = SSH_Flow(true); + downflow = SSH_Flow(false); +}; + +%include ssh-protocol.pac + +# Now we define the flow: +flow SSH_Flow(is_orig: bool) { + flowunit = SSH_PDU(is_orig) withcontext(connection, this); +}; + +%include ssh-analyzer.pac \ No newline at end of file From 2698fcea8eb5f7e83ddaa6478a20f835bf3b4761 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 22 Apr 2014 18:26:39 -0400 Subject: [PATCH 002/256] SSH: Various updates. --- scripts/base/protocols/ssh/main.bro | 36 ++++++++++++---- src/analyzer/protocol/ssh/SSH.cc | 42 +++++++++++------- src/analyzer/protocol/ssh/SSH.h | 9 ++-- src/analyzer/protocol/ssh/events.bif | 20 +++------ src/analyzer/protocol/ssh/ssh-analyzer.pac | 50 ++++++++++++++++++++-- src/analyzer/protocol/ssh/ssh-protocol.pac | 19 +++++--- 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index c3f90ec332..b9768b6dbb 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -18,6 +18,8 @@ export { client: string &log &optional; ## The server's version string server: string &log &optional; + ## The server's key fingerprint + host_key: string &log &optional; ## Auth result result: string &log &optional; ## Auth method @@ -42,7 +44,7 @@ event bro_init() &priority=5 } -event ssh_version(c: connection, is_orig: bool, version: string) +event ssh_server_version(c: connection, version: string) { if ( !c?$ssh ) { @@ -52,16 +54,25 @@ event ssh_version(c: connection, is_orig: bool, version: string) s$id = c$id; c$ssh = s; } - if ( is_orig ) - c$ssh$client = version; - else - c$ssh$server = version; -# print c$ssh; + c$ssh$server = version; + } + +event ssh_client_version(c: connection, version: string) + { + if ( !c?$ssh ) + { + local s: SSH::Info; + s$ts = network_time(); + s$uid = c$uid; + s$id = c$id; + c$ssh = s; + } + c$ssh$client = version; } event ssh_auth_successful(c: connection, method: string) { - if ( !c?$ssh ) + if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "success"; c$ssh$method = method; @@ -70,7 +81,7 @@ event ssh_auth_successful(c: connection, method: string) event ssh_auth_failed(c: connection, method: string) { - if ( !c?$ssh ) + if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "failure"; c$ssh$method = method; @@ -85,4 +96,13 @@ event connection_closed(c: connection) c$ssh$method = "unknown"; Log::write(SSH::LOG, c$ssh); } + } + +event ssh_server_host_key(c: connection, key: string) + { + if ( !c?$ssh ) + return; + local lx = str_split(md5_hash(key), vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)); + lx[0] = ""; + c$ssh$host_key = sub(join_string_vec(lx, ":"), /:/, ""); } \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index caeb5c4ca7..c89a77b9e7 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -18,6 +18,8 @@ SSH_Analyzer::SSH_Analyzer(Connection* c) interp = new binpac::SSH::SSH_Conn(this); had_gap = false; num_encrypted_packets_seen = 0; + initial_client_packet_size = 0; + initial_server_packet_size = 0; } SSH_Analyzer::~SSH_Analyzer() @@ -54,7 +56,7 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) // deliver data to the other side if the script layer can handle this. return; - if ( num_encrypted_packets_seen || interp->get_state(orig) == binpac::SSH::ENCRYPTED ) + if ( interp->get_state(orig) == binpac::SSH::ENCRYPTED ) { ProcessEncrypted(len, orig); return; @@ -80,23 +82,33 @@ void SSH_Analyzer::Undelivered(int seq, int len, bool orig) void SSH_Analyzer::ProcessEncrypted(int len, bool orig) { - if (!num_encrypted_packets_seen) - { - initial_encrypted_packet_size = len; - } - // printf("Encrypted packet of size %d from %s.\n", len, orig?"client":"server"); - int relative_len = len - initial_encrypted_packet_size; - if ( num_encrypted_packets_seen >= 2 ) + if (orig && !initial_client_packet_size) + initial_client_packet_size = len; + if (!orig && !initial_server_packet_size) + initial_server_packet_size = len; + + int relative_len; + if (orig) + relative_len = len - initial_client_packet_size; + else + relative_len = len - initial_server_packet_size; + // printf("Encrypted packet of length %d from %s.\n", len, orig?"client":"server"); + if ( num_encrypted_packets_seen >= 4 ) { int auth_result = AuthResult(relative_len, orig); if ( auth_result > 0 ) { + num_encrypted_packets_seen = 1; + //printf("Have auth\n"); StringVal* method = new StringVal(AuthMethod(relative_len, orig)); if ( auth_result == 1 ) BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); if ( auth_result == 2 ) BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); } + } + if ( num_encrypted_packets_seen >= 2 ) + { packet_n_2_is_orig = packet_n_1_is_orig; packet_n_2_size = packet_n_1_size; } @@ -108,7 +120,7 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) int SSH_Analyzer::AuthResult(int len, bool orig) { - if ( orig && !packet_n_1_is_orig && packet_n_2_is_orig ) + if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) { if ( len == -16 ) return 1; @@ -123,13 +135,13 @@ int SSH_Analyzer::AuthResult(int len, bool orig) const char* SSH_Analyzer::AuthMethod(int len, bool orig) { if ( packet_n_1_size == 96 ) // Password auth - return "keyboard-interactive"; - if ( packet_n_1_size == 32 ) // Challenge-response auth - return "challenge-response"; + return fmt("password (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); + if ( packet_n_1_size == 32 && ( packet_n_2_size == 0 || packet_n_2_size == 48 ) ) // Challenge-response auth + return fmt("challenge-response (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); if ( packet_n_2_size >= 112 && packet_n_2_size <= 432 ) // Public key auth - return "pubkey"; + return fmt("pubkey (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); if ( packet_n_2_size == 16 ) // Host-based auth - return "host-based"; - return fmt("unknown auth method: n-1=%d n-2=%d", packet_n_1_size, packet_n_2_size); + return fmt("host-based (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); + return fmt("unknown (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 7d391e8d66..b0d8aade57 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -34,9 +34,9 @@ public: static bool Available() { - // TODO: After you define your events, || them together here. - // See events.bif for more information - return ( ssh_event ); + return ( ssh_server_version || ssh_client_version || + ssh_auth_successful || ssh_auth_failed || + ssh_server_capabilities || ssh_server_host_key ); } protected: @@ -49,7 +49,8 @@ protected: bool had_gap; // Packet analysis stuff - int initial_encrypted_packet_size; + int initial_client_packet_size; + int initial_server_packet_size; int num_encrypted_packets_seen; bool packet_n_1_is_orig; diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index f1fa16919d..cefb591a6e 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -1,17 +1,11 @@ -# Generated by binpac_quickstart +event ssh_server_version%(c: connection, version: string%); -# In this file, you'll define the events that your analyzer will generate. A sample event is included. - -## Generated for SSH connections -## -## See `Google `__ for more information about SSH -## -## c: The connection -##3 -event ssh_event%(c: connection%); - -event ssh_version%(c: connection, is_orig: bool, version: string%); +event ssh_client_version%(c: connection, version: string%); event ssh_auth_successful%(c: connection, method: string%); -event ssh_auth_failed%(c: connection, method: string%); \ No newline at end of file +event ssh_auth_failed%(c: connection, method: string%); + +event ssh_server_capabilities%(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string%); + +event ssh_server_host_key%(c: connection, key: string%); \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 5cde754521..05cf20d4b4 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -3,8 +3,34 @@ refine flow SSH_Flow += { function proc_ssh_version(msg: SSH_Version): bool %{ - BifEvent::generate_ssh_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${msg.is_orig}, - bytestring_to_val(${msg.version})); + if ( ssh_client_version && ${msg.is_orig } ) + BifEvent::generate_ssh_client_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), bytestring_to_val(${msg.version})); + else if ( ssh_server_version ) + BifEvent::generate_ssh_server_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), bytestring_to_val(${msg.version})); + return true; + %} + + function proc_ssh_kexinit(msg: SSH_KEXINIT): bool + %{ + if ( ssh_server_capabilities ) + BifEvent::generate_ssh_server_capabilities(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), + bytestring_to_val(${msg.kex_algorithms}), bytestring_to_val(${msg.server_host_key_algorithms}), + bytestring_to_val(${msg.encryption_algorithms_client_to_server}), + bytestring_to_val(${msg.encryption_algorithms_server_to_client}), + bytestring_to_val(${msg.mac_algorithms_client_to_server}), + bytestring_to_val(${msg.mac_algorithms_server_to_client}), + bytestring_to_val(${msg.compression_algorithms_client_to_server}), + bytestring_to_val(${msg.compression_algorithms_server_to_client}), + bytestring_to_val(${msg.languages_client_to_server}), + bytestring_to_val(${msg.languages_server_to_client})); + return true; + %} + + function proc_ssh_server_host_key(key: bytestring): bool + %{ + if ( ssh_server_host_key ) + BifEvent::generate_ssh_server_host_key(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), + bytestring_to_val(${key})); return true; %} @@ -14,12 +40,30 @@ refine flow SSH_Flow += { return true; %} + function debug(loc: uint8): bool + %{ + printf("DEBUG: %d", loc); + return true; + %} + }; refine typeattr SSH_Version += &let { proc: bool = $context.flow.proc_ssh_version(this); }; +refine typeattr SSH_KEXINIT += &let { + proc: bool = $context.flow.proc_ssh_kexinit(this); +}; + +refine typeattr SSH_DH_GEX_REPLY += &let { + proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); +}; + +refine typeattr SSH_DH_GEX_GROUP += &let { + proc: bool = $context.flow.proc_ssh_server_host_key(p.val); +}; + refine typeattr SSH_Message += &let { proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_MSG_NEWKEYS); -}; +}; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index 84b1bc1f6a..aea112ff10 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -41,7 +41,7 @@ enum message_id { type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { VERSION_EXCHANGE -> version: SSH_Version(is_orig); KEY_EXCHANGE_CLEARTEXT -> kex: SSH_Key_Exchange(is_orig); - ENCRYPTED -> unk: bytestring &length=100; + ENCRYPTED -> ciphertext: bytestring &length=1 &transient; } &byteorder=bigendian; type SSH_Version(is_orig: bool) = record { @@ -71,12 +71,13 @@ type SSH_Payload(is_orig: bool, packet_length: uint32) = record { }; type SSH_Message(is_orig: bool, msg_type: uint8, packet_length: uint32) = case msg_type of { - SSH_MSG_KEXINIT -> kexinit: SSH_KEXINIT(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(is_orig, packet_length); - default -> unknown: bytestring &length=packet_length; + SSH_MSG_KEXINIT -> kexinit: SSH_KEXINIT(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(is_orig, packet_length); + SSH_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(is_orig, packet_length); + SSH_MSG_NEWKEYS -> new_keys: bytestring &length=packet_length; } &let { detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == SSH_MSG_NEWKEYS); }; @@ -113,6 +114,10 @@ type SSH_DH_GEX_REQUEST(is_orig: bool, length: uint32) = record { max: uint32; } &length=12; +type SSH_DH_GEX_REQUEST_OLD(is_orig: bool, length: uint32) = record { + payload: bytestring &length=length; +} &length=length; + type SSH_DH_GEX_GROUP(is_orig: bool, length: uint32) = record { p: mpint; g: mpint; From 0a50688afc15dd10dac58e7ebcda4fff3088bfe7 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 28 Aug 2014 18:23:30 -0400 Subject: [PATCH 003/256] Move auth method detection into script-land, to make it easier to change. --- scripts/base/protocols/ssh/main.bro | 24 ++++++++++++++++++------ src/analyzer/protocol/ssh/SSH.cc | 23 ++++------------------- src/analyzer/protocol/ssh/SSH.h | 1 - src/analyzer/protocol/ssh/events.bif | 4 ++-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index b9768b6dbb..2ac289750a 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -22,7 +22,7 @@ export { host_key: string &log &optional; ## Auth result result: string &log &optional; - ## Auth method + ## Auth method (password, pubkey, etc.) method: string &log &optional; }; @@ -70,21 +70,34 @@ event ssh_client_version(c: connection, version: string) c$ssh$client = version; } -event ssh_auth_successful(c: connection, method: string) +function determine_auth_method(middle_pkt_len: int, first_pkt_len: int): string + { + if ( middle_pkt_len == 96 ) + return "password"; + if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) + return "challenge-response"; + if ( ( first_pkt_len >= 112 ) && ( first_pkt_len <= 432 ) ) + return "pubkey"; + if ( first_pkt_len == 16 ) + return "host-based"; + return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); + } + +event ssh_auth_successful(c: connection, middle_pkt_len: int, first_pkt_len: int) { if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "success"; - c$ssh$method = method; + c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); Log::write(SSH::LOG, c$ssh); } -event ssh_auth_failed(c: connection, method: string) +event ssh_auth_failed(c: connection, middle_pkt_len: int, first_pkt_len: int) { if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "failure"; - c$ssh$method = method; + c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); Log::write(SSH::LOG, c$ssh); } @@ -93,7 +106,6 @@ event connection_closed(c: connection) if ( c?$ssh && !c$ssh?$result ) { c$ssh$result = "unknown"; - c$ssh$method = "unknown"; Log::write(SSH::LOG, c$ssh); } } diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index c89a77b9e7..1d942c5097 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -68,7 +68,6 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } catch ( const binpac::Exception& e ) { - printf(" **** %s\n", e.c_msg()); ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); } } @@ -92,19 +91,18 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) relative_len = len - initial_client_packet_size; else relative_len = len - initial_server_packet_size; - // printf("Encrypted packet of length %d from %s.\n", len, orig?"client":"server"); if ( num_encrypted_packets_seen >= 4 ) { int auth_result = AuthResult(relative_len, orig); if ( auth_result > 0 ) { num_encrypted_packets_seen = 1; - //printf("Have auth\n"); - StringVal* method = new StringVal(AuthMethod(relative_len, orig)); if ( auth_result == 1 ) - BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); + BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), + packet_n_1_size, packet_n_2_size); if ( auth_result == 2 ) - BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), method); + BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), + packet_n_1_size, packet_n_2_size); } } if ( num_encrypted_packets_seen >= 2 ) @@ -132,16 +130,3 @@ int SSH_Analyzer::AuthResult(int len, bool orig) return -1; } -const char* SSH_Analyzer::AuthMethod(int len, bool orig) - { - if ( packet_n_1_size == 96 ) // Password auth - return fmt("password (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); - if ( packet_n_1_size == 32 && ( packet_n_2_size == 0 || packet_n_2_size == 48 ) ) // Challenge-response auth - return fmt("challenge-response (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); - if ( packet_n_2_size >= 112 && - packet_n_2_size <= 432 ) // Public key auth - return fmt("pubkey (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); - if ( packet_n_2_size == 16 ) // Host-based auth - return fmt("host-based (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); - return fmt("unknown (L=%d, L-1=%d, L-2=%d)", len, packet_n_1_size, packet_n_2_size); - } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index b0d8aade57..7ded40c32c 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -44,7 +44,6 @@ protected: void ProcessEncrypted(int len, bool orig); int AuthResult(int len, bool orig); - const char* AuthMethod(int len, bool orig); bool had_gap; diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index cefb591a6e..1389b2e0da 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -2,9 +2,9 @@ event ssh_server_version%(c: connection, version: string%); event ssh_client_version%(c: connection, version: string%); -event ssh_auth_successful%(c: connection, method: string%); +event ssh_auth_successful%(c: connection, middle_packet_len: int, first_packet_len: int%); -event ssh_auth_failed%(c: connection, method: string%); +event ssh_auth_failed%(c: connection, middle_packet_len: int, first_packet_len: int%); event ssh_server_capabilities%(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string%); From 51373b0592307b9b5957294c8d315959b5fa4195 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 2 Sep 2014 00:15:32 -0400 Subject: [PATCH 004/256] SSH: Misc. updates to the new analyzer. --- scripts/base/protocols/ssh/main.bro | 103 ++++++++++++++++----- src/analyzer/protocol/ssh/SSH.cc | 27 ++++-- src/analyzer/protocol/ssh/ssh-analyzer.pac | 4 - src/analyzer/protocol/ssh/ssh-protocol.pac | 62 ++++++------- 4 files changed, 128 insertions(+), 68 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 2ac289750a..bba3f8ac88 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -1,7 +1,5 @@ ##! Implements base functionality for SSH analysis. Generates the ssh.log file. -# Generated by binpac_quickstart - module SSH; export { @@ -14,20 +12,33 @@ export { uid: string &log; ## The connection's 4-tuple of endpoint addresses/ports. id: conn_id &log; + ## Auth result + result: string &log &optional; + ## Auth method (password, pubkey, etc.) + method: string &log &optional; + ## Direction of the connection. If the client was a local host + ## logging into an external host, this would be OUTBOUND. INBOUND + ## would be set for the opposite situation. + ## TODO: handle local-local and remote-remote better. + direction: Direction &log &optional; ## The client's version string client: string &log &optional; ## The server's version string server: string &log &optional; ## The server's key fingerprint host_key: string &log &optional; - ## Auth result - result: string &log &optional; - ## Auth method (password, pubkey, etc.) - method: string &log &optional; + ## This connection has been logged (internal use) + logged: bool &default=F; }; + ## If true, we tell the event engine to not look at further data + ## packets after the initial SSH handshake. Helps with performance + ## (especially with large file transfers) but precludes some + ## kinds of analyses. + const skip_processing_after_detection = F &redef; + ## Event that can be handled to access the SSH record as it is sent on - ## to the loggin framework. + ## to the logging framework. global log_ssh: event(rec: Info); } @@ -43,6 +54,24 @@ event bro_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports); } +function determine_auth_method(middle_pkt_len: int, first_pkt_len: int): string + { + # This is still being tested. + # Based on "Analysis for Identifying User Authentication Methods on SSH Connections" + # by Satoh, Nakamura, Ikenaga. + + if ( middle_pkt_len == 96 ) + return "password"; + if ( middle_pkt_len == 16 ) + return "gssapi"; + if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) + return "challenge-response"; + if ( middle_pkt_len < 256 ) + return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); + if ( first_pkt_len == 16 ) + return "host-based"; + return fmt("pubkey (~%d bits)", (first_pkt_len - 16)*8); + } event ssh_server_version(c: connection, version: string) { @@ -70,46 +99,74 @@ event ssh_client_version(c: connection, version: string) c$ssh$client = version; } -function determine_auth_method(middle_pkt_len: int, first_pkt_len: int): string - { - if ( middle_pkt_len == 96 ) - return "password"; - if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) - return "challenge-response"; - if ( ( first_pkt_len >= 112 ) && ( first_pkt_len <= 432 ) ) - return "pubkey"; - if ( first_pkt_len == 16 ) - return "host-based"; - return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); - } - event ssh_auth_successful(c: connection, middle_pkt_len: int, first_pkt_len: int) { + print "ssh_auth_successful"; if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "success"; c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); - Log::write(SSH::LOG, c$ssh); } +event ssh_auth_successful(c: connection, middle_pkt_len: int, first_pkt_len: int) &priority=-5 + { + c$ssh$logged = T; + Log::write(SSH::LOG, c$ssh); + } + event ssh_auth_failed(c: connection, middle_pkt_len: int, first_pkt_len: int) { + print "ssh_auth_failed"; if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "failure"; c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); + } + +event ssh_auth_failed(c: connection, middle_pkt_len: int, first_pkt_len: int) &priority=-5 + { + c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); } -event connection_closed(c: connection) +event connection_state_remove(c: connection) { if ( c?$ssh && !c$ssh?$result ) { c$ssh$result = "unknown"; - Log::write(SSH::LOG, c$ssh); } } +event ssh_server_capabilities(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string) + { + # print "kex_algorithms", kex_algorithms; + # print ""; + # print "server_host_key_algorithms", server_host_key_algorithms; + # print ""; + # print "encryption_algorithms_client_to_server", encryption_algorithms_client_to_server; + # print ""; + # print "encryption_algorithms_server_to_client", encryption_algorithms_server_to_client; + # print ""; + # print "mac_algorithms_client_to_server", mac_algorithms_client_to_server; + # print ""; + # print "mac_algorithms_server_to_client", mac_algorithms_server_to_client; + # print ""; + # print "compression_algorithms_client_to_server", compression_algorithms_client_to_server; + # print ""; + # print "compression_algorithms_server_to_client", compression_algorithms_server_to_client; + # print ""; + # print "languages_client_to_server", languages_client_to_server; + # print ""; + # print "languages_server_to_client", languages_server_to_client; + # print ""; + } + +event connection_state_remove(c: connection) &priority=-5 + { + if ( c?$ssh && !c$ssh$logged ) + Log::write(SSH::LOG, c$ssh); + } + event ssh_server_host_key(c: connection, key: string) { if ( !c?$ssh ) diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index 1d942c5097..c6ac74f5dc 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -91,12 +91,12 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) relative_len = len - initial_client_packet_size; else relative_len = len - initial_server_packet_size; - if ( num_encrypted_packets_seen >= 4 ) + + if ( num_encrypted_packets_seen >= 6 ) { int auth_result = AuthResult(relative_len, orig); if ( auth_result > 0 ) { - num_encrypted_packets_seen = 1; if ( auth_result == 1 ) BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), packet_n_1_size, packet_n_2_size); @@ -105,28 +105,35 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) packet_n_1_size, packet_n_2_size); } } - if ( num_encrypted_packets_seen >= 2 ) + if ( ( num_encrypted_packets_seen >= 2 ) && + ( orig != packet_n_1_is_orig ) ) { packet_n_2_is_orig = packet_n_1_is_orig; packet_n_2_size = packet_n_1_size; } - packet_n_1_is_orig = orig; - packet_n_1_size = relative_len; - num_encrypted_packets_seen++; + + if ( orig == packet_n_1_is_orig ) + packet_n_1_size += len; + else + { + packet_n_1_is_orig = orig; + packet_n_1_size = relative_len; + num_encrypted_packets_seen++; + } } int SSH_Analyzer::AuthResult(int len, bool orig) { - if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) + if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) { + printf("Auth result = %d\n", len); if ( len == -16 ) return 1; - else if ( len >= 16 && - len <= 32 ) + else if ( len >= 16 && len <= 32 ) return 2; return 0; } - return -1; + return -1; } diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 05cf20d4b4..e4dd71bc39 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -60,10 +60,6 @@ refine typeattr SSH_DH_GEX_REPLY += &let { proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); }; -refine typeattr SSH_DH_GEX_GROUP += &let { - proc: bool = $context.flow.proc_ssh_server_host_key(p.val); -}; - refine typeattr SSH_Message += &let { proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_MSG_NEWKEYS); }; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index aea112ff10..03f47fd67a 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -5,37 +5,37 @@ enum state { }; enum message_id { - SSH_MSG_DISCONNECT = 1, - SSH_MSG_IGNORE = 2, - SSH_MSG_UNIMPLEMENTED = 3, - SSH_MSG_DEBUG = 4, - SSH_MSG_SERVICE_REQUEST = 5, - SSH_MSG_SERVICE_ACCEPT = 6, - SSH_MSG_KEXINIT = 20, - SSH_MSG_NEWKEYS = 21, - SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, - SSH_MSG_KEX_DH_GEX_GROUP = 31, - SSH_MSG_KEX_DH_GEX_INIT = 32, - SSH_MSG_KEX_DH_GEX_REPLY = 33, - SSH_MSG_KEX_DH_GEX_REQUEST = 34, - SSH_MSG_USERAUTH_REQUEST = 50, - SSH_MSG_USERAUTH_FAILURE = 51, - SSH_MSG_USERAUTH_SUCCESS = 52, - SSH_MSG_USERAUTH_BANNER = 53, - SSH_MSG_GLOBAL_REQUEST = 80, - SSH_MSG_REQUEST_SUCCESS = 81, - SSH_MSG_REQUEST_FAILURE = 82, - SSH_MSG_CHANNEL_OPEN = 90, - SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91, - SSH_MSG_CHANNEL_OPEN_FAILURE = 92, - SSH_MSG_CHANNEL_WINDOW_ADJUST = 93, - SSH_MSG_CHANNEL_DATA = 94, - SSH_MSG_CHANNEL_EXTENDED_DATA = 95, - SSH_MSG_CHANNEL_EOF = 96, - SSH_MSG_CHANNEL_CLOSE = 97, - SSH_MSG_CHANNEL_REQUEST = 98, - SSH_MSG_CHANNEL_SUCCESS = 99, - SSH_MSG_CHANNEL_FAILURE = 100, + SSH_MSG_DISCONNECT = 1, + SSH_MSG_IGNORE = 2, + SSH_MSG_UNIMPLEMENTED = 3, + SSH_MSG_DEBUG = 4, + SSH_MSG_SERVICE_REQUEST = 5, + SSH_MSG_SERVICE_ACCEPT = 6, + SSH_MSG_KEXINIT = 20, + SSH_MSG_NEWKEYS = 21, + SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, + SSH_MSG_KEX_DH_GEX_GROUP = 31, + SSH_MSG_KEX_DH_GEX_INIT = 32, + SSH_MSG_KEX_DH_GEX_REPLY = 33, + SSH_MSG_KEX_DH_GEX_REQUEST = 34, + SSH_MSG_USERAUTH_REQUEST = 50, + SSH_MSG_USERAUTH_FAILURE = 51, + SSH_MSG_USERAUTH_SUCCESS = 52, + SSH_MSG_USERAUTH_BANNER = 53, + SSH_MSG_GLOBAL_REQUEST = 80, + SSH_MSG_REQUEST_SUCCESS = 81, + SSH_MSG_REQUEST_FAILURE = 82, + SSH_MSG_CHANNEL_OPEN = 90, + SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91, + SSH_MSG_CHANNEL_OPEN_FAILURE = 92, + SSH_MSG_CHANNEL_WINDOW_ADJUST = 93, + SSH_MSG_CHANNEL_DATA = 94, + SSH_MSG_CHANNEL_EXTENDED_DATA = 95, + SSH_MSG_CHANNEL_EOF = 96, + SSH_MSG_CHANNEL_CLOSE = 97, + SSH_MSG_CHANNEL_REQUEST = 98, + SSH_MSG_CHANNEL_SUCCESS = 99, + SSH_MSG_CHANNEL_FAILURE = 100, }; type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { From 2446a942e0177c4f6bb2bc59b5be9e0376e14cdb Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Thu, 4 Sep 2014 20:41:44 -0400 Subject: [PATCH 005/256] Plugin API: minor change (adding parent frame) to support calling methods from hook. Also declare network time update argument to be const because good practice. --- src/Func.cc | 4 ++-- src/plugin/Manager.cc | 7 ++++--- src/plugin/Manager.h | 4 ++-- src/plugin/Plugin.cc | 4 ++-- src/plugin/Plugin.h | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index d66e9c71fa..ae449afeb3 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -331,7 +331,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const if ( sample_logger ) sample_logger->FunctionSeen(this); - Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, args), 0); + Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); if ( plugin_result ) return HandlePluginResult(plugin_result, args, Flavor()); @@ -548,7 +548,7 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const if ( sample_logger ) sample_logger->FunctionSeen(this); - Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, args), 0); + Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); if ( plugin_result ) return HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index ab0b85676b..f416172153 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -559,13 +559,14 @@ int Manager::HookLoadFile(const string& file) return rc; } -Val* Manager::HookCallFunction(const Func* func, val_list* vargs) const +Val* Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) const { HookArgumentList args; if ( HavePluginForHook(META_HOOK_PRE) ) { args.push_back(HookArgument(func)); + args.push_back(HookArgument(parent)); args.push_back(HookArgument(vargs)); MetaHookPre(HOOK_CALL_FUNCTION, args); } @@ -579,7 +580,7 @@ Val* Manager::HookCallFunction(const Func* func, val_list* vargs) const { Plugin* p = (*i).second; - v = p->HookCallFunction(func, vargs); + v = p->HookCallFunction(func, parent, vargs); if ( v ) break; @@ -644,7 +645,7 @@ void Manager::HookDrainEvents() const } -void Manager::HookUpdateNetworkTime(double network_time) const +void Manager::HookUpdateNetworkTime(const double network_time) const { HookArgumentList args; diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index 39a2f7f887..349db3e483 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -244,7 +244,7 @@ public: * functions and events, it may be any Val and must be ignored). If no * plugin handled the call, the method returns null. */ - Val* HookCallFunction(const Func* func, val_list* args) const; + Val* HookCallFunction(const Func* func, Frame *parent, val_list* args) const; /** * Hook that filters the queuing of an event. @@ -261,7 +261,7 @@ public: * * @param network_time The new network time. */ - void HookUpdateNetworkTime(double network_time) const; + void HookUpdateNetworkTime(const double network_time) const; /** * Hook that informs plugins that the event queue is being drained. diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 8aaadc1ec7..b0ccf38990 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -271,7 +271,7 @@ int Plugin::HookLoadFile(const std::string& file, const std::string& ext) return -1; } -Val* Plugin::HookCallFunction(const Func* func, val_list* args) +Val* Plugin::HookCallFunction(const Func* func, Frame *parent, val_list* args) { return 0; } @@ -285,7 +285,7 @@ void Plugin::HookDrainEvents() { } -void Plugin::HookUpdateNetworkTime(double network_time) +void Plugin::HookUpdateNetworkTime(const double network_time) { } diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 978e22b634..7794b496b2 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -573,7 +573,7 @@ protected: * ignored; best to use a \c TYPE_ANY). If the plugin did not handle * the call, it must return null. */ - virtual Val* HookCallFunction(const Func* func, val_list* args); + virtual Val* HookCallFunction(const Func* func, Frame *parent, val_list* args); /** * Hook into raising events. Whenever the script interpreter is about @@ -607,7 +607,7 @@ protected: * * @param networkt_time The new network time. */ - virtual void HookUpdateNetworkTime(double network_time); + virtual void HookUpdateNetworkTime(const double network_time); /** * Hook for destruction of objects registered with From 1a456cf9f7ebc30eadb8fc58b93fe576fc86712e Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Sat, 6 Sep 2014 13:48:44 -0400 Subject: [PATCH 006/256] Tweaks to result handling to make things a little more sane. --- src/Func.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index ae449afeb3..19ed5e1ea6 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -274,16 +274,23 @@ Val* Func::HandlePluginResult(Val* plugin_result, val_list* args, function_flavo else { - if ( plugin_result->Type()->Tag() != yt->Tag() ) - reporter->InternalError("plugin returned wrong type for function call"); - } + if ( plugin_result->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) + { + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->Type()->Tag(), yt->Tag(), this->Name()); + reporter->InternalError(sbuf); + } + } break; } } + /* + Let the plugin handle the reference counting loop_over_list(*args, i) Unref((*args)[i]); + */ return plugin_result; } From 8d04f58eda9c5890a7a93f8d9b0a720b268d2c4b Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Fri, 19 Sep 2014 21:55:47 -0400 Subject: [PATCH 007/256] Reverting change to const status of network_time. Also, see FIXME: in Func.cc / HandlePluginResult ... --- src/Func.cc | 23 ++++++++++++++++++----- src/plugin/Manager.cc | 2 +- src/plugin/Manager.h | 2 +- src/plugin/Plugin.cc | 2 +- src/plugin/Plugin.h | 4 ++-- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index 19ed5e1ea6..9a4ff6a4fb 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -269,12 +269,28 @@ Val* Func::HandlePluginResult(Val* plugin_result, val_list* args, function_flavo if ( (! yt) || yt->Tag() == TYPE_VOID ) { Unref(plugin_result); - plugin_result = 0; + plugin_result = NULL; } else { - if ( plugin_result->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) + /* + FIXME: I know this probably isn't a good idea, but what's the better solution? + + Hack: we want a way to force a NULL return in certain cases (e.g. function delayed). Since no function should ever reasonably return + an error, we use the error type to represent this case. + + Note that re-using a type that a function could reasonably return breaks down in the case of e.g. a delayed function, where the function + will have a very specific type but still return NULL because things have not yet been evaluated. Thus, if the delayed method returns a + bool, and our garbage return value is a bool, then how do we know whether or not the Val* returned by the function is actually meaningful + in the general case? + */ + if ( plugin_result->Type()->Tag() == TYPE_ERROR ) + { + Unref(plugin_result); + plugin_result = NULL; + } + else if ( plugin_result->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) { char sbuf[1024]; snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->Type()->Tag(), yt->Tag(), this->Name()); @@ -286,11 +302,8 @@ Val* Func::HandlePluginResult(Val* plugin_result, val_list* args, function_flavo } } - /* - Let the plugin handle the reference counting loop_over_list(*args, i) Unref((*args)[i]); - */ return plugin_result; } diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index f416172153..60e4d4fb78 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -645,7 +645,7 @@ void Manager::HookDrainEvents() const } -void Manager::HookUpdateNetworkTime(const double network_time) const +void Manager::HookUpdateNetworkTime(double network_time) const { HookArgumentList args; diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index 349db3e483..02071fa5b7 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -261,7 +261,7 @@ public: * * @param network_time The new network time. */ - void HookUpdateNetworkTime(const double network_time) const; + void HookUpdateNetworkTime(double network_time) const; /** * Hook that informs plugins that the event queue is being drained. diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index b0ccf38990..9565236d81 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -285,7 +285,7 @@ void Plugin::HookDrainEvents() { } -void Plugin::HookUpdateNetworkTime(const double network_time) +void Plugin::HookUpdateNetworkTime(double network_time) { } diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 7794b496b2..a921047b09 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -605,9 +605,9 @@ protected: * Hook for updates to network time. This method will be called * whenever network time is advanced. * - * @param networkt_time The new network time. + * @param network_time The new network time. */ - virtual void HookUpdateNetworkTime(const double network_time); + virtual void HookUpdateNetworkTime(double network_time); /** * Hook for destruction of objects registered with From d639488d36741e0b558bf4ab24d7b275f449195e Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Sat, 27 Sep 2014 08:03:30 -0400 Subject: [PATCH 008/256] Incremental commit: implementing a wrapper for the Val class. Just a checkpoint: need to add / update tests to make sure things work as expected. Should build / pass core btests, though. --- src/Func.cc | 94 +++++++++++-------- src/Func.h | 5 +- src/plugin/Manager.cc | 6 +- src/plugin/Manager.h | 2 +- src/plugin/Plugin.cc | 17 +++- src/plugin/Plugin.h | 55 +++++++++-- .../btest/plugins/hooks-plugin/src/Plugin.cc | 2 +- .../btest/plugins/hooks-plugin/src/Plugin.h | 2 +- 8 files changed, 127 insertions(+), 56 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index 9a4ff6a4fb..547af2c6ce 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -48,6 +48,8 @@ #include "Reporter.h" #include "plugin/Manager.h" +using plugin::ValWrapper; + extern RETSIGTYPE sig_handler(int signo); const Expr* calling_expr = 0; @@ -245,21 +247,40 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const HANDLE_TC_STMT_POST(tc); } -Val* Func::HandlePluginResult(Val* plugin_result, val_list* args, function_flavor flavor) const +ValWrapper* Func::HandlePluginResult(ValWrapper* plugin_result, val_list* args, function_flavor flavor) const { - // Helper function factoring out this code from BroFunc:Call() for better - // readability. + // We either have not received a plugin result, or the plugin result hasn't been processed (read: fall into ::Call method) + if(!plugin_result) + return NULL; + + if(!plugin_result->processed) + { + if(plugin_result->value) + { + Unref(plugin_result->value); + plugin_result->value = NULL; + } + delete plugin_result; + return NULL; + } switch ( flavor ) { case FUNC_FLAVOR_EVENT: - Unref(plugin_result); - plugin_result = 0; + if(plugin_result->value) + { + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned non-void result for event %s", this->Name()); + reporter->InternalError(sbuf); + } break; case FUNC_FLAVOR_HOOK: - if ( plugin_result->Type()->Tag() != TYPE_BOOL ) - reporter->InternalError("plugin returned non-bool for hook"); - + if ( plugin_result->value->Type()->Tag() != TYPE_BOOL ) + { + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned non-bool for hook %s", this->Name()); + reporter->InternalError(sbuf); + } break; case FUNC_FLAVOR_FUNCTION: @@ -268,34 +289,15 @@ Val* Func::HandlePluginResult(Val* plugin_result, val_list* args, function_flavo if ( (! yt) || yt->Tag() == TYPE_VOID ) { - Unref(plugin_result); - plugin_result = NULL; - } - - else + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned non-void result for void method %s", this->Name()); + reporter->InternalError(sbuf); + } + else if ( plugin_result->value->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) { - /* - FIXME: I know this probably isn't a good idea, but what's the better solution? - - Hack: we want a way to force a NULL return in certain cases (e.g. function delayed). Since no function should ever reasonably return - an error, we use the error type to represent this case. - - Note that re-using a type that a function could reasonably return breaks down in the case of e.g. a delayed function, where the function - will have a very specific type but still return NULL because things have not yet been evaluated. Thus, if the delayed method returns a - bool, and our garbage return value is a bool, then how do we know whether or not the Val* returned by the function is actually meaningful - in the general case? - */ - if ( plugin_result->Type()->Tag() == TYPE_ERROR ) - { - Unref(plugin_result); - plugin_result = NULL; - } - else if ( plugin_result->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) - { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->Type()->Tag(), yt->Tag(), this->Name()); - reporter->InternalError(sbuf); - } + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->value->Type()->Tag(), yt->Tag(), this->Name()); + reporter->InternalError(sbuf); } break; @@ -351,10 +353,15 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const if ( sample_logger ) sample_logger->FunctionSeen(this); - Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); + ValWrapper* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); - if ( plugin_result ) - return HandlePluginResult(plugin_result, args, Flavor()); + plugin_result = HandlePluginResult(plugin_result, args, Flavor()); + if(plugin_result) + { + Val *result = plugin_result->value; + delete plugin_result; + return result; + } if ( bodies.empty() ) { @@ -568,10 +575,15 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const if ( sample_logger ) sample_logger->FunctionSeen(this); - Val* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); + ValWrapper* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); - if ( plugin_result ) - return HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); + plugin_result = HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); + if(plugin_result) + { + Val *result = plugin_result->value; + delete plugin_result; + return result; + } if ( g_trace_state.DoTrace() ) { diff --git a/src/Func.h b/src/Func.h index 446043d581..bfaa24708b 100644 --- a/src/Func.h +++ b/src/Func.h @@ -14,6 +14,9 @@ class Stmt; class Frame; class ID; class CallExpr; +namespace plugin { + struct ValWrapper; +} class Func : public BroObj { public: @@ -71,7 +74,7 @@ protected: Func(); // Helper function for handling result of plugin hook. - Val* HandlePluginResult(Val* plugin_result, val_list* args, function_flavor flavor) const; + plugin::ValWrapper* HandlePluginResult(plugin::ValWrapper* plugin_result, val_list* args, function_flavor flavor) const; DECLARE_ABSTRACT_SERIAL(Func); diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index 60e4d4fb78..d6ac3866ea 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -559,7 +559,7 @@ int Manager::HookLoadFile(const string& file) return rc; } -Val* Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) const +ValWrapper* Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) const { HookArgumentList args; @@ -573,7 +573,7 @@ Val* Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) hook_list* l = hooks[HOOK_CALL_FUNCTION]; - Val* v = 0; + ValWrapper* v = 0; if ( l ) for ( hook_list::iterator i = l->begin(); i != l->end(); ++i ) @@ -582,7 +582,7 @@ Val* Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) v = p->HookCallFunction(func, parent, vargs); - if ( v ) + if ( v && v-> processed) break; } diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index 02071fa5b7..75d15a5c8b 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -244,7 +244,7 @@ public: * functions and events, it may be any Val and must be ignored). If no * plugin handled the call, the method returns null. */ - Val* HookCallFunction(const Func* func, Frame *parent, val_list* args) const; + ValWrapper* HookCallFunction(const Func* func, Frame *parent, val_list* args) const; /** * Hook that filters the queuing of an event. diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 9565236d81..8aa528bc3d 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -106,6 +106,21 @@ void HookArgument::Describe(ODesc* d) const d->Add(""); break; + case WRAPPED_VAL: + if ( arg.wrapper ) + { + d->Add("wrapped("); + if(arg.wrapper->value) + { + arg.wrapper->value->Describe(d); + } + else + d->Add(""); + d->Add(")"); + } + + break; + case VAL_LIST: if ( arg.vals ) { @@ -271,7 +286,7 @@ int Plugin::HookLoadFile(const std::string& file, const std::string& ext) return -1; } -Val* Plugin::HookCallFunction(const Func* func, Frame *parent, val_list* args) +ValWrapper* Plugin::HookCallFunction(const Func* func, Frame *parent, val_list* args) { return 0; } diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index a921047b09..9119d338d5 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -25,6 +25,34 @@ class Manager; class Component; class Plugin; +/** + * In certain cases, functions may have well-defined return types but still return NULL values (e.g. delayed functions, opaque types). + * Thus, it's necessary to explicitly define whether or not a plugin has handled a function in addition to recording the value it has + * returned. + * + * Plugins' function handlers return a result of this type. + */ +struct ValWrapper { + Val* value; //< value being wrapped by this object + bool processed; //< true if execution should *STOP* (read: the plugin is replacing a method), and false if execution should *CONTINUE* (read: bro should execute a method) + + /** + Wrapper for a specific value. If we're setting a value, we assume we've processed something. + + @param value value to be wrapped + */ + ValWrapper(Val* value) + : value(value), processed(true) { } + + /** + Wrapper for a specific value. If we're setting 'processed', we assume there's a reason we're not setting a Val and set that to NULL. + + @param processed whether or not an execution of a function was handled by the plugin + */ + ValWrapper(bool processed) + : value(NULL), processed(processed) { } +}; + /** * Hook types that a plugin may define. Each label maps to the corresponding * virtual method in \a Plugin. @@ -155,7 +183,7 @@ public: * Type of the argument. */ enum Type { - BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID, VOIDP, + BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, WRAPPED_VAL, VAL_LIST, VOID, VOIDP, }; /** @@ -208,6 +236,11 @@ public: */ HookArgument(void* p) { type = VOIDP; arg.voidp = p; } + /** + * Constructor with a ValWrapper argument. + */ + HookArgument(ValWrapper* a) { type = WRAPPED_VAL; arg.wrapper = a; } + /** * Returns the value for a boolen argument. The argument's type must * match accordingly. @@ -250,6 +283,12 @@ public: */ const Val* AsVal() const { assert(type == VAL); return arg.val; } + /** + * Returns the value for a Bro wrapped value argument. The argument's type must + * match accordingly. + */ + const ValWrapper* AsValWrapper() const { assert(type == VAL_WRAPPER); return arg.wrapper; } + /** * Returns the value for a list of Bro values argument. The argument's type must * match accordingly. @@ -283,6 +322,7 @@ private: const Func* func; int int_; const Val* val; + const ValWrapper* wrapper; const val_list* vals; const void* voidp; } arg; @@ -567,13 +607,14 @@ protected: * in place as long as it ensures matching types and correct reference * counting. * - * @return If the plugin handled the call, a Val with +1 reference - * count containixnmg the result value to pass back to the interpreter - * (for void functions and events any \a Val is fine; it will be - * ignored; best to use a \c TYPE_ANY). If the plugin did not handle - * the call, it must return null. + * @return If the plugin handled the call, a ValWrapper with the + * processed flag set to true, and a value set on the object with + * a+1 reference count containing the result value to pass back to the + * interpreter. If the plugin did not handle the call, it may either + * return NULL *or* return a ValWrapper with the processed flag set to + * 'false'. */ - virtual Val* HookCallFunction(const Func* func, Frame *parent, val_list* args); + virtual ValWrapper* HookCallFunction(const Func* func, Frame *parent, val_list* args); /** * Hook into raising events. Whenever the script interpreter is about diff --git a/testing/btest/plugins/hooks-plugin/src/Plugin.cc b/testing/btest/plugins/hooks-plugin/src/Plugin.cc index a9d0a529ba..e5507f5a0e 100644 --- a/testing/btest/plugins/hooks-plugin/src/Plugin.cc +++ b/testing/btest/plugins/hooks-plugin/src/Plugin.cc @@ -48,7 +48,7 @@ int Plugin::HookLoadFile(const std::string& file, const std::string& ext) return -1; } -Val* Plugin::HookCallFunction(const Func* func, val_list* args) +Val* Plugin::HookCallFunction(const Func* func, Frame* frame, val_list* args) { ODesc d; d.SetShort(); diff --git a/testing/btest/plugins/hooks-plugin/src/Plugin.h b/testing/btest/plugins/hooks-plugin/src/Plugin.h index 3bfa66a83f..940e427621 100644 --- a/testing/btest/plugins/hooks-plugin/src/Plugin.h +++ b/testing/btest/plugins/hooks-plugin/src/Plugin.h @@ -11,7 +11,7 @@ class Plugin : public ::plugin::Plugin { protected: virtual int HookLoadFile(const std::string& file, const std::string& ext); - virtual Val* HookCallFunction(const Func* func, val_list* args); + virtual Val* HookCallFunction(const Func* func, Frame* frame, val_list* args); virtual bool HookQueueEvent(Event* event); virtual void HookDrainEvents(); virtual void HookUpdateNetworkTime(double network_time); From 70c7258dfaf08729601507774ae4e1a797e43d75 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Thu, 2 Oct 2014 19:23:59 -0400 Subject: [PATCH 009/256] Updating tests and tweaking HookArgument to include Frame support. * Add frame support to HookArgument, since it's a new argument to HookCallFunction * Fix test in api-version-mismatch to remove absolute paths from output * Update test plugin to use new HookCallFunction interface --- src/plugin/Plugin.cc | 42 +- src/plugin/Plugin.h | 14 +- .../plugins.api-version-mismatch/output | 2 +- testing/btest/Baseline/plugins.hooks/output | 1714 ++++++++--------- testing/btest/plugins/api-version-mismatch.sh | 1 + .../btest/plugins/hooks-plugin/src/Plugin.cc | 3 +- .../btest/plugins/hooks-plugin/src/Plugin.h | 2 +- 7 files changed, 879 insertions(+), 899 deletions(-) diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 8aa528bc3d..1e98532ba6 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -83,6 +83,13 @@ void HookArgument::Describe(ODesc* d) const d->Add(""); break; + case FRAME: + if ( arg.frame ) + arg.frame->Describe(d); + else + d->Add(""); + break; + case FUNC: if ( arg.func ) d->Add(arg.func->Name()); @@ -106,21 +113,6 @@ void HookArgument::Describe(ODesc* d) const d->Add(""); break; - case WRAPPED_VAL: - if ( arg.wrapper ) - { - d->Add("wrapped("); - if(arg.wrapper->value) - { - arg.wrapper->value->Describe(d); - } - else - d->Add(""); - d->Add(")"); - } - - break; - case VAL_LIST: if ( arg.vals ) { @@ -139,6 +131,26 @@ void HookArgument::Describe(ODesc* d) const case VOIDP: d->Add(""); break; + + case WRAPPED_VAL: + if ( arg.wrapper ) + { + d->Add("wrapped("); + if(arg.wrapper->value) + { + arg.wrapper->value->Describe(d); + } + else + d->Add(""); + d->Add(")"); + } + else + { + d->Add(""); + } + + break; + } } diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 1269cf9a43..65acb37b7a 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -184,7 +184,7 @@ public: * Type of the argument. */ enum Type { - BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, WRAPPED_VAL, VAL_LIST, VOID, VOIDP, + BOOL, DOUBLE, EVENT, FRAME, FUNC, INT, STRING, VAL, VAL_LIST, VOID, VOIDP, WRAPPED_VAL }; /** @@ -242,6 +242,11 @@ public: */ HookArgument(ValWrapper* a) { type = WRAPPED_VAL; arg.wrapper = a; } + /** + * Constructor with a Frame argument. + */ + HookArgument(Frame* f) { type = FRAME; arg.frame = f; } + /** * Returns the value for a boolen argument. The argument's type must * match accordingly. @@ -290,6 +295,12 @@ public: */ const ValWrapper* AsValWrapper() const { assert(type == VAL_WRAPPER); return arg.wrapper; } + /** + * Returns the value for a Bro frame argument. The argument's type must + * match accordingly. + */ + const Frame* AsFrame() const { assert(type == FRAME); return arg.frame; } + /** * Returns the value for a list of Bro values argument. The argument's type must * match accordingly. @@ -321,6 +332,7 @@ private: double double_; const Event* event; const Func* func; + const Frame* frame; int int_; const Val* val; const ValWrapper* wrapper; diff --git a/testing/btest/Baseline/plugins.api-version-mismatch/output b/testing/btest/Baseline/plugins.api-version-mismatch/output index 806623cd02..fee3c9cd19 100644 --- a/testing/btest/Baseline/plugins.api-version-mismatch/output +++ b/testing/btest/Baseline/plugins.api-version-mismatch/output @@ -1 +1 @@ -fatal error in /home/robin/bro/master/scripts/base/init-bare.bro, line 1: plugin's API version does not match Bro (expected 2, got 42 in /home/robin/bro/master/testing/btest/.tmp/plugins.api-version-mismatch//lib/Demo-Foo.linux-x86_64.so) +fatal error in XXX line 1: plugin's API version does not match Bro (expected 2, got 42 in XXX diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 83341f3075..1fb647cd94 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -1,317 +1,294 @@ -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_AYIYA, {5072/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DHCP, {67<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNP3, {20000/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNS, {5355<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_MODBUS, {502/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_RADIUS, {1812/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SNMP, {162<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SOCKS, {1080/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSH, {22/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SYSLOG, {514/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_TEREDO, {3544/udp})) -> -0.000000 MetaHookPost CallFunction(Cluster::is_enabled, ()) -> -0.000000 MetaHookPost CallFunction(Files::register_analyzer_add_callback, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Cluster::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Communication::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DPD::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (PacketFilter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Reporter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Syslog::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Tunnel::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> -0.000000 MetaHookPost CallFunction(Log::__write, (PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Cluster::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Communication::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Conn::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DHCP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DNP3::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DNS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DPD::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (FTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Files::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (HTTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (IRC::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Intel::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Modbus::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Notice::ALARM_LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Notice::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (PacketFilter::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (RADIUS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Reporter::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SMTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SNMP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SOCKS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SSH::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SSL::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Signatures::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Software::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Syslog::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Tunnel::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Unified2::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Weird::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (X509::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Cluster::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Communication::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DPD::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (PacketFilter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Reporter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Syslog::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Tunnel::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> -0.000000 MetaHookPost CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::write, (PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Notice::want_pp, ()) -> -0.000000 MetaHookPost CallFunction(PacketFilter::build, ()) -> -0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, (ip or not ip, and, )) -> -0.000000 MetaHookPost CallFunction(PacketFilter::install, ()) -> -0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::STD_DEV, SumStats::VARIANCE)) -> -0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::VARIANCE, SumStats::AVERAGE)) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, ()) -> -0.000000 MetaHookPost CallFunction(bro_init, ()) -> -0.000000 MetaHookPost CallFunction(cat, (Packe, t, _, Filter)) -> -0.000000 MetaHookPost CallFunction(current_time, ()) -> -0.000000 MetaHookPost CallFunction(filter_change_tracking, ()) -> -0.000000 MetaHookPost CallFunction(fmt, (%s, PacketFilter::LOG)) -> -0.000000 MetaHookPost CallFunction(getenv, (CLUSTER_NODE)) -> -0.000000 MetaHookPost CallFunction(install_pcap_filter, (PacketFilter::DefaultPcapFilter)) -> -0.000000 MetaHookPost CallFunction(network_time, ()) -> -0.000000 MetaHookPost CallFunction(precompile_pcap_filter, (PacketFilter::DefaultPcapFilter, ip or not ip)) -> -0.000000 MetaHookPost CallFunction(reading_live_traffic, ()) -> -0.000000 MetaHookPost CallFunction(reading_traces, ()) -> -0.000000 MetaHookPost CallFunction(set_to_regex, ({}, (^\.?|\.)(~~)$)) -> -0.000000 MetaHookPost CallFunction(split1, (PacketFilter::LOG, <...>/)) -> -0.000000 MetaHookPost CallFunction(split_n, (PacketFilter, <...>/, T, 4)) -> -0.000000 MetaHookPost CallFunction(string_to_pattern, ((^\.?|\.)()$, F)) -> -0.000000 MetaHookPost CallFunction(sub, ((^\.?|\.)(~~)$, <...>/, )) -> -0.000000 MetaHookPost CallFunction(sub_bytes, (tFilter, 1, 1)) -> -0.000000 MetaHookPost CallFunction(sub_bytes, (tFilter, 2, 7)) -> -0.000000 MetaHookPost CallFunction(to_lower, (Packet_Filter)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_AYIYA5072<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP67<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP68<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNP320000<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS137<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5353<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5355<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP21<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP2811<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12123<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12152<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP1080<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP3128<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP631<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8000<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8080<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP80<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP81<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8888<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6666<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6667<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6668<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6669<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_MODBUS502<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_RADIUS1812<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP25<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP587<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP161<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP162<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SOCKS1080<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSH22<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL443<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL5223<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL563<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL585<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL614<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL636<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL989<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL990<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL992<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL993<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL995<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SYSLOG514<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_TEREDO3544<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) -> +0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) -> +0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) -> +0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_AYIYA{5072<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DHCP{67<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNP3{20000<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_FTP{2811<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_GTPV1{2152<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_HTTP{631<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_IRC{6669<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_MODBUS{502<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_RADIUS{1812<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SMTP{25<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SNMP{162<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SOCKS{1080<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSH{22<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSL{5223<...>/tcp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SYSLOG{514<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_TEREDO{3544<...>/udp)) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_AYIYA, {5072/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DHCP, {67<...>/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNP3, {20000/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNS, {5355<...>/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_MODBUS, {502/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SNMP, {162<...>/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SOCKS, {1080/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSH, {22/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_TEREDO, {3544/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_RADIUS, {1812/udp})) -> +0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_SYSLOG, {514/udp})) -> +0.000000 MetaHookPost CallFunction(Cluster::is_enabled, , ()) -> +0.000000 MetaHookPost CallFunction(Cluster::is_enabled, frame , ()) -> +0.000000 MetaHookPost CallFunction(Files::register_analyzer_add_callback, frame , (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) -> +0.000000 MetaHookPost CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -> +0.000000 MetaHookPost CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) -> +0.000000 MetaHookPost CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) -> +0.000000 MetaHookPost CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -> +0.000000 MetaHookPost CallFunction(Files::register_protocol, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Cluster::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Communication::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Conn::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame DHCP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame DNP3::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame DNS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame DPD::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame FTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Files::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame HTTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame IRC::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Intel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Modbus::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Notice::ALARM_LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Notice::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame PacketFilter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame RADIUS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Reporter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame SMTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame SNMP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame SOCKS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame SSH::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame SSL::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Signatures::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Software::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Syslog::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Tunnel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Unified2::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame Weird::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, frame X509::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Cluster::LOG[columns=, ev=], (Cluster::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Communication::LOG[columns=, ev=], (Communication::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG, [columns=, ev=Conn::log_conn])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG, [columns=, ev=DNS::log_dns])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame DPD::LOG[columns=, ev=], (DPD::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG, [columns=, ev=Files::log_files])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG, [columns=, ev=IRC::irc_log])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG, [columns=, ev=Intel::log_intel])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG, [columns=, ev=Notice::log_notice])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Reporter::LOG[columns=, ev=], (Reporter::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG, [columns=, ev=Software::log_software])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Syslog::LOG[columns=, ev=], (Syslog::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG, [columns=, ev=Weird::log_weird])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG, [columns=, ev=X509::log_x509])) -> +0.000000 MetaHookPost CallFunction(Log::__write, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Cluster::LOG[columns=, ev=], (Cluster::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Communication::LOG[columns=, ev=], (Communication::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame DPD::LOG[columns=, ev=], (DPD::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Reporter::LOG[columns=, ev=], (Reporter::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Syslog::LOG[columns=, ev=], (Syslog::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Cluster::LOG, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Communication::LOG, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Conn::LOG, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame DHCP::LOG, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame DNP3::LOG, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame DNS::LOG, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame DPD::LOG, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame FTP::LOG, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Files::LOG, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame HTTP::LOG, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame IRC::LOG, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Intel::LOG, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Modbus::LOG, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Notice::ALARM_LOG, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Notice::LOG, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame PacketFilter::LOG, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame RADIUS::LOG, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Reporter::LOG, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame SMTP::LOG, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame SNMP::LOG, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame SOCKS::LOG, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame SSH::LOG, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame SSL::LOG, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Signatures::LOG, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Software::LOG, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Syslog::LOG, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Tunnel::LOG, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Unified2::LOG, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame Weird::LOG, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::add_filter, frame X509::LOG, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Cluster::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Communication::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (DNS::LOG, [columns=, ev=DNS::log_dns])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (DPD::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Files::LOG, [columns=, ev=Files::log_files])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (IRC::LOG, [columns=, ev=IRC::irc_log])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Intel::LOG, [columns=, ev=Intel::log_intel])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Notice::ALARM_LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Notice::LOG, [columns=, ev=Notice::log_notice])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (PacketFilter::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Reporter::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Tunnel::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (Weird::LOG, [columns=, ev=Weird::log_weird])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame , (X509::LOG, [columns=, ev=X509::log_x509])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Conn::LOG, [columns=, ev=Conn::log_conn])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Software::LOG, [columns=, ev=Software::log_software])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Syslog::LOG, [columns=, ev=])) -> +0.000000 MetaHookPost CallFunction(Log::default_path_func, , (PacketFilter::LOG, , [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Notice::want_pp, frame , ()) -> +0.000000 MetaHookPost CallFunction(PacketFilter::build, frame [ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, frame [func=]ip or not ip, (ip or not ip, and, )) -> +0.000000 MetaHookPost CallFunction(PacketFilter::install, frame , ()) -> +0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::STD_DEV, SumStats::VARIANCE)) -> +0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::VARIANCE, SumStats::AVERAGE)) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, frame , ()) -> +0.000000 MetaHookPost CallFunction(bro_init, , ()) -> +0.000000 MetaHookPost CallFunction(cat, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (Packe, t, _, Filter)) -> +0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412291343.3228235.0 usecs[ts=0.0, node=bro, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip[ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(filter_change_tracking, , ()) -> +0.000000 MetaHookPost CallFunction(fmt, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (%s, PacketFilter::LOG)) -> +0.000000 MetaHookPost CallFunction(getenv, , (CLUSTER_NODE)) -> +0.000000 MetaHookPost CallFunction(install_pcap_filter, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::DefaultPcapFilter)) -> +0.000000 MetaHookPost CallFunction(network_time, frame ip or not ip1412291343.3228235.0 usecs[ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(precompile_pcap_filter, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], (PacketFilter::DefaultPcapFilter, ip or not ip)) -> +0.000000 MetaHookPost CallFunction(reading_live_traffic, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) -> +0.000000 MetaHookPost CallFunction(reading_traces, frame , ()) -> +0.000000 MetaHookPost CallFunction(reading_traces, frame , ()) -> +0.000000 MetaHookPost CallFunction(reading_traces, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) -> +0.000000 MetaHookPost CallFunction(set_to_regex, frame , ({}, (^\.?|\.)(~~)$)) -> +0.000000 MetaHookPost CallFunction(split1, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG, (PacketFilter::LOG, <...>/)) -> +0.000000 MetaHookPost CallFunction(split_n, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}, (PacketFilter, <...>/, T, 4)) -> +0.000000 MetaHookPost CallFunction(string_to_pattern, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)()$, F)) -> +0.000000 MetaHookPost CallFunction(sub, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)(~~)$, <...>/, )) -> +0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 1, 1)) -> +0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 2, 7)) -> +0.000000 MetaHookPost CallFunction(to_lower, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packet_Filter, (Packet_Filter)) -> 0.000000 MetaHookPost DrainEvents() -> 0.000000 MetaHookPost LoadFile(../main) -> -1 0.000000 MetaHookPost LoadFile(./Bro_ARP.events.bif.bro) -> -1 @@ -521,320 +498,297 @@ 0.000000 MetaHookPost LoadFile(base<...>/x509) -> -1 0.000000 MetaHookPost QueueEvent(bro_init()) -> false 0.000000 MetaHookPost QueueEvent(filter_change_tracking()) -> false -0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_AYIYA, {5072/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DHCP, {67<...>/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNP3, {20000/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNS, {5355<...>/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_MODBUS, {502/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_RADIUS, {1812/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SNMP, {162<...>/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SOCKS, {1080/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSH, {22/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SYSLOG, {514/udp})) -0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_TEREDO, {3544/udp})) -0.000000 MetaHookPre CallFunction(Cluster::is_enabled, ()) -0.000000 MetaHookPre CallFunction(Files::register_analyzer_add_callback, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) -0.000000 MetaHookPre CallFunction(Files::register_protocol, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -0.000000 MetaHookPre CallFunction(Files::register_protocol, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) -0.000000 MetaHookPre CallFunction(Files::register_protocol, (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) -0.000000 MetaHookPre CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) -0.000000 MetaHookPre CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Cluster::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Communication::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (DPD::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (PacketFilter::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Reporter::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Syslog::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Tunnel::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -0.000000 MetaHookPre CallFunction(Log::__create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -0.000000 MetaHookPre CallFunction(Log::__write, (PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Cluster::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Communication::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Conn::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (DHCP::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (DNP3::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (DNS::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (DPD::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (FTP::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Files::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (HTTP::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (IRC::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Intel::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Modbus::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Notice::ALARM_LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Notice::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (PacketFilter::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (RADIUS::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Reporter::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (SMTP::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (SNMP::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (SOCKS::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (SSH::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (SSL::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Signatures::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Software::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Syslog::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Tunnel::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Unified2::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Weird::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_default_filter, (X509::LOG)) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Cluster::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Communication::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (DPD::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (PacketFilter::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Reporter::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Syslog::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Tunnel::LOG, [columns=, ev=])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -0.000000 MetaHookPre CallFunction(Log::create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -0.000000 MetaHookPre CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -0.000000 MetaHookPre CallFunction(Log::write, (PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T])) -0.000000 MetaHookPre CallFunction(Notice::want_pp, ()) -0.000000 MetaHookPre CallFunction(PacketFilter::build, ()) -0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, (ip or not ip, and, )) -0.000000 MetaHookPre CallFunction(PacketFilter::install, ()) -0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::STD_DEV, SumStats::VARIANCE)) -0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::VARIANCE, SumStats::AVERAGE)) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, ()) -0.000000 MetaHookPre CallFunction(bro_init, ()) -0.000000 MetaHookPre CallFunction(cat, (Packe, t, _, Filter)) -0.000000 MetaHookPre CallFunction(current_time, ()) -0.000000 MetaHookPre CallFunction(filter_change_tracking, ()) -0.000000 MetaHookPre CallFunction(fmt, (%s, PacketFilter::LOG)) -0.000000 MetaHookPre CallFunction(getenv, (CLUSTER_NODE)) -0.000000 MetaHookPre CallFunction(install_pcap_filter, (PacketFilter::DefaultPcapFilter)) -0.000000 MetaHookPre CallFunction(network_time, ()) -0.000000 MetaHookPre CallFunction(precompile_pcap_filter, (PacketFilter::DefaultPcapFilter, ip or not ip)) -0.000000 MetaHookPre CallFunction(reading_live_traffic, ()) -0.000000 MetaHookPre CallFunction(reading_traces, ()) -0.000000 MetaHookPre CallFunction(set_to_regex, ({}, (^\.?|\.)(~~)$)) -0.000000 MetaHookPre CallFunction(split1, (PacketFilter::LOG, <...>/)) -0.000000 MetaHookPre CallFunction(split_n, (PacketFilter, <...>/, T, 4)) -0.000000 MetaHookPre CallFunction(string_to_pattern, ((^\.?|\.)()$, F)) -0.000000 MetaHookPre CallFunction(sub, ((^\.?|\.)(~~)$, <...>/, )) -0.000000 MetaHookPre CallFunction(sub_bytes, (tFilter, 1, 1)) -0.000000 MetaHookPre CallFunction(sub_bytes, (tFilter, 2, 7)) -0.000000 MetaHookPre CallFunction(to_lower, (Packet_Filter)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_AYIYA5072<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP67<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP68<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNP320000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS137<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5353<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5355<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP21<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP2811<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12123<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12152<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP3128<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP631<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP80<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP81<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8888<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6666<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6667<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6668<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6669<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_MODBUS502<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_RADIUS1812<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP25<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP587<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP161<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP162<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SOCKS1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSH22<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL443<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL5223<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL563<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL585<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL614<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL636<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL989<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL990<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL992<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL993<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL995<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SYSLOG514<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_TEREDO3544<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_AYIYA{5072<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DHCP{67<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNP3{20000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_FTP{2811<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_GTPV1{2152<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_HTTP{631<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_IRC{6669<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_MODBUS{502<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_RADIUS{1812<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SMTP{25<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SNMP{162<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SOCKS{1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSH{22<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSL{5223<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SYSLOG{514<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_TEREDO{3544<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_AYIYA, {5072/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DHCP, {67<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNP3, {20000/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNS, {5355<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_MODBUS, {502/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SNMP, {162<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SOCKS, {1080/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSH, {22/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_TEREDO, {3544/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_RADIUS, {1812/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_SYSLOG, {514/udp})) +0.000000 MetaHookPre CallFunction(Cluster::is_enabled, , ()) +0.000000 MetaHookPre CallFunction(Cluster::is_enabled, frame , ()) +0.000000 MetaHookPre CallFunction(Files::register_analyzer_add_callback, frame , (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Cluster::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Communication::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Conn::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DHCP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DNP3::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DNS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DPD::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame FTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Files::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame HTTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame IRC::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Intel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Modbus::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Notice::ALARM_LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Notice::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame PacketFilter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame RADIUS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Reporter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SMTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SNMP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SOCKS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SSH::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SSL::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Signatures::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Software::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Syslog::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Tunnel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Unified2::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Weird::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame X509::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Cluster::LOG[columns=, ev=], (Cluster::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Communication::LOG[columns=, ev=], (Communication::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG, [columns=, ev=Conn::log_conn])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG, [columns=, ev=DNS::log_dns])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DPD::LOG[columns=, ev=], (DPD::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG, [columns=, ev=FTP::log_ftp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG, [columns=, ev=Files::log_files])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG, [columns=, ev=HTTP::log_http])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG, [columns=, ev=IRC::irc_log])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG, [columns=, ev=Intel::log_intel])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG, [columns=, ev=Notice::log_notice])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Reporter::LOG[columns=, ev=], (Reporter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG, [columns=, ev=SSH::log_ssh])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG, [columns=, ev=SSL::log_ssl])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG, [columns=, ev=Signatures::log_signature])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG, [columns=, ev=Software::log_software])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Syslog::LOG[columns=, ev=], (Syslog::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG, [columns=, ev=Weird::log_weird])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG, [columns=, ev=X509::log_x509])) +0.000000 MetaHookPre CallFunction(Log::__write, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Cluster::LOG[columns=, ev=], (Cluster::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Communication::LOG[columns=, ev=], (Communication::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DPD::LOG[columns=, ev=], (DPD::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Reporter::LOG[columns=, ev=], (Reporter::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Syslog::LOG[columns=, ev=], (Syslog::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Cluster::LOG, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Communication::LOG, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Conn::LOG, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DHCP::LOG, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DNP3::LOG, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DNS::LOG, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DPD::LOG, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame FTP::LOG, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Files::LOG, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame HTTP::LOG, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame IRC::LOG, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Intel::LOG, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Modbus::LOG, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Notice::ALARM_LOG, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Notice::LOG, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame PacketFilter::LOG, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame RADIUS::LOG, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Reporter::LOG, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SMTP::LOG, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SNMP::LOG, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SOCKS::LOG, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SSH::LOG, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SSL::LOG, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Signatures::LOG, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Software::LOG, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Syslog::LOG, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Tunnel::LOG, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Unified2::LOG, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Weird::LOG, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame X509::LOG, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Cluster::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Communication::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DNS::LOG, [columns=, ev=DNS::log_dns])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DPD::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (FTP::LOG, [columns=, ev=FTP::log_ftp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Files::LOG, [columns=, ev=Files::log_files])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (HTTP::LOG, [columns=, ev=HTTP::log_http])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (IRC::LOG, [columns=, ev=IRC::irc_log])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Intel::LOG, [columns=, ev=Intel::log_intel])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Notice::ALARM_LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Notice::LOG, [columns=, ev=Notice::log_notice])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (PacketFilter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Reporter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SSH::LOG, [columns=, ev=SSH::log_ssh])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SSL::LOG, [columns=, ev=SSL::log_ssl])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Signatures::LOG, [columns=, ev=Signatures::log_signature])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Tunnel::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Weird::LOG, [columns=, ev=Weird::log_weird])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (X509::LOG, [columns=, ev=X509::log_x509])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Conn::LOG, [columns=, ev=Conn::log_conn])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Software::LOG, [columns=, ev=Software::log_software])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Syslog::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::default_path_func, , (PacketFilter::LOG, , [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Notice::want_pp, frame , ()) +0.000000 MetaHookPre CallFunction(PacketFilter::build, frame [ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, frame [func=]ip or not ip, (ip or not ip, and, )) +0.000000 MetaHookPre CallFunction(PacketFilter::install, frame , ()) +0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::STD_DEV, SumStats::VARIANCE)) +0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::VARIANCE, SumStats::AVERAGE)) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, frame , ()) +0.000000 MetaHookPre CallFunction(bro_init, , ()) +0.000000 MetaHookPre CallFunction(cat, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (Packe, t, _, Filter)) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip1412291343.3228235.0 usecs[ts=0.0, node=bro, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(filter_change_tracking, , ()) +0.000000 MetaHookPre CallFunction(fmt, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (%s, PacketFilter::LOG)) +0.000000 MetaHookPre CallFunction(getenv, , (CLUSTER_NODE)) +0.000000 MetaHookPre CallFunction(install_pcap_filter, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::DefaultPcapFilter)) +0.000000 MetaHookPre CallFunction(network_time, frame ip or not ip1412291343.3228235.0 usecs[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(precompile_pcap_filter, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], (PacketFilter::DefaultPcapFilter, ip or not ip)) +0.000000 MetaHookPre CallFunction(reading_live_traffic, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame , ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame , ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) +0.000000 MetaHookPre CallFunction(set_to_regex, frame , ({}, (^\.?|\.)(~~)$)) +0.000000 MetaHookPre CallFunction(split1, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG, (PacketFilter::LOG, <...>/)) +0.000000 MetaHookPre CallFunction(split_n, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}, (PacketFilter, <...>/, T, 4)) +0.000000 MetaHookPre CallFunction(string_to_pattern, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)()$, F)) +0.000000 MetaHookPre CallFunction(sub, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)(~~)$, <...>/, )) +0.000000 MetaHookPre CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 1, 1)) +0.000000 MetaHookPre CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 2, 7)) +0.000000 MetaHookPre CallFunction(to_lower, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packet_Filter, (Packet_Filter)) 0.000000 MetaHookPre DrainEvents() 0.000000 MetaHookPre LoadFile(../main) 0.000000 MetaHookPre LoadFile(./Bro_ARP.events.bif.bro) @@ -1228,7 +1182,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Unified2::LOG, [columns=, ev=Unified2::log_unified2]) 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) @@ -1319,8 +1273,8 @@ 0.000000 | HookCallFunction Log::create_stream(Unified2::LOG, [columns=, ev=Unified2::log_unified2]) 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509]) -0.000000 | HookCallFunction Log::default_path_func(PacketFilter::LOG, , [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1409853900.737227, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::default_path_func(PacketFilter::LOG, , [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) @@ -1367,20 +1321,20 @@ 0.000000 | HookQueueEvent bro_init() 0.000000 | HookQueueEvent filter_change_tracking() 1362692526.869344 MetaHookPost BroObjDtor() -> -1362692526.869344 MetaHookPost CallFunction(ChecksumOffloading::check, ()) -> -1362692526.869344 MetaHookPost CallFunction(filter_change_tracking, ()) -> -1362692526.869344 MetaHookPost CallFunction(net_stats, ()) -> -1362692526.869344 MetaHookPost CallFunction(new_connection, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.869344 MetaHookPost CallFunction(ChecksumOffloading::check, , ()) -> +1362692526.869344 MetaHookPost CallFunction(filter_change_tracking, , ()) -> +1362692526.869344 MetaHookPost CallFunction(net_stats, frame , ()) -> +1362692526.869344 MetaHookPost CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> 1362692526.869344 MetaHookPost DrainEvents() -> 1362692526.869344 MetaHookPost QueueEvent(ChecksumOffloading::check()) -> false 1362692526.869344 MetaHookPost QueueEvent(filter_change_tracking()) -> false 1362692526.869344 MetaHookPost QueueEvent(new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> false 1362692526.869344 MetaHookPost UpdateNetworkTime(1362692526.869344) -> 1362692526.869344 MetaHookPre BroObjDtor() -1362692526.869344 MetaHookPre CallFunction(ChecksumOffloading::check, ()) -1362692526.869344 MetaHookPre CallFunction(filter_change_tracking, ()) -1362692526.869344 MetaHookPre CallFunction(net_stats, ()) -1362692526.869344 MetaHookPre CallFunction(new_connection, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.869344 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692526.869344 MetaHookPre CallFunction(filter_change_tracking, , ()) +1362692526.869344 MetaHookPre CallFunction(net_stats, frame , ()) +1362692526.869344 MetaHookPre CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) 1362692526.869344 MetaHookPre DrainEvents() 1362692526.869344 MetaHookPre QueueEvent(ChecksumOffloading::check()) 1362692526.869344 MetaHookPre QueueEvent(filter_change_tracking()) @@ -1397,11 +1351,11 @@ 1362692526.869344 | HookQueueEvent filter_change_tracking() 1362692526.869344 | HookQueueEvent new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) 1362692526.869344 | RequestObjDtor ChecksumOffloading::check() -1362692526.939084 MetaHookPost CallFunction(connection_established, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.939084 MetaHookPost CallFunction(connection_established, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> 1362692526.939084 MetaHookPost DrainEvents() -> 1362692526.939084 MetaHookPost QueueEvent(connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> false 1362692526.939084 MetaHookPost UpdateNetworkTime(1362692526.939084) -> -1362692526.939084 MetaHookPre CallFunction(connection_established, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.939084 MetaHookPre CallFunction(connection_established, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) 1362692526.939084 MetaHookPre DrainEvents() 1362692526.939084 MetaHookPre QueueEvent(connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) 1362692526.939084 MetaHookPre UpdateNetworkTime(1362692526.939084) @@ -1415,32 +1369,32 @@ 1362692526.939378 MetaHookPre UpdateNetworkTime(1362692526.939378) 1362692526.939378 | HookUpdateNetworkTime 1362692526.939378 1362692526.939378 | HookDrainEvents -1362692526.939527 MetaHookPost CallFunction(Analyzer::__name, (Analyzer::ANALYZER_HTTP)) -> -1362692526.939527 MetaHookPost CallFunction(Analyzer::name, (Analyzer::ANALYZER_HTTP)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::new_http_session, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> -1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) -> -1362692526.939527 MetaHookPost CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692526.939527 MetaHookPost CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> -1362692526.939527 MetaHookPost CallFunction(fmt, (-%s, HTTP)) -> -1362692526.939527 MetaHookPost CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692526.939527 MetaHookPost CallFunction(http_begin_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692526.939527 MetaHookPost CallFunction(http_end_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692526.939527 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) -> -1362692526.939527 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) -> -1362692526.939527 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) -> -1362692526.939527 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) -> -1362692526.939527 MetaHookPost CallFunction(http_message_done, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -> -1362692526.939527 MetaHookPost CallFunction(http_request, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -> -1362692526.939527 MetaHookPost CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> -1362692526.939527 MetaHookPost CallFunction(network_time, ()) -> -1362692526.939527 MetaHookPost CallFunction(protocol_confirmation, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) -> -1362692526.939527 MetaHookPost CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692526.939527 MetaHookPost CallFunction(split1, (bro.org, <...>/)) -> +1362692526.939527 MetaHookPost CallFunction(Analyzer::__name, frame Analyzer::ANALYZER_HTTP, (Analyzer::ANALYZER_HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(Analyzer::name, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3, (Analyzer::ANALYZER_HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::new_http_session, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) -> +1362692526.939527 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692526.939527 MetaHookPost CallFunction(fmt, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3HTTP, (-%s, HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692526.939527 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) -> +1362692526.939527 MetaHookPost CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -> +1362692526.939527 MetaHookPost CallFunction(http_request, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -> +1362692526.939527 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692526.939527 MetaHookPost CallFunction(network_time, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=][ts=, uid=, id=[orig_h=, orig_p=, resp_h=, resp_p=], trans_depth=, method=, host=, uri=, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0], ()) -> +1362692526.939527 MetaHookPost CallFunction(protocol_confirmation, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) -> +1362692526.939527 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692526.939527 MetaHookPost CallFunction(split1, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> 1362692526.939527 MetaHookPost DrainEvents() -> 1362692526.939527 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false 1362692526.939527 MetaHookPost QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false @@ -1452,32 +1406,32 @@ 1362692526.939527 MetaHookPost QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -> false 1362692526.939527 MetaHookPost QueueEvent(http_request([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -> false 1362692526.939527 MetaHookPost UpdateNetworkTime(1362692526.939527) -> -1362692526.939527 MetaHookPre CallFunction(Analyzer::__name, (Analyzer::ANALYZER_HTTP)) -1362692526.939527 MetaHookPre CallFunction(Analyzer::name, (Analyzer::ANALYZER_HTTP)) -1362692526.939527 MetaHookPre CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692526.939527 MetaHookPre CallFunction(HTTP::new_http_session, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) -1362692526.939527 MetaHookPre CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -1362692526.939527 MetaHookPre CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -1362692526.939527 MetaHookPre CallFunction(fmt, (-%s, HTTP)) -1362692526.939527 MetaHookPre CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692526.939527 MetaHookPre CallFunction(http_begin_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692526.939527 MetaHookPre CallFunction(http_end_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692526.939527 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) -1362692526.939527 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) -1362692526.939527 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) -1362692526.939527 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) -1362692526.939527 MetaHookPre CallFunction(http_message_done, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -1362692526.939527 MetaHookPre CallFunction(http_request, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -1362692526.939527 MetaHookPre CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -1362692526.939527 MetaHookPre CallFunction(network_time, ()) -1362692526.939527 MetaHookPre CallFunction(protocol_confirmation, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) -1362692526.939527 MetaHookPre CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -1362692526.939527 MetaHookPre CallFunction(split1, (bro.org, <...>/)) +1362692526.939527 MetaHookPre CallFunction(Analyzer::__name, frame Analyzer::ANALYZER_HTTP, (Analyzer::ANALYZER_HTTP)) +1362692526.939527 MetaHookPre CallFunction(Analyzer::name, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3, (Analyzer::ANALYZER_HTTP)) +1362692526.939527 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::new_http_session, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) +1362692526.939527 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692526.939527 MetaHookPre CallFunction(fmt, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3HTTP, (-%s, HTTP)) +1362692526.939527 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692526.939527 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) +1362692526.939527 MetaHookPre CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) +1362692526.939527 MetaHookPre CallFunction(http_request, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) +1362692526.939527 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692526.939527 MetaHookPre CallFunction(network_time, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=][ts=, uid=, id=[orig_h=, orig_p=, resp_h=, resp_p=], trans_depth=, method=, host=, uri=, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0], ()) +1362692526.939527 MetaHookPre CallFunction(protocol_confirmation, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) +1362692526.939527 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) +1362692526.939527 MetaHookPre CallFunction(split1, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/)) 1362692526.939527 MetaHookPre DrainEvents() 1362692526.939527 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) 1362692526.939527 MetaHookPre QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) @@ -1532,22 +1486,38 @@ 1362692527.008509 MetaHookPre UpdateNetworkTime(1362692527.008509) 1362692527.008509 | HookUpdateNetworkTime 1362692527.008509 1362692527.008509 | HookDrainEvents -1362692527.009512 MetaHookPost CallFunction(HTTP::code_in_range, (200, 100, 199)) -> -1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> -1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> -1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> -1362692527.009512 MetaHookPost CallFunction(http_begin_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) -> -1362692527.009512 MetaHookPost CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -> -1362692527.009512 MetaHookPost CallFunction(http_reply, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) -> +1362692527.009512 MetaHookPost CallFunction(Files::__add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) -> +1362692527.009512 MetaHookPost CallFunction(Files::add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -> +1362692527.009512 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]1.1200OK[pending={}, current_request=0, current_response=0], (200, 100, 199)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009512 MetaHookPost CallFunction(file_new, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(file_over_new_connection, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.009512 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -> +1362692527.009512 MetaHookPost CallFunction(http_reply, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) -> +1362692527.009512 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.009512 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009512 MetaHookPost CallFunction(split_all, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/)) -> 1362692527.009512 MetaHookPost DrainEvents() -> +1362692527.009512 MetaHookPost QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> false +1362692527.009512 MetaHookPost QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009512 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false 1362692527.009512 MetaHookPost QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false 1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -> false 1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -> false @@ -1560,22 +1530,38 @@ 1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -> false 1362692527.009512 MetaHookPost QueueEvent(http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) -> false 1362692527.009512 MetaHookPost UpdateNetworkTime(1362692527.009512) -> -1362692527.009512 MetaHookPre CallFunction(HTTP::code_in_range, (200, 100, 199)) -1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -1362692527.009512 MetaHookPre CallFunction(http_begin_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) -1362692527.009512 MetaHookPre CallFunction(http_header, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -1362692527.009512 MetaHookPre CallFunction(http_reply, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) +1362692527.009512 MetaHookPre CallFunction(Files::__add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) +1362692527.009512 MetaHookPre CallFunction(Files::add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) +1362692527.009512 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009512 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]1.1200OK[pending={}, current_request=0, current_response=0], (200, 100, 199)) +1362692527.009512 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009512 MetaHookPre CallFunction(file_new, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre CallFunction(file_over_new_connection, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.009512 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) +1362692527.009512 MetaHookPre CallFunction(http_reply, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) +1362692527.009512 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.009512 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009512 MetaHookPre CallFunction(split_all, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/)) 1362692527.009512 MetaHookPre DrainEvents() +1362692527.009512 MetaHookPre QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) 1362692527.009512 MetaHookPre QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) 1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) 1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) @@ -1589,10 +1575,20 @@ 1362692527.009512 MetaHookPre QueueEvent(http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) 1362692527.009512 MetaHookPre UpdateNetworkTime(1362692527.009512) 1362692527.009512 | HookUpdateNetworkTime 1362692527.009512 +1362692527.009512 | HookCallFunction Files::__add_analyzers_for_mime_type(FakNcS1Jfe01uljb3, text/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0]) +1362692527.009512 | HookCallFunction Files::add_analyzers_for_mime_type([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain) +1362692527.009512 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) +1362692527.009512 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) 1362692527.009512 | HookCallFunction HTTP::code_in_range(200, 100, 199) +1362692527.009512 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) 1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) 1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) +1362692527.009512 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009512 | HookCallFunction file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) +1362692527.009512 | HookCallFunction file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) +1362692527.009512 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009512 | HookCallFunction http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes) 1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive) @@ -1604,7 +1600,13 @@ 1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora)) 1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8) 1362692527.009512 | HookCallFunction http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK) +1362692527.009512 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) +1362692527.009512 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009512 | HookCallFunction split_all(HTTP, <...>/) 1362692527.009512 | HookDrainEvents +1362692527.009512 | HookQueueEvent file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) +1362692527.009512 | HookQueueEvent file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009512 | HookQueueEvent http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes) 1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive) @@ -1616,124 +1618,76 @@ 1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora)) 1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8) 1362692527.009512 | HookQueueEvent http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK) -1362692527.009721 MetaHookPost CallFunction(Files::__add_analyzers_for_mime_type, (FakNcS1Jfe01uljb3, text/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) -> -1362692527.009721 MetaHookPost CallFunction(Files::add_analyzers_for_mime_type, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -> -1362692527.009721 MetaHookPost CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> -1362692527.009721 MetaHookPost CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> -1362692527.009721 MetaHookPost CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009721 MetaHookPost CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.009721 MetaHookPost CallFunction(file_new, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> -1362692527.009721 MetaHookPost CallFunction(file_over_new_connection, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009721 MetaHookPost CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> -1362692527.009721 MetaHookPost CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009721 MetaHookPost CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> -1362692527.009721 MetaHookPost CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.009721 MetaHookPost CallFunction(split_all, (HTTP, <...>/)) -> 1362692527.009721 MetaHookPost DrainEvents() -> -1362692527.009721 MetaHookPost QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> false -1362692527.009721 MetaHookPost QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false -1362692527.009721 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false 1362692527.009721 MetaHookPost UpdateNetworkTime(1362692527.009721) -> -1362692527.009721 MetaHookPre CallFunction(Files::__add_analyzers_for_mime_type, (FakNcS1Jfe01uljb3, text/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) -1362692527.009721 MetaHookPre CallFunction(Files::add_analyzers_for_mime_type, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -1362692527.009721 MetaHookPre CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -1362692527.009721 MetaHookPre CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -1362692527.009721 MetaHookPre CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009721 MetaHookPre CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.009721 MetaHookPre CallFunction(file_new, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -1362692527.009721 MetaHookPre CallFunction(file_over_new_connection, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009721 MetaHookPre CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -1362692527.009721 MetaHookPre CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009721 MetaHookPre CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -1362692527.009721 MetaHookPre CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.009721 MetaHookPre CallFunction(split_all, (HTTP, <...>/)) 1362692527.009721 MetaHookPre DrainEvents() -1362692527.009721 MetaHookPre QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -1362692527.009721 MetaHookPre QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009721 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) 1362692527.009721 MetaHookPre UpdateNetworkTime(1362692527.009721) 1362692527.009721 | HookUpdateNetworkTime 1362692527.009721 -1362692527.009721 | HookCallFunction Files::__add_analyzers_for_mime_type(FakNcS1Jfe01uljb3, text/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0]) -1362692527.009721 | HookCallFunction Files::add_analyzers_for_mime_type([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain) -1362692527.009721 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) -1362692527.009721 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) -1362692527.009721 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) -1362692527.009721 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) -1362692527.009721 | HookCallFunction file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) -1362692527.009721 | HookCallFunction file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) -1362692527.009721 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) -1362692527.009721 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) -1362692527.009721 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) -1362692527.009721 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80) -1362692527.009721 | HookCallFunction split_all(HTTP, <...>/) 1362692527.009721 | HookDrainEvents -1362692527.009721 | HookQueueEvent file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) -1362692527.009721 | HookQueueEvent file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) -1362692527.009721 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009765 MetaHookPost DrainEvents() -> 1362692527.009765 MetaHookPost UpdateNetworkTime(1362692527.009765) -> 1362692527.009765 MetaHookPre DrainEvents() 1362692527.009765 MetaHookPre UpdateNetworkTime(1362692527.009765) 1362692527.009765 | HookUpdateNetworkTime 1362692527.009765 1362692527.009765 | HookDrainEvents -1362692527.009775 MetaHookPost CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> -1362692527.009775 MetaHookPost CallFunction(HTTP::code_in_range, (200, 100, 199)) -> -1362692527.009775 MetaHookPost CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009775 MetaHookPost CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> -1362692527.009775 MetaHookPost CallFunction(Log::__write, (Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> -1362692527.009775 MetaHookPost CallFunction(Log::__write, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> -1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, (Files::LOG, , [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> -1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> -1362692527.009775 MetaHookPost CallFunction(Log::write, (Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> -1362692527.009775 MetaHookPost CallFunction(Log::write, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> -1362692527.009775 MetaHookPost CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.009775 MetaHookPost CallFunction(file_state_remove, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> -1362692527.009775 MetaHookPost CallFunction(fmt, (%s, Files::LOG)) -> -1362692527.009775 MetaHookPost CallFunction(fmt, (%s, HTTP::LOG)) -> -1362692527.009775 MetaHookPost CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> -1362692527.009775 MetaHookPost CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009775 MetaHookPost CallFunction(http_end_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> -1362692527.009775 MetaHookPost CallFunction(http_message_done, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -> -1362692527.009775 MetaHookPost CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> -1362692527.009775 MetaHookPost CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.009775 MetaHookPost CallFunction(split1, (Files::LOG, <...>/)) -> -1362692527.009775 MetaHookPost CallFunction(split1, (HTTP::LOG, <...>/)) -> -1362692527.009775 MetaHookPost CallFunction(split_n, (Files, <...>/, T, 4)) -> -1362692527.009775 MetaHookPost CallFunction(split_n, (HTTP, <...>/, T, 4)) -> -1362692527.009775 MetaHookPost CallFunction(to_lower, (Files)) -> -1362692527.009775 MetaHookPost CallFunction(to_lower, (HTTP)) -> +1362692527.009775 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280], (200, 100, 199)) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009775 MetaHookPost CallFunction(Log::__write, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::__write, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, , (Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, , (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(Log::write, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009775 MetaHookPost CallFunction(file_state_remove, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], (%s, Files::LOG)) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], (%s, HTTP::LOG)) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.009775 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -> +1362692527.009775 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.009775 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009775 MetaHookPost CallFunction(split1, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/)) -> +1362692527.009775 MetaHookPost CallFunction(split1, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692527.009775 MetaHookPost CallFunction(split_n, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/, T, 4)) -> +1362692527.009775 MetaHookPost CallFunction(split_n, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) -> +1362692527.009775 MetaHookPost CallFunction(to_lower, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]Files::LOG{[2] = LOG,[1] = Files}{[1] = Files}Files, (Files)) -> +1362692527.009775 MetaHookPost CallFunction(to_lower, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]HTTP::LOG{[2] = LOG,[1] = HTTP}{[1] = HTTP}HTTP, (HTTP)) -> 1362692527.009775 MetaHookPost DrainEvents() -> 1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> false 1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -> false 1362692527.009775 MetaHookPost UpdateNetworkTime(1362692527.009775) -> -1362692527.009775 MetaHookPre CallFunction(Files::set_info, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -1362692527.009775 MetaHookPre CallFunction(HTTP::code_in_range, (200, 100, 199)) -1362692527.009775 MetaHookPre CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009775 MetaHookPre CallFunction(HTTP::set_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -1362692527.009775 MetaHookPre CallFunction(Log::__write, (Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -1362692527.009775 MetaHookPre CallFunction(Log::__write, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, (Files::LOG, , [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -1362692527.009775 MetaHookPre CallFunction(Log::write, (Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -1362692527.009775 MetaHookPre CallFunction(Log::write, (HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -1362692527.009775 MetaHookPre CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.009775 MetaHookPre CallFunction(file_state_remove, ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -1362692527.009775 MetaHookPre CallFunction(fmt, (%s, Files::LOG)) -1362692527.009775 MetaHookPre CallFunction(fmt, (%s, HTTP::LOG)) -1362692527.009775 MetaHookPre CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -1362692527.009775 MetaHookPre CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009775 MetaHookPre CallFunction(http_end_entity, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -1362692527.009775 MetaHookPre CallFunction(http_message_done, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -1362692527.009775 MetaHookPre CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -1362692527.009775 MetaHookPre CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.009775 MetaHookPre CallFunction(split1, (Files::LOG, <...>/)) -1362692527.009775 MetaHookPre CallFunction(split1, (HTTP::LOG, <...>/)) -1362692527.009775 MetaHookPre CallFunction(split_n, (Files, <...>/, T, 4)) -1362692527.009775 MetaHookPre CallFunction(split_n, (HTTP, <...>/, T, 4)) -1362692527.009775 MetaHookPre CallFunction(to_lower, (Files)) -1362692527.009775 MetaHookPre CallFunction(to_lower, (HTTP)) +1362692527.009775 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009775 MetaHookPre CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280], (200, 100, 199)) +1362692527.009775 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009775 MetaHookPre CallFunction(Log::__write, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::__write, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, , (Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, , (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(Log::write, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009775 MetaHookPre CallFunction(file_state_remove, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009775 MetaHookPre CallFunction(fmt, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], (%s, Files::LOG)) +1362692527.009775 MetaHookPre CallFunction(fmt, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], (%s, HTTP::LOG)) +1362692527.009775 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.009775 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) +1362692527.009775 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.009775 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009775 MetaHookPre CallFunction(split1, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/)) +1362692527.009775 MetaHookPre CallFunction(split1, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692527.009775 MetaHookPre CallFunction(split_n, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/, T, 4)) +1362692527.009775 MetaHookPre CallFunction(split_n, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) +1362692527.009775 MetaHookPre CallFunction(to_lower, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]Files::LOG{[2] = LOG,[1] = Files}{[1] = Files}Files, (Files)) +1362692527.009775 MetaHookPre CallFunction(to_lower, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]HTTP::LOG{[2] = LOG,[1] = HTTP}{[1] = HTTP}HTTP, (HTTP)) 1362692527.009775 MetaHookPre DrainEvents() 1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) 1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) @@ -1745,11 +1699,11 @@ 1362692527.009775 | HookCallFunction HTTP::code_in_range(200, 100, 199) 1362692527.009775 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) 1362692527.009775 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) -1362692527.009775 | HookCallFunction Log::__write(Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::__write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) 1362692527.009775 | HookCallFunction Log::__write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) -1362692527.009775 | HookCallFunction Log::default_path_func(Files::LOG, , [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::default_path_func(Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) 1362692527.009775 | HookCallFunction Log::default_path_func(HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) -1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009721, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=53.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) 1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) 1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) 1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) @@ -1796,33 +1750,33 @@ 1362692527.080828 MetaHookPre UpdateNetworkTime(1362692527.080828) 1362692527.080828 | HookUpdateNetworkTime 1362692527.080828 1362692527.080828 | HookDrainEvents -1362692527.080972 MetaHookPost CallFunction(ChecksumOffloading::check, ()) -> -1362692527.080972 MetaHookPost CallFunction(Conn::conn_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) -> -1362692527.080972 MetaHookPost CallFunction(Conn::determine_service, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> -1362692527.080972 MetaHookPost CallFunction(Conn::set_conn, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692527.080972 MetaHookPost CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692527.080972 MetaHookPost CallFunction(Log::__write, (Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> -1362692527.080972 MetaHookPost CallFunction(Log::default_path_func, (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> -1362692527.080972 MetaHookPost CallFunction(Log::write, (Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> -1362692527.080972 MetaHookPost CallFunction(bro_done, ()) -> -1362692527.080972 MetaHookPost CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.080972 MetaHookPost CallFunction(connection_state_remove, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> -1362692527.080972 MetaHookPost CallFunction(filter_change_tracking, ()) -> -1362692527.080972 MetaHookPost CallFunction(fmt, (%s, Conn::LOG)) -> -1362692527.080972 MetaHookPost CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> -1362692527.080972 MetaHookPost CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> -1362692527.080972 MetaHookPost CallFunction(get_port_transport_proto, (80/tcp)) -> -1362692527.080972 MetaHookPost CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> -1362692527.080972 MetaHookPost CallFunction(is_tcp_port, (59856/tcp)) -> -1362692527.080972 MetaHookPost CallFunction(net_done, (1362692527.080972)) -> -1362692527.080972 MetaHookPost CallFunction(net_stats, ()) -> -1362692527.080972 MetaHookPost CallFunction(reading_traces, ()) -> -1362692527.080972 MetaHookPost CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> -1362692527.080972 MetaHookPost CallFunction(split1, (Conn::LOG, <...>/)) -> -1362692527.080972 MetaHookPost CallFunction(split_n, (Conn, <...>/, T, 4)) -> -1362692527.080972 MetaHookPost CallFunction(sub_bytes, (HTTP, 0, 1)) -> -1362692527.080972 MetaHookPost CallFunction(to_lower, (Conn)) -> -1362692527.080972 MetaHookPost CallFunction(to_lower, (HTTP)) -> +1362692527.080972 MetaHookPost CallFunction(ChecksumOffloading::check, , ()) -> +1362692527.080972 MetaHookPost CallFunction(Conn::conn_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) -> +1362692527.080972 MetaHookPost CallFunction(Conn::determine_service, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692527.080972 MetaHookPost CallFunction(Conn::set_conn, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(Log::__write, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(Log::default_path_func, , (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(bro_done, , ()) -> +1362692527.080972 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.080972 MetaHookPost CallFunction(connection_state_remove, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692527.080972 MetaHookPost CallFunction(filter_change_tracking, , ()) -> +1362692527.080972 MetaHookPost CallFunction(fmt, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}], (%s, Conn::LOG)) -> +1362692527.080972 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(get_port_transport_proto, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.080972 MetaHookPost CallFunction(is_tcp_port, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(net_done, , (1362692527.080972)) -> +1362692527.080972 MetaHookPost CallFunction(net_stats, frame , ()) -> +1362692527.080972 MetaHookPost CallFunction(reading_traces, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], ()) -> +1362692527.080972 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.080972 MetaHookPost CallFunction(split1, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692527.080972 MetaHookPost CallFunction(split_n, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) -> +1362692527.080972 MetaHookPost CallFunction(sub_bytes, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTP, (HTTP, 0, 1)) -> +1362692527.080972 MetaHookPost CallFunction(to_lower, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]Conn::LOG{[2] = LOG,[1] = Conn}{[1] = Conn}Conn, (Conn)) -> +1362692527.080972 MetaHookPost CallFunction(to_lower, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTPHTTP, (HTTP)) -> 1362692527.080972 MetaHookPost DrainEvents() -> 1362692527.080972 MetaHookPost QueueEvent(ChecksumOffloading::check()) -> false 1362692527.080972 MetaHookPost QueueEvent(bro_done()) -> false @@ -1830,33 +1784,33 @@ 1362692527.080972 MetaHookPost QueueEvent(filter_change_tracking()) -> false 1362692527.080972 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false 1362692527.080972 MetaHookPost UpdateNetworkTime(1362692527.080972) -> -1362692527.080972 MetaHookPre CallFunction(ChecksumOffloading::check, ()) -1362692527.080972 MetaHookPre CallFunction(Conn::conn_state, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) -1362692527.080972 MetaHookPre CallFunction(Conn::determine_service, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -1362692527.080972 MetaHookPre CallFunction(Conn::set_conn, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692527.080972 MetaHookPre CallFunction(HTTP::get_file_handle, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692527.080972 MetaHookPre CallFunction(Log::__write, (Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -1362692527.080972 MetaHookPre CallFunction(Log::default_path_func, (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -1362692527.080972 MetaHookPre CallFunction(Log::write, (Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -1362692527.080972 MetaHookPre CallFunction(bro_done, ()) -1362692527.080972 MetaHookPre CallFunction(cat, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.080972 MetaHookPre CallFunction(connection_state_remove, ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -1362692527.080972 MetaHookPre CallFunction(filter_change_tracking, ()) -1362692527.080972 MetaHookPre CallFunction(fmt, (%s, Conn::LOG)) -1362692527.080972 MetaHookPre CallFunction(fmt, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -1362692527.080972 MetaHookPre CallFunction(get_file_handle, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -1362692527.080972 MetaHookPre CallFunction(get_port_transport_proto, (80/tcp)) -1362692527.080972 MetaHookPre CallFunction(id_string, ([orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -1362692527.080972 MetaHookPre CallFunction(is_tcp_port, (59856/tcp)) -1362692527.080972 MetaHookPre CallFunction(net_done, (1362692527.080972)) -1362692527.080972 MetaHookPre CallFunction(net_stats, ()) -1362692527.080972 MetaHookPre CallFunction(reading_traces, ()) -1362692527.080972 MetaHookPre CallFunction(set_file_handle, (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -1362692527.080972 MetaHookPre CallFunction(split1, (Conn::LOG, <...>/)) -1362692527.080972 MetaHookPre CallFunction(split_n, (Conn, <...>/, T, 4)) -1362692527.080972 MetaHookPre CallFunction(sub_bytes, (HTTP, 0, 1)) -1362692527.080972 MetaHookPre CallFunction(to_lower, (Conn)) -1362692527.080972 MetaHookPre CallFunction(to_lower, (HTTP)) +1362692527.080972 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692527.080972 MetaHookPre CallFunction(Conn::conn_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) +1362692527.080972 MetaHookPre CallFunction(Conn::determine_service, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692527.080972 MetaHookPre CallFunction(Conn::set_conn, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(Log::__write, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(Log::default_path_func, , (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(bro_done, , ()) +1362692527.080972 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.080972 MetaHookPre CallFunction(connection_state_remove, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692527.080972 MetaHookPre CallFunction(filter_change_tracking, , ()) +1362692527.080972 MetaHookPre CallFunction(fmt, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}], (%s, Conn::LOG)) +1362692527.080972 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(get_port_transport_proto, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.080972 MetaHookPre CallFunction(is_tcp_port, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(net_done, , (1362692527.080972)) +1362692527.080972 MetaHookPre CallFunction(net_stats, frame , ()) +1362692527.080972 MetaHookPre CallFunction(reading_traces, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], ()) +1362692527.080972 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.080972 MetaHookPre CallFunction(split1, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692527.080972 MetaHookPre CallFunction(split_n, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) +1362692527.080972 MetaHookPre CallFunction(sub_bytes, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTP, (HTTP, 0, 1)) +1362692527.080972 MetaHookPre CallFunction(to_lower, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]Conn::LOG{[2] = LOG,[1] = Conn}{[1] = Conn}Conn, (Conn)) +1362692527.080972 MetaHookPre CallFunction(to_lower, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTPHTTP, (HTTP)) 1362692527.080972 MetaHookPre DrainEvents() 1362692527.080972 MetaHookPre QueueEvent(ChecksumOffloading::check()) 1362692527.080972 MetaHookPre QueueEvent(bro_done()) diff --git a/testing/btest/plugins/api-version-mismatch.sh b/testing/btest/plugins/api-version-mismatch.sh index f8d88b4fc4..4bd0f1078f 100644 --- a/testing/btest/plugins/api-version-mismatch.sh +++ b/testing/btest/plugins/api-version-mismatch.sh @@ -2,6 +2,7 @@ # @TEST-EXEC: bash %INPUT # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC-FAIL: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output 2>&1 +# @TEST-EXEC: cat output | sed 's/\/[^ ]*/XXX/g' > output.2 && mv -f output.2 output # @TEST-EXEC: btest-diff output ( echo '#define BRO_PLUGIN_API_VERSION 42'; cat src/Plugin.cc; ) >src/Plugin.cc.tmp && mv src/Plugin.cc.tmp src/Plugin.cc diff --git a/testing/btest/plugins/hooks-plugin/src/Plugin.cc b/testing/btest/plugins/hooks-plugin/src/Plugin.cc index e5507f5a0e..1361f8eeca 100644 --- a/testing/btest/plugins/hooks-plugin/src/Plugin.cc +++ b/testing/btest/plugins/hooks-plugin/src/Plugin.cc @@ -5,6 +5,7 @@ #include namespace plugin { namespace Demo_Hooks { Plugin plugin; } } +using plugin::ValWrapper; using namespace plugin::Demo_Hooks; @@ -48,7 +49,7 @@ int Plugin::HookLoadFile(const std::string& file, const std::string& ext) return -1; } -Val* Plugin::HookCallFunction(const Func* func, Frame* frame, val_list* args) +ValWrapper* Plugin::HookCallFunction(const Func* func, Frame* frame, val_list* args) { ODesc d; d.SetShort(); diff --git a/testing/btest/plugins/hooks-plugin/src/Plugin.h b/testing/btest/plugins/hooks-plugin/src/Plugin.h index 940e427621..8cbf1d0e5b 100644 --- a/testing/btest/plugins/hooks-plugin/src/Plugin.h +++ b/testing/btest/plugins/hooks-plugin/src/Plugin.h @@ -11,7 +11,7 @@ class Plugin : public ::plugin::Plugin { protected: virtual int HookLoadFile(const std::string& file, const std::string& ext); - virtual Val* HookCallFunction(const Func* func, Frame* frame, val_list* args); + virtual plugin::ValWrapper* HookCallFunction(const Func* func, Frame* frame, val_list* args); virtual bool HookQueueEvent(Event* event); virtual void HookDrainEvents(); virtual void HookUpdateNetworkTime(double network_time); From 619062fb5535e9c454628df633eb4400587c13f2 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Thu, 2 Oct 2014 20:25:47 -0400 Subject: [PATCH 010/256] Fixing logic errors in HandlePluginResult --- src/Func.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index 547af2c6ce..409bdcae25 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -289,11 +289,14 @@ ValWrapper* Func::HandlePluginResult(ValWrapper* plugin_result, val_list* args, if ( (! yt) || yt->Tag() == TYPE_VOID ) { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned non-void result for void method %s", this->Name()); - reporter->InternalError(sbuf); + if(plugin_result && plugin_result->value) + { + char sbuf[1024]; + snprintf(sbuf, 1024, "plugin returned non-void result for void method %s", this->Name()); + reporter->InternalError(sbuf); + } } - else if ( plugin_result->value->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) + else if ( plugin_result->value && plugin_result->value->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) { char sbuf[1024]; snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->value->Type()->Tag(), yt->Tag(), this->Name()); From be5cb549a9b1d832b0b462fe460dfc24697227c7 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Tue, 7 Oct 2014 22:11:41 -0400 Subject: [PATCH 011/256] Re-updating plugin.hooks test to include new argument output (after merge). --- testing/btest/Baseline/plugins.hooks/output | 1912 +++++++++++++++---- 1 file changed, 1580 insertions(+), 332 deletions(-) diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index c6713eb6a7..4724e9fb9f 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -155,7 +155,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG, [columns=, ev=Weird::log_weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG, [columns=, ev=X509::log_x509])) -> -0.000000 MetaHookPost CallFunction(Log::__write, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Cluster::LOG[columns=, ev=], (Cluster::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Communication::LOG[columns=, ev=], (Communication::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG)) -> @@ -246,8 +246,8 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Software::LOG, [columns=, ev=Software::log_software])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Syslog::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::default_path_func, , (PacketFilter::LOG, , [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::write, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::default_path_func, , (PacketFilter::LOG, , [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, frame , ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::build, frame [ts=, node=, filter=, init=F, success=T], ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, frame [func=]ip or not ip, (ip or not ip, and, )) -> @@ -267,340 +267,1588 @@ 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, frame , (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, frame , ()) -> 0.000000 MetaHookPost CallFunction(bro_init, , ()) -> -0.000000 MetaHookPost CallFunction(cat, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (Packe, t, _, Filter)) -> -0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412291343.3228235.0 usecs[ts=0.0, node=bro, filter=, init=F, success=T], ()) -> -0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(cat, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (Packe, t, _, Filter)) -> +0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412734245.30831964.0 usecs[ts=0.0, node=bro, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip1412734245.308319[ts=, node=, filter=, init=F, success=T], ()) -> 0.000000 MetaHookPost CallFunction(current_time, frame ip or not ip[ts=, node=, filter=, init=F, success=T], ()) -> 0.000000 MetaHookPost CallFunction(filter_change_tracking, , ()) -> -0.000000 MetaHookPost CallFunction(fmt, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (%s, PacketFilter::LOG)) -> +0.000000 MetaHookPost CallFunction(fmt, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (%s, PacketFilter::LOG)) -> 0.000000 MetaHookPost CallFunction(getenv, , (CLUSTER_NODE)) -> -0.000000 MetaHookPost CallFunction(install_pcap_filter, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::DefaultPcapFilter)) -> -0.000000 MetaHookPost CallFunction(network_time, frame ip or not ip1412291343.3228235.0 usecs[ts=, node=, filter=, init=F, success=T], ()) -> -0.000000 MetaHookPost CallFunction(precompile_pcap_filter, frame ip or not ip1412291343.32282[ts=, node=, filter=, init=F, success=T], (PacketFilter::DefaultPcapFilter, ip or not ip)) -> -0.000000 MetaHookPost CallFunction(reading_live_traffic, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) -> +0.000000 MetaHookPost CallFunction(install_pcap_filter, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::DefaultPcapFilter)) -> +0.000000 MetaHookPost CallFunction(network_time, frame ip or not ip1412734245.30831964.0 usecs[ts=, node=, filter=, init=F, success=T], ()) -> +0.000000 MetaHookPost CallFunction(precompile_pcap_filter, frame ip or not ip1412734245.308319[ts=, node=, filter=, init=F, success=T], (PacketFilter::DefaultPcapFilter, ip or not ip)) -> +0.000000 MetaHookPost CallFunction(reading_live_traffic, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], ()) -> 0.000000 MetaHookPost CallFunction(reading_traces, frame , ()) -> 0.000000 MetaHookPost CallFunction(reading_traces, frame , ()) -> -0.000000 MetaHookPost CallFunction(reading_traces, frame ip or not ip1412291343.3228235.0 usecs[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T], ()) -> +0.000000 MetaHookPost CallFunction(reading_traces, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], ()) -> 0.000000 MetaHookPost CallFunction(set_to_regex, frame , ({}, (^\.?|\.)(~~)$)) -> -0.000000 MetaHookPost CallFunction(split1, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG, (PacketFilter::LOG, <...>/)) -> -0.000000 MetaHookPost CallFunction(split_n, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}, (PacketFilter, <...>/, T, 4)) -> +0.000000 MetaHookPost CallFunction(split1, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG, (PacketFilter::LOG, <...>/)) -> +0.000000 MetaHookPost CallFunction(split_n, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}, (PacketFilter, <...>/, T, 4)) -> 0.000000 MetaHookPost CallFunction(string_to_pattern, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)()$, F)) -> 0.000000 MetaHookPost CallFunction(sub, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)(~~)$, <...>/, )) -> -0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 1, 1)) -> -0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 2, 7)) -> -0.000000 MetaHookPost CallFunction(to_lower, frame PacketFilter::LOG[ts=1412291343.322872, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packet_Filter, (Packet_Filter)) -> -======= -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_BACKDOOR)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_INTERCONN)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_STEPPINGSTONE)) -> -0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, (Analyzer::ANALYZER_TCPSTATS)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 67/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DHCP, 68/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNP3, 20000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 137/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 53/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5353/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_DNS, 5355/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 21/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_FTP, 2811/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2123/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_GTPV1, 2152/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 3128/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 631/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 80/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8000/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 81/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_HTTP, 8888/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6666/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6667/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6668/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_IRC, 6669/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_MODBUS, 502/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_RADIUS, 1812/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 25/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SMTP, 587/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 161/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SNMP, 162/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SOCKS, 1080/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSH, 22/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 443/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 5223/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 563/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 585/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 614/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 636/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 989/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 990/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 992/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 993/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SSL, 995/tcp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_SYSLOG, 514/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, (Analyzer::ANALYZER_TEREDO, 3544/udp)) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_AYIYA, {5072/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DHCP, {67<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNP3, {20000/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_DNS, {5355<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_MODBUS, {502/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_RADIUS, {1812/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SNMP, {162<...>/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SOCKS, {1080/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSH, {22/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_SYSLOG, {514/udp})) -> -0.000000 MetaHookPost CallFunction(Analyzer::register_for_ports, (Analyzer::ANALYZER_TEREDO, {3544/udp})) -> -0.000000 MetaHookPost CallFunction(Cluster::is_enabled, ()) -> -0.000000 MetaHookPost CallFunction(Files::register_analyzer_add_callback, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) -> -0.000000 MetaHookPost CallFunction(Files::register_protocol, (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Cluster::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Communication::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (DPD::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (PacketFilter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Reporter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Syslog::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Tunnel::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> -0.000000 MetaHookPost CallFunction(Log::__create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> -0.000000 MetaHookPost CallFunction(Log::__write, (PacketFilter::LOG, [ts=1412721129.083128, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Cluster::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Communication::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Conn::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DHCP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DNP3::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DNS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (DPD::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (FTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Files::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (HTTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (IRC::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Intel::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Modbus::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Notice::ALARM_LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Notice::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (PacketFilter::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (RADIUS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Reporter::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SMTP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SNMP::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SOCKS::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SSH::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (SSL::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Signatures::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Software::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Syslog::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Tunnel::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Unified2::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Weird::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_default_filter, (X509::LOG)) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::add_filter, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Cluster::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Communication::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Conn::LOG, [columns=, ev=Conn::log_conn])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DNS::LOG, [columns=, ev=DNS::log_dns])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (DPD::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (FTP::LOG, [columns=, ev=FTP::log_ftp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Files::LOG, [columns=, ev=Files::log_files])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (HTTP::LOG, [columns=, ev=HTTP::log_http])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (IRC::LOG, [columns=, ev=IRC::irc_log])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Intel::LOG, [columns=, ev=Intel::log_intel])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Notice::ALARM_LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Notice::LOG, [columns=, ev=Notice::log_notice])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (PacketFilter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Reporter::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SSH::LOG, [columns=, ev=SSH::log_ssh])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (SSL::LOG, [columns=, ev=SSL::log_ssl])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Signatures::LOG, [columns=, ev=Signatures::log_signature])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Software::LOG, [columns=, ev=Software::log_software])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Syslog::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Tunnel::LOG, [columns=, ev=])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> -0.000000 MetaHookPost CallFunction(Log::create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> -0.000000 MetaHookPost CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1412721129.083128, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::write, (PacketFilter::LOG, [ts=1412721129.083128, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Notice::want_pp, ()) -> -0.000000 MetaHookPost CallFunction(PacketFilter::build, ()) -> -0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, (ip or not ip, and, )) -> -0.000000 MetaHookPost CallFunction(PacketFilter::install, ()) -> -0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::STD_DEV, SumStats::VARIANCE)) -> -0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, (SumStats::VARIANCE, SumStats::AVERAGE)) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, ()) -> -0.000000 MetaHookPost CallFunction(bro_init, ()) -> -0.000000 MetaHookPost CallFunction(cat, (Packe, t, _, Filter)) -> -0.000000 MetaHookPost CallFunction(current_time, ()) -> -0.000000 MetaHookPost CallFunction(filter_change_tracking, ()) -> -0.000000 MetaHookPost CallFunction(fmt, (%s, PacketFilter::LOG)) -> -0.000000 MetaHookPost CallFunction(getenv, (CLUSTER_NODE)) -> -0.000000 MetaHookPost CallFunction(install_pcap_filter, (PacketFilter::DefaultPcapFilter)) -> -0.000000 MetaHookPost CallFunction(network_time, ()) -> -0.000000 MetaHookPost CallFunction(precompile_pcap_filter, (PacketFilter::DefaultPcapFilter, ip or not ip)) -> -0.000000 MetaHookPost CallFunction(reading_live_traffic, ()) -> -0.000000 MetaHookPost CallFunction(reading_traces, ()) -> -0.000000 MetaHookPost CallFunction(set_to_regex, ({}, (^\.?|\.)(~~)$)) -> -0.000000 MetaHookPost CallFunction(split1, (PacketFilter::LOG, <...>/)) -> -0.000000 MetaHookPost CallFunction(split_n, (PacketFilter, <...>/, T, 4)) -> -0.000000 MetaHookPost CallFunction(string_to_pattern, ((^\.?|\.)()$, F)) -> -0.000000 MetaHookPost CallFunction(sub, ((^\.?|\.)(~~)$, <...>/, )) -> -0.000000 MetaHookPost CallFunction(sub_bytes, (tFilter, 1, 1)) -> -0.000000 MetaHookPost CallFunction(sub_bytes, (tFilter, 2, 7)) -> -0.000000 MetaHookPost CallFunction(to_lower, (Packet_Filter)) -> +0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 1, 1)) -> +0.000000 MetaHookPost CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 2, 7)) -> +0.000000 MetaHookPost CallFunction(to_lower, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packet_Filter, (Packet_Filter)) -> +0.000000 MetaHookPost DrainEvents() -> +0.000000 MetaHookPost LoadFile(../main) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_ARP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_AYIYA.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_AsciiReader.ascii.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_AsciiWriter.ascii.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_BackDoor.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_BenchmarkReader.benchmark.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_BinaryReader.binary.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_BitTorrent.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_ConnSize.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_DCE_RPC.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_DHCP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_DNP3.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_DNS.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_FTP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_FTP.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_File.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_FileExtract.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_FileExtract.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_FileHash.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Finger.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_GTPv1.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Gnutella.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_HTTP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_HTTP.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_ICMP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_IRC.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Ident.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_InterConn.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Login.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Login.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_MIME.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Modbus.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NCP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NTP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NetBIOS.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NetBIOS.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NetFlow.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_NoneWriter.none.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_PIA.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_POP3.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_RADIUS.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_RPC.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_RawReader.raw.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMB.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMTP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMTP.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SNMP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SNMP.types.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SOCKS.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SQLiteReader.sqlite.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SQLiteWriter.sqlite.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SSH.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SSL.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SteppingStone.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Syslog.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_TCP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_TCP.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Teredo.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_UDP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Unified2.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_Unified2.types.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_X509.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_X509.functions.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_X509.types.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_ZIP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./addrs) -> -1 +0.000000 MetaHookPost LoadFile(./analyzer.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./average) -> -1 +0.000000 MetaHookPost LoadFile(./bloom-filter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./bro.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./broxygen.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./cardinality-counter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./const.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./consts) -> -1 +0.000000 MetaHookPost LoadFile(./consts.bro) -> -1 +0.000000 MetaHookPost LoadFile(./contents) -> -1 +0.000000 MetaHookPost LoadFile(./dcc-send) -> -1 +0.000000 MetaHookPost LoadFile(./entities) -> -1 +0.000000 MetaHookPost LoadFile(./event.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./exec) -> -1 +0.000000 MetaHookPost LoadFile(./file_analysis.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./files) -> -1 +0.000000 MetaHookPost LoadFile(./gridftp) -> -1 +0.000000 MetaHookPost LoadFile(./hll_unique) -> -1 +0.000000 MetaHookPost LoadFile(./hooks.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./inactivity) -> -1 +0.000000 MetaHookPost LoadFile(./info) -> -1 +0.000000 MetaHookPost LoadFile(./init.bro) -> -1 +0.000000 MetaHookPost LoadFile(./input) -> -1 +0.000000 MetaHookPost LoadFile(./input.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./last) -> -1 +0.000000 MetaHookPost LoadFile(./logging.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./magic) -> -1 +0.000000 MetaHookPost LoadFile(./main) -> -1 +0.000000 MetaHookPost LoadFile(./main.bro) -> -1 +0.000000 MetaHookPost LoadFile(./max) -> -1 +0.000000 MetaHookPost LoadFile(./min) -> -1 +0.000000 MetaHookPost LoadFile(./mozilla-ca-list) -> -1 +0.000000 MetaHookPost LoadFile(./netstats) -> -1 +0.000000 MetaHookPost LoadFile(./non-cluster) -> -1 +0.000000 MetaHookPost LoadFile(./patterns) -> -1 +0.000000 MetaHookPost LoadFile(./pcap.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./plugins) -> -1 +0.000000 MetaHookPost LoadFile(./polling) -> -1 +0.000000 MetaHookPost LoadFile(./postprocessors) -> -1 +0.000000 MetaHookPost LoadFile(./reporter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./sample) -> -1 +0.000000 MetaHookPost LoadFile(./scp) -> -1 +0.000000 MetaHookPost LoadFile(./sftp) -> -1 +0.000000 MetaHookPost LoadFile(./site) -> -1 +0.000000 MetaHookPost LoadFile(./std-dev) -> -1 +0.000000 MetaHookPost LoadFile(./strings.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./sum) -> -1 +0.000000 MetaHookPost LoadFile(./top-k.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./topk) -> -1 +0.000000 MetaHookPost LoadFile(./types.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./unique) -> -1 +0.000000 MetaHookPost LoadFile(./utils) -> -1 +0.000000 MetaHookPost LoadFile(./utils-commands) -> -1 +0.000000 MetaHookPost LoadFile(./utils.bro) -> -1 +0.000000 MetaHookPost LoadFile(./variance) -> -1 +0.000000 MetaHookPost LoadFile(./weird) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/add-geodata) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/ascii) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/benchmark) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/binary) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/drop) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/email_admin) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/hostnames) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/none) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/page) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/pp-alarms) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/raw) -> -1 +0.000000 MetaHookPost LoadFile(.<...>/sqlite) -> -1 +0.000000 MetaHookPost LoadFile(<...>/__load__.bro) -> -1 +0.000000 MetaHookPost LoadFile(<...>/hooks.bro) -> -1 +0.000000 MetaHookPost LoadFile(base/bif) -> -1 +0.000000 MetaHookPost LoadFile(base/init-default.bro) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/Bro_SNMP.types.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/active-http) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/addrs) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/analyzer) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/analyzer.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/bro.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/cluster) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/communication) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/conn) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/conn-ids) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/const.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/control) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/dhcp) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/dir) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/directions-and-hosts) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/dnp3) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/dns) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/dpd) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/event.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/exec) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/extract) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/file_analysis.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/files) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/find-checksum-offloading) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/find-filtered-trace) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/ftp) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/hash) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/http) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/input) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/input.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/intel) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/irc) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/logging) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/logging.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/main) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/modbus) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/notice) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/numbers) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/packet-filter) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/paths) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/patterns) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/plugins) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/pop3) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/queue) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/radius) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/reporter) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/reporter.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/signatures) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/site) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/smtp) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/snmp) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/socks) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/software) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/ssh) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/ssl) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/strings) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/strings.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/sumstats) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/syslog) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/thresholds) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/time) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/tunnels) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/types.bif) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/unified2) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/urls) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/utils) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/x509) -> -1 +0.000000 MetaHookPost QueueEvent(bro_init()) -> false +0.000000 MetaHookPost QueueEvent(filter_change_tracking()) -> false +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) +0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_AYIYA5072<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP67<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DHCP68<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNP320000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS137<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5353<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS5355<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_DNS53<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP21<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_FTP2811<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12123<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_GTPV12152<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP3128<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP631<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP80<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP81<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_HTTP8888<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6666<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6667<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6668<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_IRC6669<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_MODBUS502<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_RADIUS1812<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP25<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SMTP587<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP161<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SNMP162<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SOCKS1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSH22<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL443<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL5223<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL563<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL585<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL614<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL636<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL989<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL990<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL992<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL993<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SSL995<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_SYSLOG514<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, frame Analyzer::ANALYZER_TEREDO3544<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_BACKDOOR, (Analyzer::ANALYZER_BACKDOOR)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_INTERCONN, (Analyzer::ANALYZER_INTERCONN)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_STEPPINGSTONE)) +0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, frame Analyzer::ANALYZER_TCPSTATS, (Analyzer::ANALYZER_TCPSTATS)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_AYIYA{5072<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DHCP{67<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNP3{20000<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_DNS{5355<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_FTP{2811<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_GTPV1{2152<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_HTTP{631<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_IRC{6669<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_MODBUS{502<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_RADIUS{1812<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SMTP{25<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SNMP{162<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SOCKS{1080<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSH{22<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SSL{5223<...>/tcp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_SYSLOG{514<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, frame Analyzer::ANALYZER_TEREDO{3544<...>/udp)) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_AYIYA, {5072/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DHCP, {67<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNP3, {20000/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_DNS, {5355<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_FTP, {2811<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_GTPV1, {2152<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_HTTP, {631<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_IRC, {6669<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_MODBUS, {502/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SMTP, {25<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SNMP, {162<...>/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SOCKS, {1080/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSH, {22/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_SSL, {5223<...>/tcp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame , (Analyzer::ANALYZER_TEREDO, {3544/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_RADIUS, {1812/udp})) +0.000000 MetaHookPre CallFunction(Analyzer::register_for_ports, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_SYSLOG, {514/udp})) +0.000000 MetaHookPre CallFunction(Cluster::is_enabled, , ()) +0.000000 MetaHookPre CallFunction(Cluster::is_enabled, frame , ()) +0.000000 MetaHookPre CallFunction(Files::register_analyzer_add_callback, frame , (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)})) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame , (Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) +0.000000 MetaHookPre CallFunction(Files::register_protocol, frame Analyzer::ANALYZER_STEPPINGSTONE, (Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Cluster::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Communication::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Conn::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DHCP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DNP3::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DNS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame DPD::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame FTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Files::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame HTTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame IRC::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Intel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Modbus::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Notice::ALARM_LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Notice::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame PacketFilter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame RADIUS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Reporter::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SMTP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SNMP::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SOCKS::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SSH::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame SSL::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Signatures::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Software::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Syslog::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Tunnel::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Unified2::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame Weird::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, frame X509::LOG[name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Cluster::LOG[columns=, ev=], (Cluster::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Communication::LOG[columns=, ev=], (Communication::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG, [columns=, ev=Conn::log_conn])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG, [columns=, ev=DNS::log_dns])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame DPD::LOG[columns=, ev=], (DPD::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG, [columns=, ev=FTP::log_ftp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG, [columns=, ev=Files::log_files])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG, [columns=, ev=HTTP::log_http])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG, [columns=, ev=IRC::irc_log])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG, [columns=, ev=Intel::log_intel])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG, [columns=, ev=Notice::log_notice])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Reporter::LOG[columns=, ev=], (Reporter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG, [columns=, ev=SSH::log_ssh])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG, [columns=, ev=SSL::log_ssl])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG, [columns=, ev=Signatures::log_signature])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG, [columns=, ev=Software::log_software])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Syslog::LOG[columns=, ev=], (Syslog::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG, [columns=, ev=Weird::log_weird])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG, [columns=, ev=X509::log_x509])) +0.000000 MetaHookPre CallFunction(Log::__write, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Cluster::LOG[columns=, ev=], (Cluster::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Communication::LOG[columns=, ev=], (Communication::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Conn::LOG[columns=, ev=Conn::log_conn], (Conn::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DHCP::LOG[columns=, ev=DHCP::log_dhcp], (DHCP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DNP3::LOG[columns=, ev=DNP3::log_dnp3], (DNP3::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DNS::LOG[columns=, ev=DNS::log_dns], (DNS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame DPD::LOG[columns=, ev=], (DPD::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame FTP::LOG[columns=, ev=FTP::log_ftp], (FTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Files::LOG[columns=, ev=Files::log_files], (Files::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame HTTP::LOG[columns=, ev=HTTP::log_http], (HTTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame IRC::LOG[columns=, ev=IRC::irc_log], (IRC::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Intel::LOG[columns=, ev=Intel::log_intel], (Intel::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Modbus::LOG[columns=, ev=Modbus::log_modbus], (Modbus::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Notice::ALARM_LOG[columns=, ev=], (Notice::ALARM_LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Notice::LOG[columns=, ev=Notice::log_notice], (Notice::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame PacketFilter::LOG[columns=, ev=], (PacketFilter::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame RADIUS::LOG[columns=, ev=RADIUS::log_radius], (RADIUS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Reporter::LOG[columns=, ev=], (Reporter::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SMTP::LOG[columns=, ev=SMTP::log_smtp], (SMTP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SNMP::LOG[columns=, ev=SNMP::log_snmp], (SNMP::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SOCKS::LOG[columns=, ev=SOCKS::log_socks], (SOCKS::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SSH::LOG[columns=, ev=SSH::log_ssh], (SSH::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame SSL::LOG[columns=, ev=SSL::log_ssl], (SSL::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Signatures::LOG[columns=, ev=Signatures::log_signature], (Signatures::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Software::LOG[columns=, ev=Software::log_software], (Software::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Syslog::LOG[columns=, ev=], (Syslog::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Tunnel::LOG[columns=, ev=], (Tunnel::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Unified2::LOG[columns=, ev=Unified2::log_unified2], (Unified2::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame Weird::LOG[columns=, ev=Weird::log_weird], (Weird::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, frame X509::LOG[columns=, ev=X509::log_x509], (X509::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Cluster::LOG, (Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Communication::LOG, (Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Conn::LOG, (Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DHCP::LOG, (DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DNP3::LOG, (DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DNS::LOG, (DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame DPD::LOG, (DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame FTP::LOG, (FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Files::LOG, (Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame HTTP::LOG, (HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame IRC::LOG, (IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Intel::LOG, (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Modbus::LOG, (Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Notice::ALARM_LOG, (Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Notice::LOG, (Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame PacketFilter::LOG, (PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame RADIUS::LOG, (RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Reporter::LOG, (Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SMTP::LOG, (SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SNMP::LOG, (SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SOCKS::LOG, (SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SSH::LOG, (SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame SSL::LOG, (SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Signatures::LOG, (Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Software::LOG, (Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Syslog::LOG, (Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Tunnel::LOG, (Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Unified2::LOG, (Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame Weird::LOG, (Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::add_filter, frame X509::LOG, (X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Cluster::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Communication::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DHCP::LOG, [columns=, ev=DHCP::log_dhcp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DNP3::LOG, [columns=, ev=DNP3::log_dnp3])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DNS::LOG, [columns=, ev=DNS::log_dns])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (DPD::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (FTP::LOG, [columns=, ev=FTP::log_ftp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Files::LOG, [columns=, ev=Files::log_files])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (HTTP::LOG, [columns=, ev=HTTP::log_http])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (IRC::LOG, [columns=, ev=IRC::irc_log])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Intel::LOG, [columns=, ev=Intel::log_intel])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Modbus::LOG, [columns=, ev=Modbus::log_modbus])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Notice::ALARM_LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Notice::LOG, [columns=, ev=Notice::log_notice])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (PacketFilter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Reporter::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SMTP::LOG, [columns=, ev=SMTP::log_smtp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SNMP::LOG, [columns=, ev=SNMP::log_snmp])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SOCKS::LOG, [columns=, ev=SOCKS::log_socks])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SSH::LOG, [columns=, ev=SSH::log_ssh])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (SSL::LOG, [columns=, ev=SSL::log_ssl])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Signatures::LOG, [columns=, ev=Signatures::log_signature])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Tunnel::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Unified2::LOG, [columns=, ev=Unified2::log_unified2])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (Weird::LOG, [columns=, ev=Weird::log_weird])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame , (X509::LOG, [columns=, ev=X509::log_x509])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Conn::LOG, [columns=, ev=Conn::log_conn])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (RADIUS::LOG, [columns=, ev=RADIUS::log_radius])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Software::LOG, [columns=, ev=Software::log_software])) +0.000000 MetaHookPre CallFunction(Log::create_stream, frame Analyzer::ANALYZER_STEPPINGSTONE, (Syslog::LOG, [columns=, ev=])) +0.000000 MetaHookPre CallFunction(Log::default_path_func, , (PacketFilter::LOG, , [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Notice::want_pp, frame , ()) +0.000000 MetaHookPre CallFunction(PacketFilter::build, frame [ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, frame [func=]ip or not ip, (ip or not ip, and, )) +0.000000 MetaHookPre CallFunction(PacketFilter::install, frame , ()) +0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::STD_DEV, SumStats::VARIANCE)) +0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, frame , (SumStats::VARIANCE, SumStats::AVERAGE)) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, frame , (SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, frame , ()) +0.000000 MetaHookPre CallFunction(bro_init, , ()) +0.000000 MetaHookPre CallFunction(cat, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (Packe, t, _, Filter)) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip1412734245.30831964.0 usecs[ts=0.0, node=bro, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip1412734245.308319[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(current_time, frame ip or not ip[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(filter_change_tracking, , ()) +0.000000 MetaHookPre CallFunction(fmt, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (%s, PacketFilter::LOG)) +0.000000 MetaHookPre CallFunction(getenv, , (CLUSTER_NODE)) +0.000000 MetaHookPre CallFunction(install_pcap_filter, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], (PacketFilter::DefaultPcapFilter)) +0.000000 MetaHookPre CallFunction(network_time, frame ip or not ip1412734245.30831964.0 usecs[ts=, node=, filter=, init=F, success=T], ()) +0.000000 MetaHookPre CallFunction(precompile_pcap_filter, frame ip or not ip1412734245.308319[ts=, node=, filter=, init=F, success=T], (PacketFilter::DefaultPcapFilter, ip or not ip)) +0.000000 MetaHookPre CallFunction(reading_live_traffic, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame , ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame , ()) +0.000000 MetaHookPre CallFunction(reading_traces, frame ip or not ip1412734245.30831964.0 usecs[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T], ()) +0.000000 MetaHookPre CallFunction(set_to_regex, frame , ({}, (^\.?|\.)(~~)$)) +0.000000 MetaHookPre CallFunction(split1, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG, (PacketFilter::LOG, <...>/)) +0.000000 MetaHookPre CallFunction(split_n, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}, (PacketFilter, <...>/, T, 4)) +0.000000 MetaHookPre CallFunction(string_to_pattern, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)()$, F)) +0.000000 MetaHookPre CallFunction(sub, frame {}(^\.?|\.)(~~)$0, ((^\.?|\.)(~~)$, <...>/, )) +0.000000 MetaHookPre CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 1, 1)) +0.000000 MetaHookPre CallFunction(sub_bytes, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packe, (tFilter, 2, 7)) +0.000000 MetaHookPre CallFunction(to_lower, frame PacketFilter::LOG[ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]PacketFilter::LOG{[2] = LOG,[1] = PacketFilter}{[2] = tFilter,[1] = Packe,[3] = }Packet_Filter, (Packet_Filter)) +0.000000 MetaHookPre DrainEvents() +0.000000 MetaHookPre LoadFile(../main) +0.000000 MetaHookPre LoadFile(./Bro_ARP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_AYIYA.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_AsciiReader.ascii.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_AsciiWriter.ascii.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_BackDoor.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_BenchmarkReader.benchmark.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_BinaryReader.binary.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_BitTorrent.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_ConnSize.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_DCE_RPC.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_DHCP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_DNP3.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_DNS.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_FTP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_FTP.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_File.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_FileExtract.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_FileExtract.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_FileHash.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Finger.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_GTPv1.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Gnutella.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_HTTP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_HTTP.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_ICMP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_IRC.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Ident.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_InterConn.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Login.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Login.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_MIME.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Modbus.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NCP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NTP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NetBIOS.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NetBIOS.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NetFlow.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_NoneWriter.none.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_PIA.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_POP3.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_RADIUS.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_RPC.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_RawReader.raw.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMB.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMTP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMTP.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SNMP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SNMP.types.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SOCKS.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SQLiteReader.sqlite.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SQLiteWriter.sqlite.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SSH.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SSL.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SteppingStone.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Syslog.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_TCP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_TCP.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Teredo.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_UDP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Unified2.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_Unified2.types.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_X509.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_X509.functions.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_X509.types.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_ZIP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./addrs) +0.000000 MetaHookPre LoadFile(./analyzer.bif.bro) +0.000000 MetaHookPre LoadFile(./average) +0.000000 MetaHookPre LoadFile(./bloom-filter.bif.bro) +0.000000 MetaHookPre LoadFile(./bro.bif.bro) +0.000000 MetaHookPre LoadFile(./broxygen.bif.bro) +0.000000 MetaHookPre LoadFile(./cardinality-counter.bif.bro) +0.000000 MetaHookPre LoadFile(./const.bif.bro) +0.000000 MetaHookPre LoadFile(./consts) +0.000000 MetaHookPre LoadFile(./consts.bro) +0.000000 MetaHookPre LoadFile(./contents) +0.000000 MetaHookPre LoadFile(./dcc-send) +0.000000 MetaHookPre LoadFile(./entities) +0.000000 MetaHookPre LoadFile(./event.bif.bro) +0.000000 MetaHookPre LoadFile(./exec) +0.000000 MetaHookPre LoadFile(./file_analysis.bif.bro) +0.000000 MetaHookPre LoadFile(./files) +0.000000 MetaHookPre LoadFile(./gridftp) +0.000000 MetaHookPre LoadFile(./hll_unique) +0.000000 MetaHookPre LoadFile(./hooks.bif.bro) +0.000000 MetaHookPre LoadFile(./inactivity) +0.000000 MetaHookPre LoadFile(./info) +0.000000 MetaHookPre LoadFile(./init.bro) +0.000000 MetaHookPre LoadFile(./input) +0.000000 MetaHookPre LoadFile(./input.bif.bro) +0.000000 MetaHookPre LoadFile(./last) +0.000000 MetaHookPre LoadFile(./logging.bif.bro) +0.000000 MetaHookPre LoadFile(./magic) +0.000000 MetaHookPre LoadFile(./main) +0.000000 MetaHookPre LoadFile(./main.bro) +0.000000 MetaHookPre LoadFile(./max) +0.000000 MetaHookPre LoadFile(./min) +0.000000 MetaHookPre LoadFile(./mozilla-ca-list) +0.000000 MetaHookPre LoadFile(./netstats) +0.000000 MetaHookPre LoadFile(./non-cluster) +0.000000 MetaHookPre LoadFile(./patterns) +0.000000 MetaHookPre LoadFile(./pcap.bif.bro) +0.000000 MetaHookPre LoadFile(./plugins) +0.000000 MetaHookPre LoadFile(./polling) +0.000000 MetaHookPre LoadFile(./postprocessors) +0.000000 MetaHookPre LoadFile(./reporter.bif.bro) +0.000000 MetaHookPre LoadFile(./sample) +0.000000 MetaHookPre LoadFile(./scp) +0.000000 MetaHookPre LoadFile(./sftp) +0.000000 MetaHookPre LoadFile(./site) +0.000000 MetaHookPre LoadFile(./std-dev) +0.000000 MetaHookPre LoadFile(./strings.bif.bro) +0.000000 MetaHookPre LoadFile(./sum) +0.000000 MetaHookPre LoadFile(./top-k.bif.bro) +0.000000 MetaHookPre LoadFile(./topk) +0.000000 MetaHookPre LoadFile(./types.bif.bro) +0.000000 MetaHookPre LoadFile(./unique) +0.000000 MetaHookPre LoadFile(./utils) +0.000000 MetaHookPre LoadFile(./utils-commands) +0.000000 MetaHookPre LoadFile(./utils.bro) +0.000000 MetaHookPre LoadFile(./variance) +0.000000 MetaHookPre LoadFile(./weird) +0.000000 MetaHookPre LoadFile(.<...>/add-geodata) +0.000000 MetaHookPre LoadFile(.<...>/ascii) +0.000000 MetaHookPre LoadFile(.<...>/benchmark) +0.000000 MetaHookPre LoadFile(.<...>/binary) +0.000000 MetaHookPre LoadFile(.<...>/drop) +0.000000 MetaHookPre LoadFile(.<...>/email_admin) +0.000000 MetaHookPre LoadFile(.<...>/hostnames) +0.000000 MetaHookPre LoadFile(.<...>/none) +0.000000 MetaHookPre LoadFile(.<...>/page) +0.000000 MetaHookPre LoadFile(.<...>/pp-alarms) +0.000000 MetaHookPre LoadFile(.<...>/raw) +0.000000 MetaHookPre LoadFile(.<...>/sqlite) +0.000000 MetaHookPre LoadFile(<...>/__load__.bro) +0.000000 MetaHookPre LoadFile(<...>/hooks.bro) +0.000000 MetaHookPre LoadFile(base/bif) +0.000000 MetaHookPre LoadFile(base/init-default.bro) +0.000000 MetaHookPre LoadFile(base<...>/Bro_SNMP.types.bif) +0.000000 MetaHookPre LoadFile(base<...>/active-http) +0.000000 MetaHookPre LoadFile(base<...>/addrs) +0.000000 MetaHookPre LoadFile(base<...>/analyzer) +0.000000 MetaHookPre LoadFile(base<...>/analyzer.bif) +0.000000 MetaHookPre LoadFile(base<...>/bro.bif) +0.000000 MetaHookPre LoadFile(base<...>/cluster) +0.000000 MetaHookPre LoadFile(base<...>/communication) +0.000000 MetaHookPre LoadFile(base<...>/conn) +0.000000 MetaHookPre LoadFile(base<...>/conn-ids) +0.000000 MetaHookPre LoadFile(base<...>/const.bif.bro) +0.000000 MetaHookPre LoadFile(base<...>/control) +0.000000 MetaHookPre LoadFile(base<...>/dhcp) +0.000000 MetaHookPre LoadFile(base<...>/dir) +0.000000 MetaHookPre LoadFile(base<...>/directions-and-hosts) +0.000000 MetaHookPre LoadFile(base<...>/dnp3) +0.000000 MetaHookPre LoadFile(base<...>/dns) +0.000000 MetaHookPre LoadFile(base<...>/dpd) +0.000000 MetaHookPre LoadFile(base<...>/event.bif) +0.000000 MetaHookPre LoadFile(base<...>/exec) +0.000000 MetaHookPre LoadFile(base<...>/extract) +0.000000 MetaHookPre LoadFile(base<...>/file_analysis.bif) +0.000000 MetaHookPre LoadFile(base<...>/files) +0.000000 MetaHookPre LoadFile(base<...>/find-checksum-offloading) +0.000000 MetaHookPre LoadFile(base<...>/find-filtered-trace) +0.000000 MetaHookPre LoadFile(base<...>/ftp) +0.000000 MetaHookPre LoadFile(base<...>/hash) +0.000000 MetaHookPre LoadFile(base<...>/http) +0.000000 MetaHookPre LoadFile(base<...>/input) +0.000000 MetaHookPre LoadFile(base<...>/input.bif) +0.000000 MetaHookPre LoadFile(base<...>/intel) +0.000000 MetaHookPre LoadFile(base<...>/irc) +0.000000 MetaHookPre LoadFile(base<...>/logging) +0.000000 MetaHookPre LoadFile(base<...>/logging.bif) +0.000000 MetaHookPre LoadFile(base<...>/main) +0.000000 MetaHookPre LoadFile(base<...>/modbus) +0.000000 MetaHookPre LoadFile(base<...>/notice) +0.000000 MetaHookPre LoadFile(base<...>/numbers) +0.000000 MetaHookPre LoadFile(base<...>/packet-filter) +0.000000 MetaHookPre LoadFile(base<...>/paths) +0.000000 MetaHookPre LoadFile(base<...>/patterns) +0.000000 MetaHookPre LoadFile(base<...>/plugins) +0.000000 MetaHookPre LoadFile(base<...>/pop3) +0.000000 MetaHookPre LoadFile(base<...>/queue) +0.000000 MetaHookPre LoadFile(base<...>/radius) +0.000000 MetaHookPre LoadFile(base<...>/reporter) +0.000000 MetaHookPre LoadFile(base<...>/reporter.bif) +0.000000 MetaHookPre LoadFile(base<...>/signatures) +0.000000 MetaHookPre LoadFile(base<...>/site) +0.000000 MetaHookPre LoadFile(base<...>/smtp) +0.000000 MetaHookPre LoadFile(base<...>/snmp) +0.000000 MetaHookPre LoadFile(base<...>/socks) +0.000000 MetaHookPre LoadFile(base<...>/software) +0.000000 MetaHookPre LoadFile(base<...>/ssh) +0.000000 MetaHookPre LoadFile(base<...>/ssl) +0.000000 MetaHookPre LoadFile(base<...>/strings) +0.000000 MetaHookPre LoadFile(base<...>/strings.bif) +0.000000 MetaHookPre LoadFile(base<...>/sumstats) +0.000000 MetaHookPre LoadFile(base<...>/syslog) +0.000000 MetaHookPre LoadFile(base<...>/thresholds) +0.000000 MetaHookPre LoadFile(base<...>/time) +0.000000 MetaHookPre LoadFile(base<...>/tunnels) +0.000000 MetaHookPre LoadFile(base<...>/types.bif) +0.000000 MetaHookPre LoadFile(base<...>/unified2) +0.000000 MetaHookPre LoadFile(base<...>/urls) +0.000000 MetaHookPre LoadFile(base<...>/utils) +0.000000 MetaHookPre LoadFile(base<...>/x509) +0.000000 MetaHookPre QueueEvent(bro_init()) +0.000000 MetaHookPre QueueEvent(filter_change_tracking()) +0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_BACKDOOR) +0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_INTERCONN) +0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_STEPPINGSTONE) +0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_TCPSTATS) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 67/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 68/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNP3, 20000/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNS, 137/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNS, 53/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNS, 53/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNS, 5353/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNS, 5355/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_FTP, 21/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_FTP, 2811/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_GTPV1, 2123/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_GTPV1, 2152/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 1080/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 3128/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 631/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 80/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 8000/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 8080/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 81/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_HTTP, 8888/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_IRC, 6666/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_IRC, 6667/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_IRC, 6668/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_IRC, 6669/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_MODBUS, 502/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_RADIUS, 1812/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SMTP, 25/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SMTP, 587/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SNMP, 161/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SNMP, 162/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SOCKS, 1080/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSH, 22/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 443/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 5223/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 563/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 585/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 614/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 636/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 989/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 990/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 992/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 993/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SSL, 995/tcp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_SYSLOG, 514/udp) +0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_TEREDO, 3544/udp) +0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_BACKDOOR) +0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_INTERCONN) +0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_STEPPINGSTONE) +0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_TCPSTATS) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 67/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 68/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNP3, 20000/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNS, 137/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNS, 53/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNS, 53/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNS, 5353/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNS, 5355/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_FTP, 21/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_FTP, 2811/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_GTPV1, 2123/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_GTPV1, 2152/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 1080/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 3128/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 631/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 80/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 8000/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 8080/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 81/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_HTTP, 8888/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_IRC, 6666/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_IRC, 6667/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_IRC, 6668/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_IRC, 6669/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_MODBUS, 502/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_RADIUS, 1812/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SMTP, 25/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SMTP, 587/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SNMP, 161/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SNMP, 162/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SOCKS, 1080/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSH, 22/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 443/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 5223/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 563/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 585/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 614/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 636/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 989/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 990/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 992/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 993/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SSL, 995/tcp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_SYSLOG, 514/udp) +0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_TEREDO, 3544/udp) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_AYIYA, {5072/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, {67<...>/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_DNP3, {20000/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, {5355<...>/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_FTP, {2811<...>/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_GTPV1, {2152<...>/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_HTTP, {631<...>/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_IRC, {6669<...>/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_MODBUS, {502/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_RADIUS, {1812/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SMTP, {25<...>/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SNMP, {162<...>/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SOCKS, {1080/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, {22/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, {5223<...>/tcp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, {514/udp}) +0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_TEREDO, {3544/udp}) +0.000000 | HookCallFunction Cluster::is_enabled() +0.000000 | HookCallFunction Files::register_analyzer_add_callback(Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)mkdir(FileExtract::prefix)}) +0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}]) +0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_HTTP, [get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}]) +0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_IRC_DATA, [get_file_handle=IRC::get_file_handle{ return (cat(Analyzer::ANALYZER_IRC_DATA, IRC::c$start_time, IRC::c$id, IRC::is_orig))}, describe=anonymous-function{ return ()}]) +0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_SMTP, [get_file_handle=SMTP::get_file_handle{ return (cat(Analyzer::ANALYZER_SMTP, SMTP::c$start_time, SMTP::c$smtp$trans_depth, SMTP::c$smtp_state$mime_depth))}, describe=SMTP::describe_file{ SMTP::cid{ if (SMTP::f$source != SMTP) return ()for ([SMTP::cid] in SMTP::f$conns) { SMTP::c = SMTP::f$conns[SMTP::cid]return (SMTP::describe(SMTP::c$smtp))}return ()}}]) +0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_SSL, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}]) +0.000000 | HookCallFunction Log::__add_filter(Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=Log::default_path_func{ if ( != Log::path) return (Log::path)Log::id_str = fmt(%s, Log::id)Log::parts = split1(Log::id_str, <...>/, )return (cat(to_lower(Log::parts[1]), _, to_lower(Log::parts[2])))}elsereturn (to_lower(Log::id_str))}, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__create_stream(Cluster::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(Communication::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(Conn::LOG, [columns=, ev=Conn::log_conn]) +0.000000 | HookCallFunction Log::__create_stream(DHCP::LOG, [columns=, ev=DHCP::log_dhcp]) +0.000000 | HookCallFunction Log::__create_stream(DNP3::LOG, [columns=, ev=DNP3::log_dnp3]) +0.000000 | HookCallFunction Log::__create_stream(DNS::LOG, [columns=, ev=DNS::log_dns]) +0.000000 | HookCallFunction Log::__create_stream(DPD::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(FTP::LOG, [columns=, ev=FTP::log_ftp]) +0.000000 | HookCallFunction Log::__create_stream(Files::LOG, [columns=, ev=Files::log_files]) +0.000000 | HookCallFunction Log::__create_stream(HTTP::LOG, [columns=, ev=HTTP::log_http]) +0.000000 | HookCallFunction Log::__create_stream(IRC::LOG, [columns=, ev=IRC::irc_log]) +0.000000 | HookCallFunction Log::__create_stream(Intel::LOG, [columns=, ev=Intel::log_intel]) +0.000000 | HookCallFunction Log::__create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus]) +0.000000 | HookCallFunction Log::__create_stream(Notice::ALARM_LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(Notice::LOG, [columns=, ev=Notice::log_notice]) +0.000000 | HookCallFunction Log::__create_stream(PacketFilter::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius]) +0.000000 | HookCallFunction Log::__create_stream(Reporter::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(SMTP::LOG, [columns=, ev=SMTP::log_smtp]) +0.000000 | HookCallFunction Log::__create_stream(SNMP::LOG, [columns=, ev=SNMP::log_snmp]) +0.000000 | HookCallFunction Log::__create_stream(SOCKS::LOG, [columns=, ev=SOCKS::log_socks]) +0.000000 | HookCallFunction Log::__create_stream(SSH::LOG, [columns=, ev=SSH::log_ssh]) +0.000000 | HookCallFunction Log::__create_stream(SSL::LOG, [columns=, ev=SSL::log_ssl]) +0.000000 | HookCallFunction Log::__create_stream(Signatures::LOG, [columns=, ev=Signatures::log_signature]) +0.000000 | HookCallFunction Log::__create_stream(Software::LOG, [columns=, ev=Software::log_software]) +0.000000 | HookCallFunction Log::__create_stream(Syslog::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(Tunnel::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::__create_stream(Unified2::LOG, [columns=, ev=Unified2::log_unified2]) +0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) +0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) +0.000000 | HookCallFunction Log::add_default_filter(DHCP::LOG) +0.000000 | HookCallFunction Log::add_default_filter(DNP3::LOG) +0.000000 | HookCallFunction Log::add_default_filter(DNS::LOG) +0.000000 | HookCallFunction Log::add_default_filter(DPD::LOG) +0.000000 | HookCallFunction Log::add_default_filter(FTP::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Files::LOG) +0.000000 | HookCallFunction Log::add_default_filter(HTTP::LOG) +0.000000 | HookCallFunction Log::add_default_filter(IRC::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Intel::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Modbus::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Notice::ALARM_LOG) +0.000000 | HookCallFunction Log::add_default_filter(Notice::LOG) +0.000000 | HookCallFunction Log::add_default_filter(PacketFilter::LOG) +0.000000 | HookCallFunction Log::add_default_filter(RADIUS::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Reporter::LOG) +0.000000 | HookCallFunction Log::add_default_filter(SMTP::LOG) +0.000000 | HookCallFunction Log::add_default_filter(SNMP::LOG) +0.000000 | HookCallFunction Log::add_default_filter(SOCKS::LOG) +0.000000 | HookCallFunction Log::add_default_filter(SSH::LOG) +0.000000 | HookCallFunction Log::add_default_filter(SSL::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Signatures::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Software::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Syslog::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Tunnel::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Unified2::LOG) +0.000000 | HookCallFunction Log::add_default_filter(Weird::LOG) +0.000000 | HookCallFunction Log::add_default_filter(X509::LOG) +0.000000 | HookCallFunction Log::add_filter(Cluster::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Communication::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Conn::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(DHCP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(DNP3::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(DNS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(DPD::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(FTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Files::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(HTTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(IRC::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Modbus::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Notice::ALARM_LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Notice::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(PacketFilter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(RADIUS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Reporter::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(SMTP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(SNMP::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(SOCKS::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(SSH::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(SSL::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Signatures::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Software::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Syslog::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Tunnel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Unified2::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(Weird::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::add_filter(X509::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::create_stream(Cluster::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(Communication::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(Conn::LOG, [columns=, ev=Conn::log_conn]) +0.000000 | HookCallFunction Log::create_stream(DHCP::LOG, [columns=, ev=DHCP::log_dhcp]) +0.000000 | HookCallFunction Log::create_stream(DNP3::LOG, [columns=, ev=DNP3::log_dnp3]) +0.000000 | HookCallFunction Log::create_stream(DNS::LOG, [columns=, ev=DNS::log_dns]) +0.000000 | HookCallFunction Log::create_stream(DPD::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(FTP::LOG, [columns=, ev=FTP::log_ftp]) +0.000000 | HookCallFunction Log::create_stream(Files::LOG, [columns=, ev=Files::log_files]) +0.000000 | HookCallFunction Log::create_stream(HTTP::LOG, [columns=, ev=HTTP::log_http]) +0.000000 | HookCallFunction Log::create_stream(IRC::LOG, [columns=, ev=IRC::irc_log]) +0.000000 | HookCallFunction Log::create_stream(Intel::LOG, [columns=, ev=Intel::log_intel]) +0.000000 | HookCallFunction Log::create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus]) +0.000000 | HookCallFunction Log::create_stream(Notice::ALARM_LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(Notice::LOG, [columns=, ev=Notice::log_notice]) +0.000000 | HookCallFunction Log::create_stream(PacketFilter::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius]) +0.000000 | HookCallFunction Log::create_stream(Reporter::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(SMTP::LOG, [columns=, ev=SMTP::log_smtp]) +0.000000 | HookCallFunction Log::create_stream(SNMP::LOG, [columns=, ev=SNMP::log_snmp]) +0.000000 | HookCallFunction Log::create_stream(SOCKS::LOG, [columns=, ev=SOCKS::log_socks]) +0.000000 | HookCallFunction Log::create_stream(SSH::LOG, [columns=, ev=SSH::log_ssh]) +0.000000 | HookCallFunction Log::create_stream(SSL::LOG, [columns=, ev=SSL::log_ssl]) +0.000000 | HookCallFunction Log::create_stream(Signatures::LOG, [columns=, ev=Signatures::log_signature]) +0.000000 | HookCallFunction Log::create_stream(Software::LOG, [columns=, ev=Software::log_software]) +0.000000 | HookCallFunction Log::create_stream(Syslog::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(Tunnel::LOG, [columns=, ev=]) +0.000000 | HookCallFunction Log::create_stream(Unified2::LOG, [columns=, ev=Unified2::log_unified2]) +0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) +0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509]) +0.000000 | HookCallFunction Log::default_path_func(PacketFilter::LOG, , [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1412734245.308401, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Notice::want_pp() +0.000000 | HookCallFunction PacketFilter::build() +0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) +0.000000 | HookCallFunction PacketFilter::install() +0.000000 | HookCallFunction SumStats::add_observe_plugin_dependency(SumStats::STD_DEV, SumStats::VARIANCE) +0.000000 | HookCallFunction SumStats::add_observe_plugin_dependency(SumStats::VARIANCE, SumStats::AVERAGE) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::AVERAGE, anonymous-function{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::HLL_UNIQUE, anonymous-function{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, SumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::LAST, anonymous-function{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, SumStats::obs)}}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::MAX, anonymous-function{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::MIN, anonymous-function{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SAMPLE, anonymous-function{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::STD_DEV, anonymous-function{ SumStats::calc_std_dev(SumStats::rv)}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SUM, anonymous-function{ SumStats::rv$sum += SumStats::val}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::TOPK, anonymous-function{ topk_add(SumStats::rv$topk, SumStats::obs)}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, anonymous-function{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || flattenSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = flattenSumStats::rv$unique_vals}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::VARIANCE, anonymous-function{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average}) +0.000000 | HookCallFunction SumStats::register_observe_plugins() +0.000000 | HookCallFunction bro_init() +0.000000 | HookCallFunction cat(Packe, t, _, Filter) +0.000000 | HookCallFunction current_time() +0.000000 | HookCallFunction filter_change_tracking() +0.000000 | HookCallFunction fmt(%s, PacketFilter::LOG) +0.000000 | HookCallFunction getenv(CLUSTER_NODE) +0.000000 | HookCallFunction install_pcap_filter(PacketFilter::DefaultPcapFilter) +0.000000 | HookCallFunction network_time() +0.000000 | HookCallFunction precompile_pcap_filter(PacketFilter::DefaultPcapFilter, ip or not ip) +0.000000 | HookCallFunction reading_live_traffic() +0.000000 | HookCallFunction reading_traces() +0.000000 | HookCallFunction set_to_regex({}, (^\.?|\.)(~~)$) +0.000000 | HookCallFunction split1(PacketFilter::LOG, <...>/) +0.000000 | HookCallFunction split_n(PacketFilter, <...>/, T, 4) +0.000000 | HookCallFunction string_to_pattern((^\.?|\.)()$, F) +0.000000 | HookCallFunction sub((^\.?|\.)(~~)$, <...>/, ) +0.000000 | HookCallFunction sub_bytes(tFilter, 1, 1) +0.000000 | HookCallFunction sub_bytes(tFilter, 2, 7) +0.000000 | HookCallFunction to_lower(Packet_Filter) +0.000000 | HookDrainEvents +0.000000 | HookLoadFile ..<...>/bro +0.000000 | HookLoadFile .<...>/bro +0.000000 | HookLoadFile <...>/bro +0.000000 | HookLoadFile base<...>/bif +0.000000 | HookLoadFile base<...>/bro +0.000000 | HookQueueEvent bro_init() +0.000000 | HookQueueEvent filter_change_tracking() +1362692526.869344 MetaHookPost BroObjDtor() -> +1362692526.869344 MetaHookPost CallFunction(ChecksumOffloading::check, , ()) -> +1362692526.869344 MetaHookPost CallFunction(filter_change_tracking, , ()) -> +1362692526.869344 MetaHookPost CallFunction(net_stats, frame , ()) -> +1362692526.869344 MetaHookPost CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.869344 MetaHookPost DrainEvents() -> +1362692526.869344 MetaHookPost QueueEvent(ChecksumOffloading::check()) -> false +1362692526.869344 MetaHookPost QueueEvent(filter_change_tracking()) -> false +1362692526.869344 MetaHookPost QueueEvent(new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> false +1362692526.869344 MetaHookPost UpdateNetworkTime(1362692526.869344) -> +1362692526.869344 MetaHookPre BroObjDtor() +1362692526.869344 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692526.869344 MetaHookPre CallFunction(filter_change_tracking, , ()) +1362692526.869344 MetaHookPre CallFunction(net_stats, frame , ()) +1362692526.869344 MetaHookPre CallFunction(new_connection, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.869344 MetaHookPre DrainEvents() +1362692526.869344 MetaHookPre QueueEvent(ChecksumOffloading::check()) +1362692526.869344 MetaHookPre QueueEvent(filter_change_tracking()) +1362692526.869344 MetaHookPre QueueEvent(new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.869344 MetaHookPre UpdateNetworkTime(1362692526.869344) +1362692526.869344 | HookBroObjDtor +1362692526.869344 | HookUpdateNetworkTime 1362692526.869344 +1362692526.869344 | HookCallFunction ChecksumOffloading::check() +1362692526.869344 | HookCallFunction filter_change_tracking() +1362692526.869344 | HookCallFunction net_stats() +1362692526.869344 | HookCallFunction new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692526.869344 | HookDrainEvents +1362692526.869344 | HookQueueEvent ChecksumOffloading::check() +1362692526.869344 | HookQueueEvent filter_change_tracking() +1362692526.869344 | HookQueueEvent new_connection([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.0, service={}, addl=, hot=0, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692526.869344 | RequestObjDtor ChecksumOffloading::check() +1362692526.939084 MetaHookPost CallFunction(connection_established, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.939084 MetaHookPost DrainEvents() -> +1362692526.939084 MetaHookPost QueueEvent(connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> false +1362692526.939084 MetaHookPost UpdateNetworkTime(1362692526.939084) -> +1362692526.939084 MetaHookPre CallFunction(connection_established, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.939084 MetaHookPre DrainEvents() +1362692526.939084 MetaHookPre QueueEvent(connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.939084 MetaHookPre UpdateNetworkTime(1362692526.939084) +1362692526.939084 | HookUpdateNetworkTime 1362692526.939084 +1362692526.939084 | HookCallFunction connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692526.939084 | HookDrainEvents +1362692526.939084 | HookQueueEvent connection_established([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=64, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1362692526.869344, duration=0.06974, service={}, addl=, hot=0, history=Sh, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692526.939378 MetaHookPost DrainEvents() -> +1362692526.939378 MetaHookPost UpdateNetworkTime(1362692526.939378) -> +1362692526.939378 MetaHookPre DrainEvents() +1362692526.939378 MetaHookPre UpdateNetworkTime(1362692526.939378) +1362692526.939378 | HookUpdateNetworkTime 1362692526.939378 +1362692526.939378 | HookDrainEvents +1362692526.939527 MetaHookPost CallFunction(Analyzer::__name, frame Analyzer::ANALYZER_HTTP, (Analyzer::ANALYZER_HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(Analyzer::name, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3, (Analyzer::ANALYZER_HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::new_http_session, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) -> +1362692526.939527 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) -> +1362692526.939527 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692526.939527 MetaHookPost CallFunction(fmt, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3HTTP, (-%s, HTTP)) -> +1362692526.939527 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692526.939527 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) -> +1362692526.939527 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) -> +1362692526.939527 MetaHookPost CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -> +1362692526.939527 MetaHookPost CallFunction(http_request, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -> +1362692526.939527 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692526.939527 MetaHookPost CallFunction(network_time, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=][ts=, uid=, id=[orig_h=, orig_p=, resp_h=, resp_p=], trans_depth=, method=, host=, uri=, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0], ()) -> +1362692526.939527 MetaHookPost CallFunction(protocol_confirmation, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) -> +1362692526.939527 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692526.939527 MetaHookPost CallFunction(split1, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692526.939527 MetaHookPost DrainEvents() -> +1362692526.939527 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) -> false +1362692526.939527 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) -> false +1362692526.939527 MetaHookPost QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) -> false +1362692526.939527 MetaHookPost QueueEvent(http_request([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) -> false +1362692526.939527 MetaHookPost UpdateNetworkTime(1362692526.939527) -> +1362692526.939527 MetaHookPre CallFunction(Analyzer::__name, frame Analyzer::ANALYZER_HTTP, (Analyzer::ANALYZER_HTTP)) +1362692526.939527 MetaHookPre CallFunction(Analyzer::name, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3, (Analyzer::ANALYZER_HTTP)) +1362692526.939527 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::new_http_session, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T)) +1362692526.939527 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T)) +1362692526.939527 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692526.939527 MetaHookPre CallFunction(fmt, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]Analyzer::ANALYZER_HTTP3HTTP, (-%s, HTTP)) +1362692526.939527 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692526.939527 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) +1362692526.939527 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) +1362692526.939527 MetaHookPre CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) +1362692526.939527 MetaHookPre CallFunction(http_request, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) +1362692526.939527 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692526.939527 MetaHookPre CallFunction(network_time, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=][ts=, uid=, id=[orig_h=, orig_p=, resp_h=, resp_p=], trans_depth=, method=, host=, uri=, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0], ()) +1362692526.939527 MetaHookPre CallFunction(protocol_confirmation, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3)) +1362692526.939527 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) +1362692526.939527 MetaHookPre CallFunction(split1, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692526.939527 MetaHookPre DrainEvents() +1362692526.939527 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692526.939527 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/*)) +1362692526.939527 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0))) +1362692526.939527 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive)) +1362692526.939527 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org)) +1362692526.939527 MetaHookPre QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124])) +1362692526.939527 MetaHookPre QueueEvent(http_request([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1)) +1362692526.939527 MetaHookPre UpdateNetworkTime(1362692526.939527) +1362692526.939527 | HookUpdateNetworkTime 1362692526.939527 +1362692526.939527 | HookCallFunction Analyzer::__name(Analyzer::ANALYZER_HTTP) +1362692526.939527 | HookCallFunction Analyzer::name(Analyzer::ANALYZER_HTTP) +1362692526.939527 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookCallFunction HTTP::new_http_session([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692526.939527 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T) +1362692526.939527 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T) +1362692526.939527 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T) +1362692526.939527 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, T) +1362692526.939527 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=[pending={}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, T) +1362692526.939527 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) +1362692526.939527 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) +1362692526.939527 | HookCallFunction fmt(-%s, HTTP) +1362692526.939527 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookCallFunction http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, referrer=, user_agent=, request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=0, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookCallFunction http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/*) +1362692526.939527 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0)) +1362692526.939527 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive) +1362692526.939527 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org) +1362692526.939527 | HookCallFunction http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124]) +1362692526.939527 | HookCallFunction http_request([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1) +1362692526.939527 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) +1362692526.939527 | HookCallFunction network_time() +1362692526.939527 | HookCallFunction protocol_confirmation([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], Analyzer::ANALYZER_HTTP, 3) +1362692526.939527 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80) +1362692526.939527 | HookCallFunction split1(bro.org, <...>/) +1362692526.939527 | HookDrainEvents +1362692526.939527 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookQueueEvent http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692526.939527 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/*) +1362692526.939527 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0)) +1362692526.939527 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, CONNECTION, Keep-Alive) +1362692526.939527 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], orig=[size=136, state=4, num_pkts=2, num_bytes_ip=116, flow_label=0], resp=[size=0, state=4, num_pkts=1, num_bytes_ip=60, flow_label=0], start_time=1362692526.869344, duration=0.070183, service={HTTP}, addl=, hot=0, history=ShAD, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, HOST, bro.org) +1362692526.939527 | HookQueueEvent http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T, [start=1362692526.939527, interrupted=F, finish_msg=message ends normally, body_length=0, content_gap_length=0, header_length=124]) +1362692526.939527 | HookQueueEvent http_request([id=[orig_h=141.142.228.5, orig_p=59856<...>/CHANGES.bro-aux.txt, 1.1) +1362692527.008509 MetaHookPost DrainEvents() -> +1362692527.008509 MetaHookPost UpdateNetworkTime(1362692527.008509) -> +1362692527.008509 MetaHookPre DrainEvents() +1362692527.008509 MetaHookPre UpdateNetworkTime(1362692527.008509) +1362692527.008509 | HookUpdateNetworkTime 1362692527.008509 +1362692527.008509 | HookDrainEvents +1362692527.009512 MetaHookPost CallFunction(Files::__add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) -> +1362692527.009512 MetaHookPost CallFunction(Files::add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) -> +1362692527.009512 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]1.1200OK[pending={}, current_request=0, current_response=0], (200, 100, 199)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009512 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009512 MetaHookPost CallFunction(file_new, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> +1362692527.009512 MetaHookPost CallFunction(file_over_new_connection, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.009512 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) -> +1362692527.009512 MetaHookPost CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -> +1362692527.009512 MetaHookPost CallFunction(http_reply, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) -> +1362692527.009512 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.009512 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009512 MetaHookPost CallFunction(split_all, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692527.009512 MetaHookPost DrainEvents() -> +1362692527.009512 MetaHookPost QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) -> false +1362692527.009512 MetaHookPost QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009512 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) -> false +1362692527.009512 MetaHookPost QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) -> false +1362692527.009512 MetaHookPost QueueEvent(http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) -> false +1362692527.009512 MetaHookPost UpdateNetworkTime(1362692527.009512) -> +1362692527.009512 MetaHookPre CallFunction(Files::__add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0])) +1362692527.009512 MetaHookPre CallFunction(Files::add_analyzers_for_mime_type, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain)) +1362692527.009512 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009512 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]1.1200OK[pending={}, current_request=0, current_response=0], (200, 100, 199)) +1362692527.009512 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009512 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009512 MetaHookPre CallFunction(file_new, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre CallFunction(file_over_new_connection, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.009512 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(http_begin_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) +1362692527.009512 MetaHookPre CallFunction(http_header, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) +1362692527.009512 MetaHookPre CallFunction(http_reply, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) +1362692527.009512 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.009512 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009512 MetaHookPre CallFunction(split_all, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692527.009512 MetaHookPre DrainEvents() +1362692527.009512 MetaHookPre QueueEvent(file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=])) +1362692527.009512 MetaHookPre QueueEvent(file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre QueueEvent(http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0")) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT)) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora))) +1362692527.009512 MetaHookPre QueueEvent(http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8)) +1362692527.009512 MetaHookPre QueueEvent(http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK)) +1362692527.009512 MetaHookPre UpdateNetworkTime(1362692527.009512) +1362692527.009512 | HookUpdateNetworkTime 1362692527.009512 +1362692527.009512 | HookCallFunction Files::__add_analyzers_for_mime_type(FakNcS1Jfe01uljb3, text/plain, [chunk_event=, stream_event=, extract_filename=, extract_limit=0]) +1362692527.009512 | HookCallFunction Files::add_analyzers_for_mime_type([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain) +1362692527.009512 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) +1362692527.009512 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) +1362692527.009512 | HookCallFunction HTTP::code_in_range(200, 100, 199) +1362692527.009512 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) +1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) +1362692527.009512 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) +1362692527.009512 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009512 | HookCallFunction file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) +1362692527.009512 | HookCallFunction file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) +1362692527.009512 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookCallFunction http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0") +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora)) +1362692527.009512 | HookCallFunction http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8) +1362692527.009512 | HookCallFunction http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK) +1362692527.009512 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) +1362692527.009512 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009512 | HookCallFunction split_all(HTTP, <...>/) +1362692527.009512 | HookDrainEvents +1362692527.009512 | HookQueueEvent file_new([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], info=, u2_events=]) +1362692527.009512 | HookQueueEvent file_over_new_connection([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=200, status_msg=OK, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookQueueEvent http_begin_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ACCEPT-RANGES, bytes) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONNECTION, Keep-Alive) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, CONTENT-LENGTH, 4705) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, DATE, Thu, 07 Mar 2013 21:43:07 GMT) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, ETAG, "1261-4c870358a6fc0") +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, KEEP-ALIVE, timeout=5, max=100) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, LAST-MODIFIED, Wed, 29 Aug 2012 23:49:27 GMT) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/2.4.3 (Fedora)) +1362692527.009512 | HookQueueEvent http_header([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain; charset=UTF-8) +1362692527.009512 | HookQueueEvent http_reply([id=[orig_h=141.142.228.5, orig_p=59856<...>/1.14 (darwin12.2.0), request_body_len=0, response_body_len=0, status_code=, status_msg=, info_code=, info_msg=, filename=, tags={}, username=, password=, capture_password=F, proxied=, range_request=F, orig_fuids=, orig_mime_types=, resp_fuids=, resp_mime_types=, current_entity=, orig_mime_depth=1, resp_mime_depth=0]}, current_request=1, current_response=0], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], 1.1, 200, OK) +1362692527.009721 MetaHookPost DrainEvents() -> +1362692527.009721 MetaHookPost UpdateNetworkTime(1362692527.009721) -> +1362692527.009721 MetaHookPre DrainEvents() +1362692527.009721 MetaHookPre UpdateNetworkTime(1362692527.009721) +1362692527.009721 | HookUpdateNetworkTime 1362692527.009721 +1362692527.009721 | HookDrainEvents +1362692527.009765 MetaHookPost DrainEvents() -> +1362692527.009765 MetaHookPost UpdateNetworkTime(1362692527.009765) -> +1362692527.009765 MetaHookPre DrainEvents() +1362692527.009765 MetaHookPre UpdateNetworkTime(1362692527.009765) +1362692527.009765 | HookUpdateNetworkTime 1362692527.009765 +1362692527.009765 | HookDrainEvents +1362692527.009775 MetaHookPost CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280], (200, 100, 199)) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) -> +1362692527.009775 MetaHookPost CallFunction(Log::__write, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::__write, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, , (Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::default_path_func, , (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(Log::write, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) -> +1362692527.009775 MetaHookPost CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) -> +1362692527.009775 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009775 MetaHookPost CallFunction(file_state_remove, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], (%s, Files::LOG)) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], (%s, HTTP::LOG)) -> +1362692527.009775 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.009775 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> +1362692527.009775 MetaHookPost CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -> +1362692527.009775 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.009775 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.009775 MetaHookPost CallFunction(split1, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/)) -> +1362692527.009775 MetaHookPost CallFunction(split1, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692527.009775 MetaHookPost CallFunction(split_n, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/, T, 4)) -> +1362692527.009775 MetaHookPost CallFunction(split_n, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) -> +1362692527.009775 MetaHookPost CallFunction(to_lower, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]Files::LOG{[2] = LOG,[1] = Files}{[1] = Files}Files, (Files)) -> +1362692527.009775 MetaHookPost CallFunction(to_lower, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]HTTP::LOG{[2] = LOG,[1] = HTTP}{[1] = HTTP}HTTP, (HTTP)) -> +1362692527.009775 MetaHookPost DrainEvents() -> +1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) -> false +1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) -> false +1362692527.009775 MetaHookPost QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) -> false +1362692527.009775 MetaHookPost UpdateNetworkTime(1362692527.009775) -> +1362692527.009775 MetaHookPre CallFunction(Files::set_info, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009775 MetaHookPre CallFunction(HTTP::code_in_range, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280], (200, 100, 199)) +1362692527.009775 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(HTTP::set_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F)) +1362692527.009775 MetaHookPre CallFunction(Log::__write, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::__write, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, , (Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::default_path_func, , (HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(Log::write, frame [id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=])) +1362692527.009775 MetaHookPre CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1])) +1362692527.009775 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009775 MetaHookPre CallFunction(file_state_remove, , ([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009775 MetaHookPre CallFunction(fmt, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], (%s, Files::LOG)) +1362692527.009775 MetaHookPre CallFunction(fmt, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], (%s, HTTP::LOG)) +1362692527.009775 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.009775 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(http_end_entity, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre CallFunction(http_message_done, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) +1362692527.009775 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.009775 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]F[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.009775 MetaHookPre CallFunction(split1, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/)) +1362692527.009775 MetaHookPre CallFunction(split1, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692527.009775 MetaHookPre CallFunction(split_n, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text<...>/, T, 4)) +1362692527.009775 MetaHookPre CallFunction(split_n, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) +1362692527.009775 MetaHookPre CallFunction(to_lower, frame Files::LOG[ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]Files::LOG{[2] = LOG,[1] = Files}{[1] = Files}Files, (Files)) +1362692527.009775 MetaHookPre CallFunction(to_lower, frame HTTP::LOG[ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]HTTP::LOG{[2] = LOG,[1] = HTTP}{[1] = HTTP}HTTP, (HTTP)) +1362692527.009775 MetaHookPre DrainEvents() +1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=])) +1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F)) +1362692527.009775 MetaHookPre QueueEvent(http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280])) +1362692527.009775 MetaHookPre UpdateNetworkTime(1362692527.009775) +1362692527.009775 | HookUpdateNetworkTime 1362692527.009775 +1362692527.009775 | HookCallFunction Files::set_info([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) +1362692527.009775 | HookCallFunction HTTP::code_in_range(200, 100, 199) +1362692527.009775 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009775 | HookCallFunction HTTP::set_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, F) +1362692527.009775 | HookCallFunction Log::__write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::__write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) +1362692527.009775 | HookCallFunction Log::default_path_func(Files::LOG, , [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::default_path_func(HTTP::LOG, , [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) +1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CXWv6p3arKYeMETxOg}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=, duration=262.0 usecs, local_orig=, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=]) +1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]) +1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) +1362692527.009775 | HookCallFunction fmt(%s, Files::LOG) +1362692527.009775 | HookCallFunction fmt(%s, HTTP::LOG) +1362692527.009775 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) +1362692527.009775 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009775 | HookCallFunction http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009775 | HookCallFunction http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280]) +1362692527.009775 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) +1362692527.009775 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344F11141.142.228.5:59856 > 192.150.187.43:80) +1362692527.009775 | HookCallFunction split1(Files::LOG, <...>/) +1362692527.009775 | HookCallFunction split1(HTTP::LOG, <...>/) +1362692527.009775 | HookCallFunction split_n(Files, <...>/, T, 4) +1362692527.009775 | HookCallFunction split_n(HTTP, <...>/, T, 4) +1362692527.009775 | HookCallFunction to_lower(Files) +1362692527.009775 | HookCallFunction to_lower(HTTP) +1362692527.009775 | HookDrainEvents +1362692527.009775 | HookQueueEvent file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=]) +1362692527.009775 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009775 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F) +1362692527.009775 | HookQueueEvent http_message_done([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], F, [start=1362692527.009512, interrupted=F, finish_msg=message ends normally, body_length=4705, content_gap_length=0, header_length=280]) +1362692527.009855 MetaHookPost DrainEvents() -> +1362692527.009855 MetaHookPost UpdateNetworkTime(1362692527.009855) -> +1362692527.009855 MetaHookPre DrainEvents() +1362692527.009855 MetaHookPre UpdateNetworkTime(1362692527.009855) +1362692527.009855 | HookUpdateNetworkTime 1362692527.009855 +1362692527.009855 | HookDrainEvents +1362692527.009887 MetaHookPost DrainEvents() -> +1362692527.009887 MetaHookPost UpdateNetworkTime(1362692527.009887) -> +1362692527.009887 MetaHookPre DrainEvents() +1362692527.009887 MetaHookPre UpdateNetworkTime(1362692527.009887) +1362692527.009887 | HookUpdateNetworkTime 1362692527.009887 +1362692527.009887 | HookDrainEvents +1362692527.011846 MetaHookPost DrainEvents() -> +1362692527.011846 MetaHookPost UpdateNetworkTime(1362692527.011846) -> +1362692527.011846 MetaHookPre DrainEvents() +1362692527.011846 MetaHookPre UpdateNetworkTime(1362692527.011846) +1362692527.011846 | HookUpdateNetworkTime 1362692527.011846 +1362692527.011846 | HookDrainEvents +1362692527.080828 MetaHookPost DrainEvents() -> +1362692527.080828 MetaHookPost UpdateNetworkTime(1362692527.080828) -> +1362692527.080828 MetaHookPre DrainEvents() +1362692527.080828 MetaHookPre UpdateNetworkTime(1362692527.080828) +1362692527.080828 | HookUpdateNetworkTime 1362692527.080828 +1362692527.080828 | HookDrainEvents +1362692527.080972 MetaHookPost CallFunction(ChecksumOffloading::check, , ()) -> +1362692527.080972 MetaHookPost CallFunction(Conn::conn_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) -> +1362692527.080972 MetaHookPost CallFunction(Conn::determine_service, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692527.080972 MetaHookPost CallFunction(Conn::set_conn, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(Log::__write, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(Log::default_path_func, , (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) -> +1362692527.080972 MetaHookPost CallFunction(bro_done, , ()) -> +1362692527.080972 MetaHookPost CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.080972 MetaHookPost CallFunction(connection_state_remove, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> +1362692527.080972 MetaHookPost CallFunction(filter_change_tracking, , ()) -> +1362692527.080972 MetaHookPost CallFunction(fmt, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}], (%s, Conn::LOG)) -> +1362692527.080972 MetaHookPost CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> +1362692527.080972 MetaHookPost CallFunction(get_port_transport_proto, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) -> +1362692527.080972 MetaHookPost CallFunction(is_tcp_port, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) -> +1362692527.080972 MetaHookPost CallFunction(net_done, , (1362692527.080972)) -> +1362692527.080972 MetaHookPost CallFunction(net_stats, frame , ()) -> +1362692527.080972 MetaHookPost CallFunction(reading_traces, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], ()) -> +1362692527.080972 MetaHookPost CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) -> +1362692527.080972 MetaHookPost CallFunction(split1, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) -> +1362692527.080972 MetaHookPost CallFunction(split_n, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) -> +1362692527.080972 MetaHookPost CallFunction(sub_bytes, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTP, (HTTP, 0, 1)) -> +1362692527.080972 MetaHookPost CallFunction(to_lower, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]Conn::LOG{[2] = LOG,[1] = Conn}{[1] = Conn}Conn, (Conn)) -> +1362692527.080972 MetaHookPost CallFunction(to_lower, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTPHTTP, (HTTP)) -> +1362692527.080972 MetaHookPost DrainEvents() -> +1362692527.080972 MetaHookPost QueueEvent(ChecksumOffloading::check()) -> false +1362692527.080972 MetaHookPost QueueEvent(bro_done()) -> false +1362692527.080972 MetaHookPost QueueEvent(connection_state_remove([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> false +1362692527.080972 MetaHookPost QueueEvent(filter_change_tracking()) -> false +1362692527.080972 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) -> false +1362692527.080972 MetaHookPost UpdateNetworkTime(1362692527.080972) -> +1362692527.080972 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692527.080972 MetaHookPre CallFunction(Conn::conn_state, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp)) +1362692527.080972 MetaHookPre CallFunction(Conn::determine_service, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692527.080972 MetaHookPre CallFunction(Conn::set_conn, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(HTTP::get_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(Log::__write, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(Log::default_path_func, , (Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(Log::write, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}])) +1362692527.080972 MetaHookPre CallFunction(bro_done, , ()) +1362692527.080972 MetaHookPre CallFunction(cat, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T1, (Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.080972 MetaHookPre CallFunction(connection_state_remove, , ([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692527.080972 MetaHookPre CallFunction(filter_change_tracking, , ()) +1362692527.080972 MetaHookPre CallFunction(fmt, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}], (%s, Conn::LOG)) +1362692527.080972 MetaHookPre CallFunction(fmt, frame [orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(get_file_handle, , (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre CallFunction(get_port_transport_proto, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(id_string, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp])) +1362692527.080972 MetaHookPre CallFunction(is_tcp_port, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp)) +1362692527.080972 MetaHookPre CallFunction(net_done, , (1362692527.080972)) +1362692527.080972 MetaHookPre CallFunction(net_stats, frame , ()) +1362692527.080972 MetaHookPre CallFunction(reading_traces, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], ()) +1362692527.080972 MetaHookPre CallFunction(set_file_handle, frame Analyzer::ANALYZER_HTTP[id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]T[get_file_handle=HTTP::get_file_handle{ if (!HTTP::c?$http) return ()if (HTTP::c$http$range_request && !HTTP::is_orig) { return (cat(Analyzer::ANALYZER_HTTP, HTTP::is_orig, HTTP::c$id$orig_h, HTTP::build_url(HTTP::c$http)))}else{ HTTP::mime_depth = HTTP::is_orig ? HTTP::c$http$orig_mime_depth : HTTP::c$http$resp_mime_depthreturn (cat(Analyzer::ANALYZER_HTTP, HTTP::c$start_time, HTTP::is_orig, HTTP::c$http$trans_depth, HTTP::mime_depth, id_string(HTTP::c$id)))}}, describe=HTTP::describe_file{ HTTP::cid{ if (HTTP::f$source != HTTP) return ()for ([HTTP::cid] in HTTP::f$conns) { if (HTTP::f$conns[HTTP::cid]?$http) return (HTTP::build_url_http(HTTP::f$conns[HTTP::cid]$http))}return ()}}], (Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80)) +1362692527.080972 MetaHookPre CallFunction(split1, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/)) +1362692527.080972 MetaHookPre CallFunction(split_n, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/, T, 4)) +1362692527.080972 MetaHookPre CallFunction(sub_bytes, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTP, (HTTP, 0, 1)) +1362692527.080972 MetaHookPre CallFunction(to_lower, frame Conn::LOG[ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]Conn::LOG{[2] = LOG,[1] = Conn}{[1] = Conn}Conn, (Conn)) +1362692527.080972 MetaHookPre CallFunction(to_lower, frame [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]HTTPHTTP, (HTTP)) +1362692527.080972 MetaHookPre DrainEvents() +1362692527.080972 MetaHookPre QueueEvent(ChecksumOffloading::check()) +1362692527.080972 MetaHookPre QueueEvent(bro_done()) +1362692527.080972 MetaHookPre QueueEvent(connection_state_remove([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) +1362692527.080972 MetaHookPre QueueEvent(filter_change_tracking()) +1362692527.080972 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T)) +1362692527.080972 MetaHookPre UpdateNetworkTime(1362692527.080972) +1362692527.080972 | HookUpdateNetworkTime 1362692527.080972 +1362692527.080972 | HookCallFunction ChecksumOffloading::check() +1362692527.080972 | HookCallFunction Conn::conn_state([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], tcp) +1362692527.080972 | HookCallFunction Conn::determine_service([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692527.080972 | HookCallFunction Conn::set_conn([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692527.080972 | HookCallFunction HTTP::get_file_handle([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692527.080972 | HookCallFunction Log::__write(Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]) +1362692527.080972 | HookCallFunction Log::default_path_func(Conn::LOG, , [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]) +1362692527.080972 | HookCallFunction Log::write(Conn::LOG, [ts=1362692526.869344, uid=CXWv6p3arKYeMETxOg, id=[orig_h=141.142.228.5, orig_p=59856<...>/tcp], proto=tcp, service=http, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents={}]) +1362692527.080972 | HookCallFunction bro_done() +1362692527.080972 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, T, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) +1362692527.080972 | HookCallFunction connection_state_remove([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692527.080972 | HookCallFunction filter_change_tracking() +1362692527.080972 | HookCallFunction fmt(%s, Conn::LOG) +1362692527.080972 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) +1362692527.080972 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) +1362692527.080972 | HookCallFunction get_port_transport_proto(80/tcp) +1362692527.080972 | HookCallFunction id_string([orig_h=141.142.228.5, orig_p=59856<...>/tcp]) +1362692527.080972 | HookCallFunction is_tcp_port(59856/tcp) +1362692527.080972 | HookCallFunction net_done(1362692527.080972) +1362692527.080972 | HookCallFunction net_stats() +1362692527.080972 | HookCallFunction reading_traces() +1362692527.080972 | HookCallFunction set_file_handle(Analyzer::ANALYZER_HTTP1362692526.869344T11141.142.228.5:59856 > 192.150.187.43:80) +1362692527.080972 | HookCallFunction split1(Conn::LOG, <...>/) +1362692527.080972 | HookCallFunction split_n(Conn, <...>/, T, 4) +1362692527.080972 | HookCallFunction sub_bytes(HTTP, 0, 1) +1362692527.080972 | HookCallFunction to_lower(Conn) +1362692527.080972 | HookCallFunction to_lower(HTTP) +1362692527.080972 | HookDrainEvents +1362692527.080972 | HookQueueEvent ChecksumOffloading::check() +1362692527.080972 | HookQueueEvent bro_done() +1362692527.080972 | HookQueueEvent connection_state_remove([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) +1362692527.080972 | HookQueueEvent filter_change_tracking() +1362692527.080972 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={}, current_request=1, current_response=1], irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=], T) From 6055b56f5c8e6acba33be2efcb93b69a80961103 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Mon, 24 Nov 2014 14:28:17 -0500 Subject: [PATCH 012/256] Incremental --- src/Func.cc | 98 ++++++++++++++++++++------------------------ src/plugin/Plugin.cc | 54 ++++++++++++------------ src/plugin/Plugin.h | 84 ++++++++++++++++++------------------- 3 files changed, 114 insertions(+), 122 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index 409bdcae25..ccc5698b2c 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -249,38 +249,34 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const ValWrapper* Func::HandlePluginResult(ValWrapper* plugin_result, val_list* args, function_flavor flavor) const { - // We either have not received a plugin result, or the plugin result hasn't been processed (read: fall into ::Call method) - if(!plugin_result) - return NULL; + // We either have not received a plugin result, or the plugin result hasn't been processed (read: fall into ::Call method) + if(!plugin_result) + return NULL; - if(!plugin_result->processed) - { - if(plugin_result->value) - { - Unref(plugin_result->value); - plugin_result->value = NULL; - } - delete plugin_result; - return NULL; - } + if(!plugin_result->processed) + { + if(plugin_result->value) + { + Unref(plugin_result->value); + plugin_result->value = NULL; + } + delete plugin_result; + return NULL; + } switch ( flavor ) { case FUNC_FLAVOR_EVENT: - if(plugin_result->value) - { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned non-void result for event %s", this->Name()); - reporter->InternalError(sbuf); - } + if(plugin_result->value) + { + reporter->InternalError("plugin returned non-void result for event %s", this->Name()); + } break; case FUNC_FLAVOR_HOOK: if ( plugin_result->value->Type()->Tag() != TYPE_BOOL ) - { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned non-bool for hook %s", this->Name()); - reporter->InternalError(sbuf); - } + { + reporter->InternalError("plugin returned non-bool for hook %s", this->Name()); + } break; case FUNC_FLAVOR_FUNCTION: @@ -289,19 +285,15 @@ ValWrapper* Func::HandlePluginResult(ValWrapper* plugin_result, val_list* args, if ( (! yt) || yt->Tag() == TYPE_VOID ) { - if(plugin_result && plugin_result->value) - { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned non-void result for void method %s", this->Name()); - reporter->InternalError(sbuf); - } - } + if(plugin_result && plugin_result->value) + { + reporter->InternalError("plugin returned non-void result for void method %s", this->Name()); + } + } else if ( plugin_result->value && plugin_result->value->Type()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY) { - char sbuf[1024]; - snprintf(sbuf, 1024, "plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->value->Type()->Tag(), yt->Tag(), this->Name()); - reporter->InternalError(sbuf); - } + reporter->InternalError("plugin returned wrong type (got %d, expecting %d) for %s", plugin_result->value->Type()->Tag(), yt->Tag(), this->Name()); + } break; } @@ -358,13 +350,13 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const ValWrapper* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); - plugin_result = HandlePluginResult(plugin_result, args, Flavor()); - if(plugin_result) - { - Val *result = plugin_result->value; - delete plugin_result; - return result; - } + plugin_result = HandlePluginResult(plugin_result, args, Flavor()); + if(plugin_result) + { + Val *result = plugin_result->value; + delete plugin_result; + return result; + } if ( bodies.empty() ) { @@ -455,11 +447,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const // Warn if the function returns something, but we returned from // the function without an explicit return, or without a value. else if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID && - (flow != FLOW_RETURN /* we fell off the end */ || - ! result /* explicit return with no result */) && - ! f->HasDelayed() ) + (flow != FLOW_RETURN /* we fell off the end */ || + ! result /* explicit return with no result */) && + ! f->HasDelayed() ) reporter->Warning("non-void function returns without a value: %s", - Name()); + Name()); if ( result && g_trace_state.DoTrace() ) { @@ -580,13 +572,13 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const ValWrapper* plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), 0); - plugin_result = HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); - if(plugin_result) - { - Val *result = plugin_result->value; - delete plugin_result; - return result; - } + plugin_result = HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); + if(plugin_result) + { + Val *result = plugin_result->value; + delete plugin_result; + return result; + } if ( g_trace_state.DoTrace() ) { diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 1e98532ba6..9a571743af 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -83,12 +83,12 @@ void HookArgument::Describe(ODesc* d) const d->Add(""); break; - case FRAME: - if ( arg.frame ) - arg.frame->Describe(d); - else - d->Add(""); - break; + case FRAME: + if ( arg.frame ) + arg.frame->Describe(d); + else + d->Add(""); + break; case FUNC: if ( arg.func ) @@ -131,25 +131,25 @@ void HookArgument::Describe(ODesc* d) const case VOIDP: d->Add(""); break; - - case WRAPPED_VAL: - if ( arg.wrapper ) - { - d->Add("wrapped("); - if(arg.wrapper->value) - { - arg.wrapper->value->Describe(d); - } - else - d->Add(""); - d->Add(")"); - } - else - { - d->Add(""); - } + + case WRAPPED_VAL: + if ( arg.wrapper ) + { + d->Add("wrapped("); + if(arg.wrapper->value) + { + arg.wrapper->value->Describe(d); + } + else + d->Add(""); + d->Add(")"); + } + else + { + d->Add(""); + } - break; + break; } } @@ -226,7 +226,7 @@ void Plugin::InitPostScript() Plugin::bif_item_list Plugin::BifItems() const { - return bif_items; + return bif_items; } void Plugin::Done() @@ -399,7 +399,7 @@ void Plugin::Describe(ODesc* d) const type = ""; } - d->Add(" "); + d->Add(" "); d->Add("["); d->Add(type); d->Add("] "); @@ -414,7 +414,7 @@ void Plugin::Describe(ODesc* d) const HookType hook = (*i).first; int prio = (*i).second; - d->Add(" Implements "); + d->Add(" Implements "); d->Add(hook_name(hook)); d->Add(" (priority "); d->Add(prio); diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 65acb37b7a..af47a5f4bf 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -34,24 +34,24 @@ class Plugin; * Plugins' function handlers return a result of this type. */ struct ValWrapper { - Val* value; //< value being wrapped by this object - bool processed; //< true if execution should *STOP* (read: the plugin is replacing a method), and false if execution should *CONTINUE* (read: bro should execute a method) + Val* value; //< value being wrapped by this object + bool processed; //< true if execution should *STOP* (read: the plugin is replacing a method), and false if execution should *CONTINUE* (read: bro should execute a method) - /** - Wrapper for a specific value. If we're setting a value, we assume we've processed something. - - @param value value to be wrapped - */ - ValWrapper(Val* value) - : value(value), processed(true) { } + /** + Wrapper for a specific value. If we're setting a value, we assume we've processed something. + + @param value value to be wrapped + */ + ValWrapper(Val* value) + : value(value), processed(true) { } - /** - Wrapper for a specific value. If we're setting 'processed', we assume there's a reason we're not setting a Val and set that to NULL. - - @param processed whether or not an execution of a function was handled by the plugin - */ - ValWrapper(bool processed) - : value(NULL), processed(processed) { } + /** + Wrapper for a specific value. If we're setting 'processed', we assume there's a reason we're not setting a Val and set that to NULL. + + @param processed whether or not an execution of a function was handled by the plugin + */ + ValWrapper(bool processed) + : value(NULL), processed(processed) { } }; /** @@ -237,15 +237,15 @@ public: */ HookArgument(void* p) { type = VOIDP; arg.voidp = p; } - /** - * Constructor with a ValWrapper argument. - */ - HookArgument(ValWrapper* a) { type = WRAPPED_VAL; arg.wrapper = a; } + /** + * Constructor with a ValWrapper argument. + */ + HookArgument(ValWrapper* a) { type = WRAPPED_VAL; arg.wrapper = a; } - /** - * Constructor with a Frame argument. - */ - HookArgument(Frame* f) { type = FRAME; arg.frame = f; } + /** + * Constructor with a Frame argument. + */ + HookArgument(Frame* f) { type = FRAME; arg.frame = f; } /** * Returns the value for a boolen argument. The argument's type must @@ -289,17 +289,17 @@ public: */ const Val* AsVal() const { assert(type == VAL); return arg.val; } - /** - * Returns the value for a Bro wrapped value argument. The argument's type must - * match accordingly. - */ - const ValWrapper* AsValWrapper() const { assert(type == VAL_WRAPPER); return arg.wrapper; } + /** + * Returns the value for a Bro wrapped value argument. The argument's type must + * match accordingly. + */ + const ValWrapper* AsValWrapper() const { assert(type == VAL_WRAPPER); return arg.wrapper; } - /** - * Returns the value for a Bro frame argument. The argument's type must - * match accordingly. - */ - const Frame* AsFrame() const { assert(type == FRAME); return arg.frame; } + /** + * Returns the value for a Bro frame argument. The argument's type must + * match accordingly. + */ + const Frame* AsFrame() const { assert(type == FRAME); return arg.frame; } /** * Returns the value for a list of Bro values argument. The argument's type must @@ -332,10 +332,10 @@ private: double double_; const Event* event; const Func* func; - const Frame* frame; + const Frame* frame; int int_; const Val* val; - const ValWrapper* wrapper; + const ValWrapper* wrapper; const val_list* vals; const void* voidp; } arg; @@ -564,7 +564,7 @@ protected: * actually has code to execute for it. By calling this method, the * plugin tells Bro to raise the event even if there's no correspondong * handler; it will then go into HookQueueEvent() just as any other. - * + * * @param handler The event handler being interested in. */ void RequestEvent(EventHandlerPtr handler); @@ -621,11 +621,11 @@ protected: * counting. * * @return If the plugin handled the call, a ValWrapper with the - * processed flag set to true, and a value set on the object with - * a+1 reference count containing the result value to pass back to the - * interpreter. If the plugin did not handle the call, it may either - * return NULL *or* return a ValWrapper with the processed flag set to - * 'false'. + * processed flag set to true, and a value set on the object with + * a+1 reference count containing the result value to pass back to the + * interpreter. If the plugin did not handle the call, it may either + * return NULL *or* return a ValWrapper with the processed flag set to + * 'false'. */ virtual ValWrapper* HookCallFunction(const Func* func, Frame *parent, val_list* args); From 616ed2257226cbbf2bf5d82d1625ed2f800a4510 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Mon, 24 Nov 2014 16:30:12 -0500 Subject: [PATCH 013/256] Small fixes --- src/plugin/Manager.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index eb8681c1cd..1445ed9a63 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -331,7 +331,7 @@ void Manager::InitPreScript() assert(! init); for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); - i != Manager::ActivePluginsInternal()->end(); i++ ) + i != Manager::ActivePluginsInternal()->end(); i++ ) { Plugin* plugin = *i; plugin->DoConfigure(); @@ -346,7 +346,7 @@ void Manager::InitBifs() bif_init_func_map* bifs = BifFilesInternal(); for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); - i != Manager::ActivePluginsInternal()->end(); i++ ) + i != Manager::ActivePluginsInternal()->end(); i++ ) { bif_init_func_map::const_iterator b = bifs->find((*i)->Name()); @@ -363,7 +363,7 @@ void Manager::InitPostScript() assert(init); for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); - i != Manager::ActivePluginsInternal()->end(); i++ ) + i != Manager::ActivePluginsInternal()->end(); i++ ) (*i)->InitPostScript(); } @@ -372,7 +372,7 @@ void Manager::FinishPlugins() assert(init); for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); - i != Manager::ActivePluginsInternal()->end(); i++ ) + i != Manager::ActivePluginsInternal()->end(); i++ ) (*i)->Done(); Manager::ActivePluginsInternal()->clear(); @@ -505,13 +505,13 @@ void Manager::DisableHook(HookType hook, Plugin* plugin) void Manager::RequestEvent(EventHandlerPtr handler, Plugin* plugin) { DBG_LOG(DBG_PLUGINS, "Plugin %s requested event %s", - plugin->Name().c_str(), handler->Name()); + plugin->Name().c_str(), handler->Name()); handler->SetGenerateAlways(); } void Manager::RequestBroObjDtor(BroObj* obj, Plugin* plugin) { - obj->NotifyPluginsOnDtor(); + obj->NotifyPluginsOnDtor(); } int Manager::HookLoadFile(const string& file) @@ -566,14 +566,14 @@ std::pair Manager::HookCallFunction(const Func* func, Frame* parent, if ( HavePluginForHook(META_HOOK_PRE) ) { args.push_back(HookArgument(func)); - args.push_back(HookArgument(parent)); + args.push_back(HookArgument(parent)); args.push_back(HookArgument(vargs)); MetaHookPre(HOOK_CALL_FUNCTION, args); } hook_list* l = hooks[HOOK_CALL_FUNCTION]; - std::pair v; + std::pair v = std::pair(NULL, false); if ( l ) for ( hook_list::iterator i = l->begin(); i != l->end(); ++i ) @@ -583,10 +583,10 @@ std::pair Manager::HookCallFunction(const Func* func, Frame* parent, v = p->HookCallFunction(func, parent, vargs); if ( v.second ) - { + { break; } - } + } if ( HavePluginForHook(META_HOOK_POST) ) MetaHookPost(HOOK_CALL_FUNCTION, args, HookArgument(v)); @@ -674,7 +674,7 @@ void Manager::HookBroObjDtor(void* obj) const { HookArgumentList args; - if ( HavePluginForHook(META_HOOK_PRE) ) + if ( HavePluginForHook(META_HOOK_PRE) ) { args.push_back(obj); MetaHookPre(HOOK_BRO_OBJ_DTOR, args); From cda7c93704ff3ea7201cd17af19759efdc9dd491 Mon Sep 17 00:00:00 2001 From: Gilbert Clark Date: Mon, 24 Nov 2014 16:35:26 -0500 Subject: [PATCH 014/256] More small fixes --- src/plugin/Manager.cc | 8 ++++---- src/plugin/Plugin.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index 1445ed9a63..c63c47dfd0 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -583,11 +583,11 @@ std::pair Manager::HookCallFunction(const Func* func, Frame* parent, v = p->HookCallFunction(func, parent, vargs); if ( v.second ) - { + { break; - } - } - + } + } + if ( HavePluginForHook(META_HOOK_POST) ) MetaHookPost(HOOK_CALL_FUNCTION, args, HookArgument(v)); diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index a54829d883..0c2d2dba40 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -293,7 +293,7 @@ int Plugin::HookLoadFile(const std::string& file, const std::string& ext) std::pair Plugin::HookCallFunction(const Func* func, Frame *parent, val_list* args) { - std::pair result(NULL, false); + std::pair result(NULL, false); return result; } From 3ed6dd558518c2de64c83c3936f8df88b6583392 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Sat, 27 Dec 2014 17:19:43 -0600 Subject: [PATCH 015/256] A bit of code cleanup. --- src/analyzer/protocol/ssh/ssh-analyzer.pac | 55 ++++---- src/analyzer/protocol/ssh/ssh-protocol.pac | 157 +++++++++------------ 2 files changed, 99 insertions(+), 113 deletions(-) diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index e4dd71bc39..da940fffed 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -1,36 +1,49 @@ -# Generated by binpac_quickstart - refine flow SSH_Flow += { function proc_ssh_version(msg: SSH_Version): bool %{ if ( ssh_client_version && ${msg.is_orig } ) - BifEvent::generate_ssh_client_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), bytestring_to_val(${msg.version})); - else if ( ssh_server_version ) - BifEvent::generate_ssh_server_version(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), bytestring_to_val(${msg.version})); + { + BifEvent::generate_ssh_client_version(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${msg.version})); + } + else if ( ssh_server_version ) + { + BifEvent::generate_ssh_server_version(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${msg.version})); + } return true; %} function proc_ssh_kexinit(msg: SSH_KEXINIT): bool %{ if ( ssh_server_capabilities ) - BifEvent::generate_ssh_server_capabilities(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - bytestring_to_val(${msg.kex_algorithms}), bytestring_to_val(${msg.server_host_key_algorithms}), - bytestring_to_val(${msg.encryption_algorithms_client_to_server}), - bytestring_to_val(${msg.encryption_algorithms_server_to_client}), - bytestring_to_val(${msg.mac_algorithms_client_to_server}), - bytestring_to_val(${msg.mac_algorithms_server_to_client}), - bytestring_to_val(${msg.compression_algorithms_client_to_server}), - bytestring_to_val(${msg.compression_algorithms_server_to_client}), - bytestring_to_val(${msg.languages_client_to_server}), - bytestring_to_val(${msg.languages_server_to_client})); + { + BifEvent::generate_ssh_server_capabilities(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${msg.kex_algorithms.val}), + bytestring_to_val(${msg.server_host_key_algorithms.val}), + bytestring_to_val(${msg.encryption_algorithms_client_to_server.val}), + bytestring_to_val(${msg.encryption_algorithms_server_to_client.val}), + bytestring_to_val(${msg.mac_algorithms_client_to_server.val}), + bytestring_to_val(${msg.mac_algorithms_server_to_client.val}), + bytestring_to_val(${msg.compression_algorithms_client_to_server.val}), + bytestring_to_val(${msg.compression_algorithms_server_to_client.val}), + bytestring_to_val(${msg.languages_client_to_server.val}), + bytestring_to_val(${msg.languages_server_to_client.val})); + } return true; %} function proc_ssh_server_host_key(key: bytestring): bool %{ if ( ssh_server_host_key ) - BifEvent::generate_ssh_server_host_key(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), - bytestring_to_val(${key})); + { + BifEvent::generate_ssh_server_host_key(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${key})); + } return true; %} @@ -40,12 +53,6 @@ refine flow SSH_Flow += { return true; %} - function debug(loc: uint8): bool - %{ - printf("DEBUG: %d", loc); - return true; - %} - }; refine typeattr SSH_Version += &let { @@ -61,5 +68,5 @@ refine typeattr SSH_DH_GEX_REPLY += &let { }; refine typeattr SSH_Message += &let { - proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_MSG_NEWKEYS); + proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH2_MSG_NEWKEYS); }; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index 03f47fd67a..d14af0a663 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -5,43 +5,43 @@ enum state { }; enum message_id { - SSH_MSG_DISCONNECT = 1, - SSH_MSG_IGNORE = 2, - SSH_MSG_UNIMPLEMENTED = 3, - SSH_MSG_DEBUG = 4, - SSH_MSG_SERVICE_REQUEST = 5, - SSH_MSG_SERVICE_ACCEPT = 6, - SSH_MSG_KEXINIT = 20, - SSH_MSG_NEWKEYS = 21, - SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, - SSH_MSG_KEX_DH_GEX_GROUP = 31, - SSH_MSG_KEX_DH_GEX_INIT = 32, - SSH_MSG_KEX_DH_GEX_REPLY = 33, - SSH_MSG_KEX_DH_GEX_REQUEST = 34, - SSH_MSG_USERAUTH_REQUEST = 50, - SSH_MSG_USERAUTH_FAILURE = 51, - SSH_MSG_USERAUTH_SUCCESS = 52, - SSH_MSG_USERAUTH_BANNER = 53, - SSH_MSG_GLOBAL_REQUEST = 80, - SSH_MSG_REQUEST_SUCCESS = 81, - SSH_MSG_REQUEST_FAILURE = 82, - SSH_MSG_CHANNEL_OPEN = 90, - SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91, - SSH_MSG_CHANNEL_OPEN_FAILURE = 92, - SSH_MSG_CHANNEL_WINDOW_ADJUST = 93, - SSH_MSG_CHANNEL_DATA = 94, - SSH_MSG_CHANNEL_EXTENDED_DATA = 95, - SSH_MSG_CHANNEL_EOF = 96, - SSH_MSG_CHANNEL_CLOSE = 97, - SSH_MSG_CHANNEL_REQUEST = 98, - SSH_MSG_CHANNEL_SUCCESS = 99, - SSH_MSG_CHANNEL_FAILURE = 100, + SSH2_MSG_DISCONNECT = 1, + SSH2_MSG_IGNORE = 2, + SSH2_MSG_UNIMPLEMENTED = 3, + SSH2_MSG_DEBUG = 4, + SSH2_MSG_SERVICE_REQUEST = 5, + SSH2_MSG_SERVICE_ACCEPT = 6, + SSH2_MSG_KEXINIT = 20, + SSH2_MSG_NEWKEYS = 21, + SSH2_MSG_KEX_DH_GEX_REQUEST_OLD = 30, + SSH2_MSG_KEX_DH_GEX_GROUP = 31, + SSH2_MSG_KEX_DH_GEX_INIT = 32, + SSH2_MSG_KEX_DH_GEX_REPLY = 33, + SSH2_MSG_KEX_DH_GEX_REQUEST = 34, + SSH2_MSG_USERAUTH_REQUEST = 50, + SSH2_MSG_USERAUTH_FAILURE = 51, + SSH2_MSG_USERAUTH_SUCCESS = 52, + SSH2_MSG_USERAUTH_BANNER = 53, + SSH2_MSG_GLOBAL_REQUEST = 80, + SSH2_MSG_REQUEST_SUCCESS = 81, + SSH2_MSG_REQUEST_FAILURE = 82, + SSH2_MSG_CHANNEL_OPEN = 90, + SSH2_MSG_CHANNEL_OPEN_CONFIRMATION = 91, + SSH2_MSG_CHANNEL_OPEN_FAILURE = 92, + SSH2_MSG_CHANNEL_WINDOW_ADJUST = 93, + SSH2_MSG_CHANNEL_DATA = 94, + SSH2_MSG_CHANNEL_EXTENDED_DATA = 95, + SSH2_MSG_CHANNEL_EOF = 96, + SSH2_MSG_CHANNEL_CLOSE = 97, + SSH2_MSG_CHANNEL_REQUEST = 98, + SSH2_MSG_CHANNEL_SUCCESS = 99, + SSH2_MSG_CHANNEL_FAILURE = 100, }; type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { - VERSION_EXCHANGE -> version: SSH_Version(is_orig); - KEY_EXCHANGE_CLEARTEXT -> kex: SSH_Key_Exchange(is_orig); - ENCRYPTED -> ciphertext: bytestring &length=1 &transient; + VERSION_EXCHANGE -> version: SSH_Version(is_orig); + KEY_EXCHANGE_CLEARTEXT -> kex: SSH_Key_Exchange(is_orig); + ENCRYPTED -> ciphertext: bytestring &length=1 &transient; } &byteorder=bigendian; type SSH_Version(is_orig: bool) = record { @@ -51,7 +51,7 @@ type SSH_Version(is_orig: bool) = record { }; type SSH_Key_Exchange_Header(is_orig: bool) = record { - packet_length: uint32; + packet_length : uint32; padding_length: uint8; } &length=5; @@ -61,89 +61,68 @@ type SSH_Key_Exchange(is_orig: bool) = record { pad : bytestring &length=header.padding_length; }; -type SSH_Payload_Header(length: uint32) = record { +type SSH_Payload_Header = record { message_type: uint8; } &length=1; type SSH_Payload(is_orig: bool, packet_length: uint32) = record { - header: SSH_Payload_Header(packet_length); + header: SSH_Payload_Header; message: SSH_Message(is_orig, header.message_type, packet_length); }; type SSH_Message(is_orig: bool, msg_type: uint8, packet_length: uint32) = case msg_type of { - SSH_MSG_KEXINIT -> kexinit: SSH_KEXINIT(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(is_orig, packet_length); - SSH_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(is_orig, packet_length); - SSH_MSG_NEWKEYS -> new_keys: bytestring &length=packet_length; + SSH2_MSG_KEXINIT -> kexinit: SSH_KEXINIT(packet_length); + SSH2_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(packet_length); + SSH2_MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(packet_length); + SSH2_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(packet_length); + SSH2_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(packet_length); + SSH2_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(packet_length); + SSH2_MSG_NEWKEYS -> new_keys: bytestring &length=packet_length; } &let { - detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == SSH_MSG_NEWKEYS); + detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == SSH2_MSG_NEWKEYS); }; -type SSH_KEXINIT(is_orig: bool, length: uint32) = record { - cookie : bytestring &length=16; - kex_algorithms_len : uint32; - kex_algorithms : bytestring &length=kex_algorithms_len; - server_host_key_algorithms_len : uint32; - server_host_key_algorithms : bytestring &length=server_host_key_algorithms_len; - encryption_algorithms_client_to_server_len : uint32; - encryption_algorithms_client_to_server : bytestring &length=encryption_algorithms_client_to_server_len; - encryption_algorithms_server_to_client_len : uint32; - encryption_algorithms_server_to_client : bytestring &length=encryption_algorithms_server_to_client_len; - mac_algorithms_client_to_server_len : uint32; - mac_algorithms_client_to_server : bytestring &length=mac_algorithms_client_to_server_len; - mac_algorithms_server_to_client_len : uint32; - mac_algorithms_server_to_client : bytestring &length=mac_algorithms_server_to_client_len; - compression_algorithms_client_to_server_len : uint32; - compression_algorithms_client_to_server : bytestring &length=compression_algorithms_client_to_server_len; - compression_algorithms_server_to_client_len : uint32; - compression_algorithms_server_to_client : bytestring &length=compression_algorithms_server_to_client_len; - languages_client_to_server_len : uint32; - languages_client_to_server : bytestring &length=languages_client_to_server_len; - languages_server_to_client_len : uint32; - languages_server_to_client : bytestring &length=languages_server_to_client_len; - first_kex_packet_follows : uint8; - reserved : uint32; +type SSH_KEXINIT(length: uint32) = record { + cookie : bytestring &length=16; + kex_algorithms : ssh_string; + server_host_key_algorithms : ssh_string; + encryption_algorithms_client_to_server : ssh_string; + encryption_algorithms_server_to_client : ssh_string; + mac_algorithms_client_to_server : ssh_string; + mac_algorithms_server_to_client : ssh_string; + compression_algorithms_client_to_server : ssh_string; + compression_algorithms_server_to_client : ssh_string; + languages_client_to_server : ssh_string; + languages_server_to_client : ssh_string; + first_kex_packet_follows : uint8; + reserved : uint32; } &length=length; -type SSH_DH_GEX_REQUEST(is_orig: bool, length: uint32) = record { +type SSH_DH_GEX_REQUEST(length: uint32) = record { min: uint32; n : uint32; max: uint32; } &length=12; -type SSH_DH_GEX_REQUEST_OLD(is_orig: bool, length: uint32) = record { +type SSH_DH_GEX_REQUEST_OLD(length: uint32) = record { payload: bytestring &length=length; } &length=length; -type SSH_DH_GEX_GROUP(is_orig: bool, length: uint32) = record { - p: mpint; - g: mpint; +type SSH_DH_GEX_GROUP(length: uint32) = record { + p: ssh_string; + g: ssh_string; } &length=length; -type SSH_DH_GEX_INIT(is_orig: bool, length: uint32) = record { - e: mpint; +type SSH_DH_GEX_INIT(length: uint32) = record { + e: ssh_string; } &length=length; -type SSH_DH_GEX_REPLY(is_orig: bool, length: uint32) = record { +type SSH_DH_GEX_REPLY(length: uint32) = record { k_s : ssh_string; - f : mpint; + f : ssh_string; signature: ssh_string; } &length=length; -#type SSH_NEWKEYS(is_orig: bool, length: uint32) = record { -# blah: ; -#} &let { -# detach: bool = $context.connection.detach(); -#} &length=0; - -type mpint = record { - len: uint32; - val: bytestring &length=len; -}; - type ssh_string = record { len: uint32; val: bytestring &length=len; From 727eada9ac6e92679d5d2bfd3a5ded6c97633051 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Sat, 27 Dec 2014 17:46:42 -0600 Subject: [PATCH 016/256] Move SSH analyzer to new plugin architecture. --- src/analyzer/protocol/ssh/Plugin.cc | 7 ++++++- src/analyzer/protocol/ssh/SSH.cc | 4 ++-- src/analyzer/protocol/ssh/SSH.h | 21 +++++++-------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/analyzer/protocol/ssh/Plugin.cc b/src/analyzer/protocol/ssh/Plugin.cc index 5887b7a2c6..d2e0116b09 100644 --- a/src/analyzer/protocol/ssh/Plugin.cc +++ b/src/analyzer/protocol/ssh/Plugin.cc @@ -1,5 +1,10 @@ // See the file in the main distribution directory for copyright. + +#include "plugin/Plugin.h" + +#include "SSH.h" + namespace plugin { namespace Bro_SSH { @@ -7,7 +12,7 @@ class Plugin : public plugin::Plugin { public: plugin::Configuration Configure() { - AddComponent(new ::analyzer::Component("SSH", ::analyzer::ssh::SSH_Analyzer::Instantiate)); + AddComponent(new ::analyzer::Component("SSH", ::analyzer::SSH::SSH_Analyzer::Instantiate)); plugin::Configuration config; config.name = "Bro::SSH"; diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index c6ac74f5dc..184dbba914 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -1,4 +1,4 @@ -// Generated by binpac_quickstart +// See the file "COPYING" in the main distribution directory for copyright. #include "SSH.h" @@ -72,7 +72,7 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void SSH_Analyzer::Undelivered(int seq, int len, bool orig) +void SSH_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); had_gap = true; diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 4d587b4426..73a5420166 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -1,18 +1,16 @@ +// See the file "COPYING" in the main distribution directory for copyright. + #ifndef ANALYZER_PROTOCOL_SSH_SSH_H #define ANALYZER_PROTOCOL_SSH_SSH_H #include "events.bif.h" - #include "analyzer/protocol/tcp/TCP.h" - #include "ssh_pac.h" namespace analyzer { namespace SSH { -class SSH_Analyzer - -: public tcp::TCP_ApplicationAnalyzer { +class SSH_Analyzer : public tcp::TCP_ApplicationAnalyzer { public: SSH_Analyzer(Connection* conn); @@ -20,20 +18,15 @@ public: // Overriden from 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 Undelivered(uint64 seq, int len, bool orig); + + // Overriden from tcp::TCP_ApplicationAnalyzer. + virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* Instantiate(Connection* conn) { return new SSH_Analyzer(conn); } - static bool Available() - { - return ( ssh_server_version || ssh_client_version || - ssh_auth_successful || ssh_auth_failed || - ssh_server_capabilities || ssh_server_host_key ); - } - protected: binpac::SSH::SSH_Conn* interp; From 5e206ed108e13a31b0829c0c029880007fd8a884 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 6 Jan 2015 20:27:20 -0600 Subject: [PATCH 017/256] Add support for SSH1 --- scripts/base/protocols/ssh/dpd.sig | 11 +- scripts/base/protocols/ssh/main.bro | 55 +++-- src/analyzer/protocol/ssh/SSH.cc | 65 ++++-- src/analyzer/protocol/ssh/SSH.h | 4 +- src/analyzer/protocol/ssh/events.bif | 4 +- src/analyzer/protocol/ssh/ssh-analyzer.pac | 8 +- src/analyzer/protocol/ssh/ssh-protocol.pac | 240 +++++++++++++++------ 7 files changed, 275 insertions(+), 112 deletions(-) diff --git a/scripts/base/protocols/ssh/dpd.sig b/scripts/base/protocols/ssh/dpd.sig index 95e22908ab..e56878275c 100644 --- a/scripts/base/protocols/ssh/dpd.sig +++ b/scripts/base/protocols/ssh/dpd.sig @@ -1,13 +1,6 @@ -signature dpd_ssh_client { +signature dpd_ssh { ip-proto == tcp - payload /^[sS][sS][hH]-/ - requires-reverse-signature dpd_ssh_server + payload /^[sS][sS][hH]-[12]./ enable "ssh" - tcp-state originator } -signature dpd_ssh_server { - ip-proto == tcp - payload /^[sS][sS][hH]-/ - tcp-state responder -} diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index bba3f8ac88..00f387d432 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -12,6 +12,8 @@ export { uid: string &log; ## The connection's 4-tuple of endpoint addresses/ports. id: conn_id &log; + ## SSH major version (1 or 2) + version: count &log; ## Auth result result: string &log &optional; ## Auth method (password, pubkey, etc.) @@ -54,23 +56,36 @@ event bro_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports); } -function determine_auth_method(middle_pkt_len: int, first_pkt_len: int): string +function determine_auth_method(version: int, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int): string { # This is still being tested. # Based on "Analysis for Identifying User Authentication Methods on SSH Connections" # by Satoh, Nakamura, Ikenaga. - if ( middle_pkt_len == 96 ) - return "password"; - if ( middle_pkt_len == 16 ) - return "gssapi"; - if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) - return "challenge-response"; - if ( middle_pkt_len < 256 ) - return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); - if ( first_pkt_len == 16 ) - return "host-based"; - return fmt("pubkey (~%d bits)", (first_pkt_len - 16)*8); + if ( version == 2 ) + { + if ( first_pkt_len == 0 ) + return "none"; + if ( middle_pkt_len == 96 ) + return "password"; + if ( middle_pkt_len == 16 ) + return "gssapi"; + if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) + return "challenge-response"; + if ( middle_pkt_len < 256 ) + return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); + if ( first_pkt_len == 16 ) + return "host-based"; + return fmt("pubkey (~%d bits)", (first_pkt_len - 16)*8); + } + else if ( version == 1 ) + { + if ( first_pkt_len == 0 ) + return "password"; + if ( first_pkt_len >= 96 && first_pkt_len <= 256 ) + return fmt("pubkey (~%d bits)", first_pkt_len * 8); + return fmt("%d %d %d", first_pkt_len, middle_pkt_len, last_pkt_len); + } } event ssh_server_version(c: connection, version: string) @@ -97,33 +112,37 @@ event ssh_client_version(c: connection, version: string) c$ssh = s; } c$ssh$client = version; + if ( version[4] == "1" ) + c$ssh$version = 1; + if ( version[4] == "2" ) + c$ssh$version = 2; } -event ssh_auth_successful(c: connection, middle_pkt_len: int, first_pkt_len: int) +event ssh_auth_successful(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) { print "ssh_auth_successful"; if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "success"; - c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); + c$ssh$method = determine_auth_method(c$ssh$version, last_pkt_len, middle_pkt_len, first_pkt_len); } -event ssh_auth_successful(c: connection, middle_pkt_len: int, first_pkt_len: int) &priority=-5 +event ssh_auth_successful(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) &priority=-5 { c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); } -event ssh_auth_failed(c: connection, middle_pkt_len: int, first_pkt_len: int) +event ssh_auth_failed(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) { print "ssh_auth_failed"; if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) return; c$ssh$result = "failure"; - c$ssh$method = determine_auth_method(middle_pkt_len, first_pkt_len); + c$ssh$method = determine_auth_method(c$ssh$version, last_pkt_len, middle_pkt_len, first_pkt_len); } -event ssh_auth_failed(c: connection, middle_pkt_len: int, first_pkt_len: int) &priority=-5 +event ssh_auth_failed(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) &priority=-5 { c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index 184dbba914..19ca99417c 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -17,6 +17,7 @@ SSH_Analyzer::SSH_Analyzer(Connection* c) { interp = new binpac::SSH::SSH_Conn(this); had_gap = false; + auth_decision_made = false; num_encrypted_packets_seen = 0; initial_client_packet_size = 0; initial_server_packet_size = 0; @@ -68,6 +69,7 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } catch ( const binpac::Exception& e ) { + printf("Binpac exception: %s\n", e.c_msg()); ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); } } @@ -92,17 +94,24 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) else relative_len = len - initial_server_packet_size; - if ( num_encrypted_packets_seen >= 6 ) + if ( !auth_decision_made && ( num_encrypted_packets_seen > 3 ) ) { - int auth_result = AuthResult(relative_len, orig); + int auth_result = AuthResult(relative_len, orig, interp->get_version()); if ( auth_result > 0 ) { + auth_decision_made = true; if ( auth_result == 1 ) - BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), - packet_n_1_size, packet_n_2_size); + BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), + interp->bro_analyzer()->Conn(), + len, + packet_n_1_size, + packet_n_2_size); if ( auth_result == 2 ) - BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), - packet_n_1_size, packet_n_2_size); + BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), + interp->bro_analyzer()->Conn(), + len, + packet_n_1_size, + packet_n_2_size); } } if ( ( num_encrypted_packets_seen >= 2 ) && @@ -111,29 +120,47 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) packet_n_2_is_orig = packet_n_1_is_orig; packet_n_2_size = packet_n_1_size; } - - if ( orig == packet_n_1_is_orig ) + if ( num_encrypted_packets_seen == 0 ) + num_encrypted_packets_seen = 1; + else if ( orig == packet_n_1_is_orig ) packet_n_1_size += len; else { packet_n_1_is_orig = orig; packet_n_1_size = relative_len; - num_encrypted_packets_seen++; + if ( ! ( ( interp->get_version() == binpac::SSH::SSH1 ) && len > 90 ) ) + num_encrypted_packets_seen++; } } -int SSH_Analyzer::AuthResult(int len, bool orig) +int SSH_Analyzer::AuthResult(int len, bool orig, int version) { - if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) - { - printf("Auth result = %d\n", len); - if ( len == -16 ) - return 1; - else if ( len >= 16 && len <= 32 ) - return 2; - return 0; - } + if ( version == binpac::SSH::SSH2 ) + { + if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) + { + if ( len == -16 ) + return 1; + else if ( len >= 16 && len <= 32 ) + return 2; + return 0; + } + } + else if ( version == binpac::SSH::SSH1 ) + { + // On a successful login, the server sends a longer message + if ( !orig && len > 0 ) + { + // To verify a public key, the server sends back a message of the same size + // as the previous one. Ignore that occurrence here. + if ( ! ( packet_n_1_is_orig && ( len == packet_n_1_size ) ) ) + return 1; + } + // If we've seen too many messages without a longer message, treat it as a failure + if ( num_encrypted_packets_seen > 7 ) + return 2; + } return -1; } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 73a5420166..185e83d4de 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -31,11 +31,13 @@ protected: binpac::SSH::SSH_Conn* interp; void ProcessEncrypted(int len, bool orig); - int AuthResult(int len, bool orig); + int AuthResult(int len, bool orig, int version); bool had_gap; // Packet analysis stuff + bool auth_decision_made; + int initial_client_packet_size; int initial_server_packet_size; int num_encrypted_packets_seen; diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 1389b2e0da..1b6b80f8df 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -2,9 +2,9 @@ event ssh_server_version%(c: connection, version: string%); event ssh_client_version%(c: connection, version: string%); -event ssh_auth_successful%(c: connection, middle_packet_len: int, first_packet_len: int%); +event ssh_auth_successful%(c: connection, last_packet_len: int, middle_packet_len: int, first_packet_len: int%); -event ssh_auth_failed%(c: connection, middle_packet_len: int, first_packet_len: int%); +event ssh_auth_failed%(c: connection, last_packet_len: int, middle_packet_len: int, first_packet_len: int%); event ssh_server_capabilities%(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string%); diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index da940fffed..0e627481a4 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -67,6 +67,10 @@ refine typeattr SSH_DH_GEX_REPLY += &let { proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); }; -refine typeattr SSH_Message += &let { - proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH2_MSG_NEWKEYS); +refine typeattr SSH1_Message += &let { + proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_CMSG_SESSION_KEY); +}; + +refine typeattr SSH2_Message += &let { + proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == MSG_NEWKEYS); }; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index d14af0a663..3e1ec95ecc 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -1,41 +1,95 @@ +enum version { + SSH1 = 1, + SSH2 = 2, + UNK = 3, +}; + enum state { VERSION_EXCHANGE = 0, KEY_EXCHANGE_CLEARTEXT = 1, ENCRYPTED = 2, }; -enum message_id { - SSH2_MSG_DISCONNECT = 1, - SSH2_MSG_IGNORE = 2, - SSH2_MSG_UNIMPLEMENTED = 3, - SSH2_MSG_DEBUG = 4, - SSH2_MSG_SERVICE_REQUEST = 5, - SSH2_MSG_SERVICE_ACCEPT = 6, - SSH2_MSG_KEXINIT = 20, - SSH2_MSG_NEWKEYS = 21, - SSH2_MSG_KEX_DH_GEX_REQUEST_OLD = 30, - SSH2_MSG_KEX_DH_GEX_GROUP = 31, - SSH2_MSG_KEX_DH_GEX_INIT = 32, - SSH2_MSG_KEX_DH_GEX_REPLY = 33, - SSH2_MSG_KEX_DH_GEX_REQUEST = 34, - SSH2_MSG_USERAUTH_REQUEST = 50, - SSH2_MSG_USERAUTH_FAILURE = 51, - SSH2_MSG_USERAUTH_SUCCESS = 52, - SSH2_MSG_USERAUTH_BANNER = 53, - SSH2_MSG_GLOBAL_REQUEST = 80, - SSH2_MSG_REQUEST_SUCCESS = 81, - SSH2_MSG_REQUEST_FAILURE = 82, - SSH2_MSG_CHANNEL_OPEN = 90, - SSH2_MSG_CHANNEL_OPEN_CONFIRMATION = 91, - SSH2_MSG_CHANNEL_OPEN_FAILURE = 92, - SSH2_MSG_CHANNEL_WINDOW_ADJUST = 93, - SSH2_MSG_CHANNEL_DATA = 94, - SSH2_MSG_CHANNEL_EXTENDED_DATA = 95, - SSH2_MSG_CHANNEL_EOF = 96, - SSH2_MSG_CHANNEL_CLOSE = 97, - SSH2_MSG_CHANNEL_REQUEST = 98, - SSH2_MSG_CHANNEL_SUCCESS = 99, - SSH2_MSG_CHANNEL_FAILURE = 100, +enum ssh1_message_id { + SSH_MSG_NONE = 0, + SSH_MSG_DISCONNECT = 1, + SSH_SMSG_PUBLIC_KEY = 2, + SSH_CMSG_SESSION_KEY = 3, + SSH_CMSG_USER = 4, + SSH_CMSG_AUTH_RHOSTS = 5, + SSH_CMSG_AUTH_RSA = 6, + SSH_SMSG_AUTH_RSA_CHALLENGE = 7, + SSH_CMSG_AUTH_RSA_RESPONSE = 8, + SSH_CMSG_AUTH_PASSWORD = 9, + SSH_CMSG_REQUEST_PTY = 10, + SSH_CMSG_WINDOW_SIZE = 11, + SSH_CMSG_EXEC_SHELL = 12, + SSH_CMSG_EXEC_CMD = 13, + SSH_SMSG_SUCCESS = 14, + SSH_SMSG_FAILURE = 15, + SSH_CMSG_STDIN_DATA = 16, + SSH_SMSG_STDOUT_DATA = 17, + SSH_SMSG_STDERR_DATA = 18, + SSH_CMSG_EOF = 19, + SSH_SMSG_EXITSTATUS = 20, + SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 21, + SSH_MSG_CHANNEL_OPEN_FAILURE = 22, + SSH_MSG_CHANNEL_DATA = 23, + SSH_MSG_CHANNEL_CLOSE = 24, + SSH_MSG_CHANNEL_CLOSE_CONFIRMATION = 25, + SSH_CMSG_X11_REQUEST_FORWARDING_OLD = 26, + SSH_SMSG_X11_OPEN = 27, + SSH_CMSG_PORT_FORWARD_REQUEST = 28, + SSH_MSG_PORT_OPEN = 29, + SSH_CMSG_AGENT_REQUEST_FORWARDING = 30, + SSH_SMSG_AGENT_OPEN = 31, + SSH_MSG_IGNORE = 32, + SSH_CMSG_EXIT_CONFIRMATION = 33, + SSH_CMSG_X11_REQUEST_FORWARDING = 34, + SSH_CMSG_AUTH_RHOSTS_RSA = 35, + SSH_MSG_DEBUG = 36, + SSH_CMSG_REQUEST_COMPRESSION = 37, + SSH_CMSG_MAX_PACKET_SIZE = 38, + SSH_CMSG_AUTH_TIS = 39, + SSH_SMSG_AUTH_TIS_CHALLENGE = 40, + SSH_CMSG_AUTH_TIS_RESPONSE = 41, + SSH_CMSG_AUTH_KERBEROS = 42, + SSH_SMSG_AUTH_KERBEROS_RESPONSE = 43, + SSH_CMSG_HAVE_KERBEROS_TGT = 44, +}; + +enum ssh2_message_id { + MSG_DISCONNECT = 1, + MSG_IGNORE = 2, + MSG_UNIMPLEMENTED = 3, + MSG_DEBUG = 4, + MSG_SERVICE_REQUEST = 5, + MSG_SERVICE_ACCEPT = 6, + MSG_KEXINIT = 20, + MSG_NEWKEYS = 21, + MSG_KEX_DH_GEX_REQUEST_OLD = 30, + MSG_KEX_DH_GEX_GROUP = 31, + MSG_KEX_DH_GEX_INIT = 32, + MSG_KEX_DH_GEX_REPLY = 33, + MSG_KEX_DH_GEX_REQUEST = 34, + MSG_USERAUTH_REQUEST = 50, + MSG_USERAUTH_FAILURE = 51, + MSG_USERAUTH_SUCCESS = 52, + MSG_USERAUTH_BANNER = 53, + MSG_GLOBAL_REQUEST = 80, + MSG_REQUEST_SUCCESS = 81, + MSG_REQUEST_FAILURE = 82, + MSG_CHANNEL_OPEN = 90, + MSG_CHANNEL_OPEN_CONFIRMATION = 91, + MSG_CHANNEL_OPEN_FAILURE = 92, + MSG_CHANNEL_WINDOW_ADJUST = 93, + MSG_CHANNEL_DATA = 94, + MSG_CHANNEL_EXTENDED_DATA = 95, + MSG_CHANNEL_EOF = 96, + MSG_CHANNEL_CLOSE = 97, + MSG_CHANNEL_REQUEST = 98, + MSG_CHANNEL_SUCCESS = 99, + MSG_CHANNEL_FAILURE = 100, }; type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { @@ -46,40 +100,76 @@ type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { type SSH_Version(is_orig: bool) = record { version: bytestring &oneline; + pad: bytestring &length=0 &transient; } &let { - update_state: bool = $context.connection.update_state(KEY_EXCHANGE_CLEARTEXT, is_orig); + update_state : bool = $context.connection.update_state(KEY_EXCHANGE_CLEARTEXT, is_orig); + update_version: bool = $context.connection.update_version(version, is_orig); }; -type SSH_Key_Exchange_Header(is_orig: bool) = record { - packet_length : uint32; +type SSH_Key_Exchange(is_orig: bool) = case $context.connection.get_version() of { + SSH1 -> ssh1_msg: SSH1_Key_Exchange(is_orig); + SSH2 -> ssh2_msg: SSH2_Key_Exchange(is_orig); +}; + +type SSH1_Key_Exchange(is_orig: bool) = record { + packet_length: uint32; + pad_fill : bytestring &length = 8 - (packet_length % 8); + msg_type : uint8; + message : SSH1_Message(is_orig, msg_type, packet_length-5); + crc : uint32; +} &length = packet_length + 4 + 8 - (packet_length % 8); + +type SSH2_Key_Exchange_Header = record { + packet_length : uint32; padding_length: uint8; -} &length=5; - -type SSH_Key_Exchange(is_orig: bool) = record { - header : SSH_Key_Exchange_Header(is_orig); - payload: SSH_Payload(is_orig, header.packet_length - header.padding_length - 2); - pad : bytestring &length=header.padding_length; -}; - -type SSH_Payload_Header = record { - message_type: uint8; -} &length=1; - -type SSH_Payload(is_orig: bool, packet_length: uint32) = record { - header: SSH_Payload_Header; - message: SSH_Message(is_orig, header.message_type, packet_length); -}; - -type SSH_Message(is_orig: bool, msg_type: uint8, packet_length: uint32) = case msg_type of { - SSH2_MSG_KEXINIT -> kexinit: SSH_KEXINIT(packet_length); - SSH2_MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(packet_length); - SSH2_MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(packet_length); - SSH2_MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(packet_length); - SSH2_MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(packet_length); - SSH2_MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(packet_length); - SSH2_MSG_NEWKEYS -> new_keys: bytestring &length=packet_length; + msg_type : uint8; } &let { - detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == SSH2_MSG_NEWKEYS); + payload_length: uint32 = packet_length - padding_length - 2; +} &length=6; + +type SSH2_Key_Exchange(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH2_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH1_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_SMSG_PUBLIC_KEY -> public_key: SSH1_PUBLIC_KEY(length); + SSH_CMSG_SESSION_KEY -> session_key: SSH1_SESSION_KEY(length); +} &let { + detach: bool = $context.connection.update_state(ENCRYPTED, is_orig); +}; + +type SSH1_PUBLIC_KEY(length: uint32) = record { + cookie : bytestring &length=8; + server_key : uint32; + server_key_p : ssh1_mp_int; + server_key_e : ssh1_mp_int; + host_key : uint32; + host_key_p : ssh1_mp_int; + host_key_e : ssh1_mp_int; + flags : uint32; + supported_ciphers : uint32; + supported_auths : uint32; +} &length=length; + +type SSH1_SESSION_KEY(length: uint32) = record { + cipher : uint8; + cookie : bytestring &length=8; + session_key : ssh1_mp_int; + flags : uint32; +} &length=length; + +type SSH2_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + MSG_KEXINIT -> kexinit: SSH_KEXINIT(length); + MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(length); + MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(length); + MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(length); + MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(length); + MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(length); + MSG_NEWKEYS -> new_keys: bytestring &length=length; +} &let { + detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == MSG_NEWKEYS); }; type SSH_KEXINIT(length: uint32) = record { @@ -123,6 +213,11 @@ type SSH_DH_GEX_REPLY(length: uint32) = record { signature: ssh_string; } &length=length; +type ssh1_mp_int = record { + len: uint16; + val: bytestring &length=(len+7)/8; +}; + type ssh_string = record { len: uint32; val: bytestring &length=len; @@ -132,19 +227,25 @@ refine connection SSH_Conn += { %member{ int state_up_; int state_down_; + int version_; %} %init{ state_up_ = VERSION_EXCHANGE; state_down_ = VERSION_EXCHANGE; + version_ = UNK; %} function get_state(is_orig: bool): int %{ if ( is_orig ) + { return state_up_; + } else + { return state_down_; + } %} function update_state(s: state, is_orig: bool): bool @@ -156,4 +257,21 @@ refine connection SSH_Conn += { return true; %} + function get_version(): int + %{ + return version_; + %} + + function update_version(v: bytestring, is_orig: bool): bool + %{ + if ( is_orig && ( v.length() >= 4 ) ) + { + if ( v[4] == '2' ) + version_ = SSH2; + if ( v[4] == '1' ) + version_ = SSH1; + } + return true; + %} + }; \ No newline at end of file From 245bd07af7d58af2fc3772a7a3363a573db7a6fa Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 6 Jan 2015 21:23:18 -0600 Subject: [PATCH 018/256] Add host key support for SSH1. --- scripts/base/protocols/ssh/main.bro | 21 +++++++++++++++++---- src/analyzer/protocol/ssh/events.bif | 4 +++- src/analyzer/protocol/ssh/ssh-analyzer.pac | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 00f387d432..24e11779b7 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -186,11 +186,24 @@ event connection_state_remove(c: connection) &priority=-5 Log::write(SSH::LOG, c$ssh); } +function generate_fingerprint(c: connection, key: string) + { + local lx = str_split(md5_hash(key), vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)); + lx[0] = ""; + c$ssh$host_key = sub(join_string_vec(lx, ":"), /:/, ""); + } + +event ssh1_server_host_key(c: connection, p: string, e: string) + { + if ( !c?$ssh ) + return; + generate_fingerprint(c, e + p); + } + event ssh_server_host_key(c: connection, key: string) { if ( !c?$ssh ) return; - local lx = str_split(md5_hash(key), vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)); - lx[0] = ""; - c$ssh$host_key = sub(join_string_vec(lx, ":"), /:/, ""); - } \ No newline at end of file + generate_fingerprint(c, key); + } + diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 1b6b80f8df..7505dfd6db 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -8,4 +8,6 @@ event ssh_auth_failed%(c: connection, last_packet_len: int, middle_packet_len: i event ssh_server_capabilities%(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string%); -event ssh_server_host_key%(c: connection, key: string%); \ No newline at end of file +event ssh_server_host_key%(c: connection, key: string%); + +event ssh1_server_host_key%(c: connection, p: string, e: string%); \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 0e627481a4..1af96a4c5c 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -47,6 +47,18 @@ refine flow SSH_Flow += { return true; %} + function proc_ssh1_server_host_key(p: bytestring, e: bytestring): bool + %{ + if ( ssh_server_host_key ) + { + BifEvent::generate_ssh1_server_host_key(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${p}), + bytestring_to_val(${e})); + } + return true; + %} + function proc_newkeys(): bool %{ connection()->bro_analyzer()->ProtocolConfirmation(); @@ -73,4 +85,8 @@ refine typeattr SSH1_Message += &let { refine typeattr SSH2_Message += &let { proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == MSG_NEWKEYS); +}; + +refine typeattr SSH1_PUBLIC_KEY += &let { + proc: bool = $context.flow.proc_ssh1_server_host_key(host_key_p.val, host_key_e.val); }; \ No newline at end of file From 7120098ca2eef0449c383dbf57cc0a26b6303d11 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 8 Jan 2015 16:43:07 -0600 Subject: [PATCH 019/256] Add support for building/linking broker within bro The new --enable-broker flag can be used to toggle the use of Broker, which also implies building with -std=c++11, though nothing makes use of these features at the moment. --- .gitmodules | 3 +++ CMakeLists.txt | 7 +++++++ aux/broker | 1 + cmake | 2 +- configure | 15 +++++++++++++++ 5 files changed, 27 insertions(+), 1 deletion(-) create mode 160000 aux/broker diff --git a/.gitmodules b/.gitmodules index 24375ce23d..91f39e3d04 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "aux/plugins"] path = aux/plugins url = git://git.bro.org/bro-plugins +[submodule "aux/broker"] + path = aux/broker + url = git://git.bro.org/broker diff --git a/CMakeLists.txt b/CMakeLists.txt index c0ff6c09d4..1f0fcf8d07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,6 +177,12 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) ######################################################################## ## Recurse on sub-directories +if ( ENABLE_BROKER ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + add_subdirectory(aux/broker) + set(brodeps ${brodeps} broker) +endif () + add_subdirectory(src) add_subdirectory(scripts) add_subdirectory(doc) @@ -224,6 +230,7 @@ message( "\nCXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BuildType}}" "\nCPP: ${CMAKE_CXX_COMPILER}" "\n" + "\nBroker: ${ENABLE_BROKER}" "\nBroccoli: ${INSTALL_BROCCOLI}" "\nBroctl: ${INSTALL_BROCTL}" "\nAux. Tools: ${INSTALL_AUX_TOOLS}" diff --git a/aux/broker b/aux/broker new file mode 160000 index 0000000000..a1b51def07 --- /dev/null +++ b/aux/broker @@ -0,0 +1 @@ +Subproject commit a1b51def07cfb191d0a83a78c7102560740dbcb3 diff --git a/cmake b/cmake index 1316c07f70..c2057b7f15 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 1316c07f7059647b6c4a496ea36e4b83bb5d8f0f +Subproject commit c2057b7f15dedc27641a50312384505ce4f2112c diff --git a/configure b/configure index 2b1c568b26..6235aba7dd 100755 --- a/configure +++ b/configure @@ -41,6 +41,8 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --enable-perftools-debug use Google's perftools for debugging --enable-jemalloc link against jemalloc --enable-ruby build ruby bindings for broccoli (deprecated) + --enable-broker enable use of the Broker communication library + (requires C++ Actor Framework and C++11) --disable-broccoli don't build or install the Broccoli library --disable-broctl don't install Broctl --disable-auxtools don't build or install auxiliary tools @@ -55,6 +57,8 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --with-flex=PATH path to flex executable --with-bison=PATH path to bison executable --with-perl=PATH path to perl executable + --with-libcaf=PATH path to C++ Actor Framework installation + (a required Broker dependency) Optional Packages in Non-Standard Locations: --with-geoip=PATH path to the libGeoIP install root @@ -67,6 +71,8 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --with-ruby-lib=PATH path to ruby library --with-ruby-inc=PATH path to ruby headers --with-swig=PATH path to SWIG executable + --with-rocksdb=PATH path to RocksDB installation + (an optional Broker dependency) Packaging Options (for developers): --binary-package toggle special logic for binary packaging @@ -176,6 +182,9 @@ while [ $# -ne 0 ]; do --enable-jemalloc) append_cache_entry ENABLE_JEMALLOC BOOL true ;; + --enable-broker) + append_cache_entry ENABLE_BROKER BOOL true + ;; --disable-broccoli) append_cache_entry INSTALL_BROCCOLI BOOL false ;; @@ -248,6 +257,12 @@ while [ $# -ne 0 ]; do --with-swig=*) append_cache_entry SWIG_EXECUTABLE PATH $optarg ;; + --with-libcaf=*) + append_cache_entry LIBCAF_ROOT_DIR PATH $optarg + ;; + --with-rocksdb=*) + append_cache_entry ROCKSDB_ROOT_DIR PATH $optarg + ;; --binary-package) append_cache_entry BINARY_PACKAGING_MODE BOOL true ;; From 05ecac24971cba58f58c28704cdb2b77bee2dbf1 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 13 Jan 2015 12:02:31 -0500 Subject: [PATCH 020/256] Refactored the SSH analyzer. Added supported for algorithm detection and more key exchange message types. --- scripts/base/init-bare.bro | 37 ++ scripts/base/protocols/ssh/dpd.sig | 11 +- scripts/base/protocols/ssh/main.bro | 251 ++++++----- src/analyzer/protocol/ssh/CMakeLists.txt | 1 + src/analyzer/protocol/ssh/SSH.cc | 147 +++--- src/analyzer/protocol/ssh/SSH.h | 12 +- src/analyzer/protocol/ssh/events.bif | 8 +- src/analyzer/protocol/ssh/ssh-analyzer.pac | 98 +++- src/analyzer/protocol/ssh/ssh-protocol.pac | 502 ++++++++++++++++----- src/analyzer/protocol/ssh/ssh.pac | 1 + src/analyzer/protocol/ssh/types.bif | 5 + 11 files changed, 745 insertions(+), 328 deletions(-) create mode 100644 src/analyzer/protocol/ssh/types.bif diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index efce524fc5..f71ebe7718 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2222,6 +2222,43 @@ export { const heartbeat_interval = 1.0 secs &redef; } +module SSH; + +export { + ## SSH Capability record + type Capabilities: record { + ## Key exchange algorithms + kex_algorithms : string_vec; + ## The algorithms supported for the server host key + server_host_key_algorithms : string_vec; + ## Acceptable symmetric encryption algorithms for c->s, + ## in order of preference + encryption_algorithms_client_to_server : string_vec; + ## Acceptable symmetric encryption algorithms for s->c, + ## in order of preference + encryption_algorithms_server_to_client : string_vec; + ## Acceptable MAC algorithms for c->s, + ## in order of preference + mac_algorithms_client_to_server : string_vec; + + ## Acceptable MAC algorithms for s->c, + ## in order of preference + mac_algorithms_server_to_client : string_vec; + ## Acceptable compression algorithms for c->s, + ## in order of preference + compression_algorithms_client_to_server : string_vec; + ## Acceptable compression algorithms for c->s, + ## in order of preference + compression_algorithms_server_to_client : string_vec; + ## Language tags in order of preference for c->s + languages_client_to_server : string_vec &optional; + ## Language tags in order of preference for s->c + languages_server_to_client : string_vec &optional; + ## Are these the capabilities of the server? + is_server : bool; + }; +} + module GLOBAL; ## An NTP message. diff --git a/scripts/base/protocols/ssh/dpd.sig b/scripts/base/protocols/ssh/dpd.sig index e56878275c..816e7929b3 100644 --- a/scripts/base/protocols/ssh/dpd.sig +++ b/scripts/base/protocols/ssh/dpd.sig @@ -1,6 +1,13 @@ -signature dpd_ssh { +signature dpd_ssh_client { ip-proto == tcp - payload /^[sS][sS][hH]-[12]./ + payload /^[sS][sS][hH]-[12]\./ + requires-reverse-signature dpd_ssh_server enable "ssh" + tcp-state originator } +signature dpd_ssh_server { + ip-proto == tcp + payload /^[sS][sS][hH]-[12]\./ + tcp-state responder +} \ No newline at end of file diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 24e11779b7..8db2e4d023 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -15,22 +15,40 @@ export { ## SSH major version (1 or 2) version: count &log; ## Auth result - result: string &log &optional; - ## Auth method (password, pubkey, etc.) - method: string &log &optional; + auth_success: bool &log &optional; + + ## Auth details + auth_details: string &log &optional; ## Direction of the connection. If the client was a local host ## logging into an external host, this would be OUTBOUND. INBOUND ## would be set for the opposite situation. ## TODO: handle local-local and remote-remote better. direction: Direction &log &optional; + ## The encryption algorithm in use + cipher_alg: string &log &optional; + ## The signing (MAC) algorithm in use + mac_alg: string &log &optional; + ## The compression algorithm in use + compression_alg: string &log &optional; + ## The key exchange algorithm in use + kex_alg: string &log &optional; + + ## The server host key's algorithm + host_key_alg: string &log &optional; + ## The server's key fingerprint + host_key: string &log &optional; ## The client's version string client: string &log &optional; ## The server's version string server: string &log &optional; - ## The server's key fingerprint - host_key: string &log &optional; + ## This connection has been logged (internal use) logged: bool &default=F; + ## Number of failures seen (internal use) + num_failures: count &default=0; + ## Store capabilities from the first host for + ## comparison with the second (internal use) + capabilities: Capabilities &optional; }; ## If true, we tell the event engine to not look at further data @@ -48,146 +66,167 @@ redef record connection += { ssh: Info &optional; }; -const ports = { 22/tcp }; - event bro_init() &priority=5 { Log::create_stream(SSH::LOG, [$columns=Info, $ev=log_ssh]); - Analyzer::register_for_ports(Analyzer::ANALYZER_SSH, ports); } -function determine_auth_method(version: int, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int): string - { - # This is still being tested. - # Based on "Analysis for Identifying User Authentication Methods on SSH Connections" - # by Satoh, Nakamura, Ikenaga. - if ( version == 2 ) - { - if ( first_pkt_len == 0 ) - return "none"; - if ( middle_pkt_len == 96 ) - return "password"; - if ( middle_pkt_len == 16 ) - return "gssapi"; - if ( ( middle_pkt_len == 32 ) && ( first_pkt_len == 0 || first_pkt_len == 48 ) ) - return "challenge-response"; - if ( middle_pkt_len < 256 ) - return fmt("unknown (mid=%d, first=%d)", middle_pkt_len, first_pkt_len); - if ( first_pkt_len == 16 ) - return "host-based"; - return fmt("pubkey (~%d bits)", (first_pkt_len - 16)*8); - } - else if ( version == 1 ) - { - if ( first_pkt_len == 0 ) - return "password"; - if ( first_pkt_len >= 96 && first_pkt_len <= 256 ) - return fmt("pubkey (~%d bits)", first_pkt_len * 8); - return fmt("%d %d %d", first_pkt_len, middle_pkt_len, last_pkt_len); - } - } +function init_record(c: connection) + { + local s: SSH::Info; + s$ts = network_time(); + s$uid = c$uid; + s$id = c$id; + c$ssh = s; + } + event ssh_server_version(c: connection, version: string) { if ( !c?$ssh ) - { - local s: SSH::Info; - s$ts = network_time(); - s$uid = c$uid; - s$id = c$id; - c$ssh = s; - } + init_record(c); + c$ssh$server = version; } event ssh_client_version(c: connection, version: string) { if ( !c?$ssh ) - { - local s: SSH::Info; - s$ts = network_time(); - s$uid = c$uid; - s$id = c$id; - c$ssh = s; - } + init_record(c); + c$ssh$client = version; + if ( version[4] == "1" ) c$ssh$version = 1; if ( version[4] == "2" ) c$ssh$version = 2; } -event ssh_auth_successful(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) +event ssh_auth_successful(c: connection, auth_method_none: bool) { - print "ssh_auth_successful"; - if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) + if ( !c?$ssh || ( c$ssh?$auth_success && c$ssh$auth_success ) ) return; - c$ssh$result = "success"; - c$ssh$method = determine_auth_method(c$ssh$version, last_pkt_len, middle_pkt_len, first_pkt_len); - } -event ssh_auth_successful(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) &priority=-5 - { - c$ssh$logged = T; - Log::write(SSH::LOG, c$ssh); - } - -event ssh_auth_failed(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) - { - print "ssh_auth_failed"; - if ( !c?$ssh || ( c$ssh?$result && c$ssh$result == "success" ) ) + # We can't accurately tell for compressed streams + if ( c$ssh?$compression_alg && ( c$ssh$compression_alg == "zlib@openssh.com" || + c$ssh$compression_alg == "zlib" ) ) return; - c$ssh$result = "failure"; - c$ssh$method = determine_auth_method(c$ssh$version, last_pkt_len, middle_pkt_len, first_pkt_len); - } - -event ssh_auth_failed(c: connection, last_pkt_len: int, middle_pkt_len: int, first_pkt_len: int) &priority=-5 - { - c$ssh$logged = T; - Log::write(SSH::LOG, c$ssh); - } + + c$ssh$auth_success = T; -event connection_state_remove(c: connection) - { - if ( c?$ssh && !c$ssh?$result ) + if ( auth_method_none ) + c$ssh$auth_details = "method: none"; + + if ( skip_processing_after_detection) { - c$ssh$result = "unknown"; + skip_further_processing(c$id); + set_record_packets(c$id, F); + } + } + +event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=-5 + { + if ( c?$ssh && !c$ssh$logged ) + { + c$ssh$logged = T; + Log::write(SSH::LOG, c$ssh); } } - -event ssh_server_capabilities(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string) + +event ssh_auth_failed(c: connection) { - # print "kex_algorithms", kex_algorithms; - # print ""; - # print "server_host_key_algorithms", server_host_key_algorithms; - # print ""; - # print "encryption_algorithms_client_to_server", encryption_algorithms_client_to_server; - # print ""; - # print "encryption_algorithms_server_to_client", encryption_algorithms_server_to_client; - # print ""; - # print "mac_algorithms_client_to_server", mac_algorithms_client_to_server; - # print ""; - # print "mac_algorithms_server_to_client", mac_algorithms_server_to_client; - # print ""; - # print "compression_algorithms_client_to_server", compression_algorithms_client_to_server; - # print ""; - # print "compression_algorithms_server_to_client", compression_algorithms_server_to_client; - # print ""; - # print "languages_client_to_server", languages_client_to_server; - # print ""; - # print "languages_server_to_client", languages_server_to_client; - # print ""; + if ( !c?$ssh || ( c$ssh?$auth_success && !c$ssh$auth_success ) ) + return; + + # We can't accurately tell for compressed streams + if ( c$ssh?$compression_alg && ( c$ssh$compression_alg == "zlib@openssh.com" || + c$ssh$compression_alg == "zlib" ) ) + return; + + c$ssh$auth_success = F; + c$ssh$num_failures += 1; + } + +function array_to_vec(s: string_array): vector of string + { + local r: vector of string; + + for (i in s) + r[i] = s[i]; + return r; + } + +function find_client_preferred_algorithm(client_algorithms: vector of string, server_algorithms: vector of string): string + { + for ( i in client_algorithms ) + for ( j in server_algorithms ) + if ( client_algorithms[i] == server_algorithms[j] ) + return client_algorithms[i]; + } + +function find_client_preferred_algorithm_bidirectional(client_algorithms_c_to_s: vector of string, + server_algorithms_c_to_s: vector of string, + client_algorithms_s_to_c: vector of string, + server_algorithms_s_to_c: vector of string): string + { + local c_to_s = find_client_preferred_algorithm(client_algorithms_c_to_s, server_algorithms_c_to_s); + local s_to_c = find_client_preferred_algorithm(client_algorithms_s_to_c, server_algorithms_s_to_c); + + return c_to_s == s_to_c ? c_to_s : fmt("To server: %s, to client: %s", c_to_s, s_to_c); + } + +event ssh_capabilities(c: connection, cookie: string, capabilities: Capabilities) + { + if ( !c?$ssh || ( c$ssh?$capabilities && c$ssh$capabilities$is_server == capabilities$is_server ) ) + return; + + if ( !c$ssh?$capabilities ) + { + c$ssh$capabilities = capabilities; + return; + } + + local client_caps = capabilities$is_server ? c$ssh$capabilities : capabilities; + local server_caps = capabilities$is_server ? capabilities : c$ssh$capabilities; + + c$ssh$cipher_alg = find_client_preferred_algorithm_bidirectional(client_caps$encryption_algorithms_client_to_server, + server_caps$encryption_algorithms_client_to_server, + client_caps$encryption_algorithms_server_to_client, + server_caps$encryption_algorithms_server_to_client); + + c$ssh$mac_alg = find_client_preferred_algorithm_bidirectional(client_caps$mac_algorithms_client_to_server, + server_caps$mac_algorithms_client_to_server, + client_caps$mac_algorithms_server_to_client, + server_caps$mac_algorithms_server_to_client); + + c$ssh$compression_alg = find_client_preferred_algorithm_bidirectional(client_caps$compression_algorithms_client_to_server, + server_caps$compression_algorithms_client_to_server, + client_caps$compression_algorithms_server_to_client, + server_caps$compression_algorithms_server_to_client); + + c$ssh$kex_alg = find_client_preferred_algorithm(client_caps$kex_algorithms, server_caps$kex_algorithms); + c$ssh$host_key_alg = find_client_preferred_algorithm(client_caps$server_host_key_algorithms, + server_caps$server_host_key_algorithms); } event connection_state_remove(c: connection) &priority=-5 { - if ( c?$ssh && !c$ssh$logged ) + if ( c?$ssh && !c$ssh$logged && c$ssh?$client && c$ssh?$server ) + { + if ( c$ssh?$auth_success && !c$ssh$auth_success ) + c$ssh$auth_details = fmt("%d failure%s", c$ssh$num_failures, c$ssh$num_failures == 1 ? "" : "s"); + + c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); + } } function generate_fingerprint(c: connection, key: string) { + if ( !c?$ssh ) + return; + local lx = str_split(md5_hash(key), vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)); lx[0] = ""; c$ssh$host_key = sub(join_string_vec(lx, ":"), /:/, ""); @@ -195,15 +234,11 @@ function generate_fingerprint(c: connection, key: string) event ssh1_server_host_key(c: connection, p: string, e: string) { - if ( !c?$ssh ) - return; generate_fingerprint(c, e + p); } event ssh_server_host_key(c: connection, key: string) { - if ( !c?$ssh ) - return; generate_fingerprint(c, key); } diff --git a/src/analyzer/protocol/ssh/CMakeLists.txt b/src/analyzer/protocol/ssh/CMakeLists.txt index 1266e4f496..de9abeb31f 100644 --- a/src/analyzer/protocol/ssh/CMakeLists.txt +++ b/src/analyzer/protocol/ssh/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI bro_plugin_begin(Bro SSH) bro_plugin_cc(SSH.cc Plugin.cc) + bro_plugin_bif(types.bif) bro_plugin_bif(events.bif) bro_plugin_pac(ssh.pac ssh-analyzer.pac ssh-protocol.pac) bro_plugin_end() \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index 19ca99417c..4cf05c8c54 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -6,6 +6,7 @@ #include "Reporter.h" +#include "types.bif.h" #include "events.bif.h" using namespace analyzer::SSH; @@ -18,10 +19,10 @@ SSH_Analyzer::SSH_Analyzer(Connection* c) interp = new binpac::SSH::SSH_Conn(this); had_gap = false; auth_decision_made = false; - num_encrypted_packets_seen = 0; - initial_client_packet_size = 0; - initial_server_packet_size = 0; - } + skipped_banner = false; + service_accept_size = 0; + userauth_failure_size = 0; + } SSH_Analyzer::~SSH_Analyzer() { @@ -59,7 +60,13 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) if ( interp->get_state(orig) == binpac::SSH::ENCRYPTED ) { - ProcessEncrypted(len, orig); + if ( ssh_encrypted_packet ) + BifEvent::generate_ssh_encrypted_packet(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), + orig, len); + + if ( !auth_decision_made ) + ProcessEncrypted(len, orig); + return; } @@ -69,7 +76,6 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } catch ( const binpac::Exception& e ) { - printf("Binpac exception: %s\n", e.c_msg()); ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); } } @@ -83,84 +89,65 @@ void SSH_Analyzer::Undelivered(uint64 seq, int len, bool orig) void SSH_Analyzer::ProcessEncrypted(int len, bool orig) { - if (orig && !initial_client_packet_size) - initial_client_packet_size = len; - if (!orig && !initial_server_packet_size) - initial_server_packet_size = len; - - int relative_len; - if (orig) - relative_len = len - initial_client_packet_size; - else - relative_len = len - initial_server_packet_size; - - if ( !auth_decision_made && ( num_encrypted_packets_seen > 3 ) ) + // We're interested in messages from the server for SSH2 + if (!orig && (interp->get_version() == binpac::SSH::SSH2)) { - int auth_result = AuthResult(relative_len, orig, interp->get_version()); - if ( auth_result > 0 ) + // The first thing we see and want to know is the length of + // SSH_MSG_SERVICE_REQUEST, which has a fixed (decrypted) size + // of 24 bytes (17 for content pad-aligned to 8-byte + // boundaries) + if (!service_accept_size) + { + service_accept_size = len; + return; + } + + // If our user can authenticate via the "none" method, this + // packet will be a SSH_MSG_USERAUTH_SUCCESS, which has a + // fixed (decrypted) size of 8 bytes (1 for content + // pad-aligned to 8-byte boundaries). relative_len would be + // -16. + if (!userauth_failure_size && (len + 16 == service_accept_size)) { auth_decision_made = true; - if ( auth_result == 1 ) - BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), - interp->bro_analyzer()->Conn(), - len, - packet_n_1_size, - packet_n_2_size); - if ( auth_result == 2 ) - BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), - interp->bro_analyzer()->Conn(), - len, - packet_n_1_size, - packet_n_2_size); + if ( ssh_auth_successful ) + BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), true); + return; + } + + // Normally, this packet would be a SSH_MSG_USERAUTH_FAILURE + // message, with a variable length, depending on the + // authentication methods the server supports. If it's too + // big, it might contain a pre-auth MOTD/banner, so we'll just + // skip it. + if (!userauth_failure_size) + { + if ( !skipped_banner && (len - service_accept_size) > 256 ) + { + skipped_banner = true; + return; + } + userauth_failure_size = len; + return; + } + + // If we've already seen a failure, let's see if this is + // another packet of the same size. + if (len == userauth_failure_size) + { + if ( ssh_auth_failed ) + BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn()); + return; + } + + // ...or a success packet. + if (len - service_accept_size == -16) + { + auth_decision_made = true; + if ( ssh_auth_successful ) + BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), false); + return; } } - if ( ( num_encrypted_packets_seen >= 2 ) && - ( orig != packet_n_1_is_orig ) ) - { - packet_n_2_is_orig = packet_n_1_is_orig; - packet_n_2_size = packet_n_1_size; - } - if ( num_encrypted_packets_seen == 0 ) - num_encrypted_packets_seen = 1; - else if ( orig == packet_n_1_is_orig ) - packet_n_1_size += len; - else - { - packet_n_1_is_orig = orig; - packet_n_1_size = relative_len; - if ( ! ( ( interp->get_version() == binpac::SSH::SSH1 ) && len > 90 ) ) - num_encrypted_packets_seen++; - } - } - - -int SSH_Analyzer::AuthResult(int len, bool orig, int version) - { - if ( version == binpac::SSH::SSH2 ) - { - if ( !orig && packet_n_1_is_orig && !packet_n_2_is_orig ) - { - if ( len == -16 ) - return 1; - else if ( len >= 16 && len <= 32 ) - return 2; - return 0; - } - } - else if ( version == binpac::SSH::SSH1 ) - { - // On a successful login, the server sends a longer message - if ( !orig && len > 0 ) - { - // To verify a public key, the server sends back a message of the same size - // as the previous one. Ignore that occurrence here. - if ( ! ( packet_n_1_is_orig && ( len == packet_n_1_size ) ) ) - return 1; - } - // If we've seen too many messages without a longer message, treat it as a failure - if ( num_encrypted_packets_seen > 7 ) - return 2; - } - return -1; } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 185e83d4de..af6dcbf090 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -31,22 +31,16 @@ protected: binpac::SSH::SSH_Conn* interp; void ProcessEncrypted(int len, bool orig); - int AuthResult(int len, bool orig, int version); bool had_gap; // Packet analysis stuff bool auth_decision_made; + bool skipped_banner; - int initial_client_packet_size; - int initial_server_packet_size; - int num_encrypted_packets_seen; + int service_accept_size; + int userauth_failure_size; - bool packet_n_1_is_orig; - int packet_n_1_size; - bool packet_n_2_is_orig; - int packet_n_2_size; - }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 7505dfd6db..4a8d959de4 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -2,11 +2,13 @@ event ssh_server_version%(c: connection, version: string%); event ssh_client_version%(c: connection, version: string%); -event ssh_auth_successful%(c: connection, last_packet_len: int, middle_packet_len: int, first_packet_len: int%); +event ssh_auth_successful%(c: connection, auth_method_none: bool%); -event ssh_auth_failed%(c: connection, last_packet_len: int, middle_packet_len: int, first_packet_len: int%); +event ssh_auth_failed%(c: connection%); -event ssh_server_capabilities%(c: connection, kex_algorithms: string, server_host_key_algorithms: string, encryption_algorithms_client_to_server: string, encryption_algorithms_server_to_client: string, mac_algorithms_client_to_server: string, mac_algorithms_server_to_client: string, compression_algorithms_client_to_server: string, compression_algorithms_server_to_client: string, languages_client_to_server: string, languages_server_to_client: string%); +event ssh_encrypted_packet%(c: connection, orig: bool, len: count%); + +event ssh_capabilities%(c: connection, cookie: string, capabilities: SSH::Capabilities%); event ssh_server_host_key%(c: connection, key: string%); diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 1af96a4c5c..0a76b7c8f4 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -1,3 +1,53 @@ +%extern{ +#include +#include +#include +%} + +%header{ +VectorVal* name_list_to_vector(const bytestring nl); +%} + +%code{ +// Copied from IRC_Analyzer::SplitWords +VectorVal* name_list_to_vector(const bytestring nl) + { + VectorVal* vv = new VectorVal(internal_type("string_vec")->AsVectorType()); + + string name_list = std_str(nl); + if ( name_list.size() < 1 ) + return vv; + + unsigned int start = 0; + unsigned int split_pos = 0; + + while ( name_list[start] == ',' ) + { + ++start; + ++split_pos; + } + + string word; + while ( (split_pos = name_list.find(',', start)) < name_list.size() ) + { + word = name_list.substr(start, split_pos - start); + if ( word.size() > 0 && word[0] != ',' ) + vv->Assign(vv->Size(), new StringVal(word)); + + start = split_pos + 1; + } + + // Add line end if needed. + if ( start < name_list.size() ) + { + word = name_list.substr(start, name_list.size() - start); + vv->Assign(vv->Size(), new StringVal(word)); + } + + return vv; + } +%} + refine flow SSH_Flow += { function proc_ssh_version(msg: SSH_Version): bool %{ @@ -18,20 +68,26 @@ refine flow SSH_Flow += { function proc_ssh_kexinit(msg: SSH_KEXINIT): bool %{ - if ( ssh_server_capabilities ) + if ( ssh_capabilities ) { - BifEvent::generate_ssh_server_capabilities(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${msg.kex_algorithms.val}), - bytestring_to_val(${msg.server_host_key_algorithms.val}), - bytestring_to_val(${msg.encryption_algorithms_client_to_server.val}), - bytestring_to_val(${msg.encryption_algorithms_server_to_client.val}), - bytestring_to_val(${msg.mac_algorithms_client_to_server.val}), - bytestring_to_val(${msg.mac_algorithms_server_to_client.val}), - bytestring_to_val(${msg.compression_algorithms_client_to_server.val}), - bytestring_to_val(${msg.compression_algorithms_server_to_client.val}), - bytestring_to_val(${msg.languages_client_to_server.val}), - bytestring_to_val(${msg.languages_server_to_client.val})); + RecordVal* result = new RecordVal(BifType::Record::SSH::Capabilities); + result->Assign(0, name_list_to_vector(${msg.kex_algorithms.val})); + result->Assign(1, name_list_to_vector(${msg.server_host_key_algorithms.val})); + result->Assign(2, name_list_to_vector(${msg.encryption_algorithms_client_to_server.val})); + result->Assign(3, name_list_to_vector(${msg.encryption_algorithms_server_to_client.val})); + result->Assign(4, name_list_to_vector(${msg.mac_algorithms_client_to_server.val})); + result->Assign(5, name_list_to_vector(${msg.mac_algorithms_server_to_client.val})); + result->Assign(6, name_list_to_vector(${msg.compression_algorithms_client_to_server.val})); + result->Assign(7, name_list_to_vector(${msg.compression_algorithms_server_to_client.val})); + if ( ${msg.languages_client_to_server.len} ) + result->Assign(8, name_list_to_vector(${msg.languages_client_to_server.val})); + if ( ${msg.languages_server_to_client.len} ) + result->Assign(9, name_list_to_vector(${msg.languages_server_to_client.val})); + result->Assign(10, new Val(${msg.is_orig}, TYPE_BOOL)); + + BifEvent::generate_ssh_capabilities(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), bytestring_to_val(${msg.cookie}), + result); } return true; %} @@ -49,7 +105,7 @@ refine flow SSH_Flow += { function proc_ssh1_server_host_key(p: bytestring, e: bytestring): bool %{ - if ( ssh_server_host_key ) + if ( ssh1_server_host_key ) { BifEvent::generate_ssh1_server_host_key(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), @@ -75,10 +131,6 @@ refine typeattr SSH_KEXINIT += &let { proc: bool = $context.flow.proc_ssh_kexinit(this); }; -refine typeattr SSH_DH_GEX_REPLY += &let { - proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); -}; - refine typeattr SSH1_Message += &let { proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == SSH_CMSG_SESSION_KEY); }; @@ -87,6 +139,14 @@ refine typeattr SSH2_Message += &let { proc_newkeys: bool = $context.flow.proc_newkeys() &if(msg_type == MSG_NEWKEYS); }; +refine typeattr SSH_DH_GEX_REPLY += &let { + proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); +}; + +refine typeattr SSH_ECC_REPLY += &let { + proc: bool = $context.flow.proc_ssh_server_host_key(k_s.val); +}; + refine typeattr SSH1_PUBLIC_KEY += &let { - proc: bool = $context.flow.proc_ssh1_server_host_key(host_key_p.val, host_key_e.val); + proc: bool = $context.flow.proc_ssh1_server_host_key(host_key_p.val, host_key_e.val); }; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index 3e1ec95ecc..36bfcaedf3 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -5,104 +5,143 @@ enum version { }; enum state { - VERSION_EXCHANGE = 0, - KEY_EXCHANGE_CLEARTEXT = 1, - ENCRYPTED = 2, + VERSION_EXCHANGE = 0, + KEX_INIT = 1, + KEX_DH_GEX = 2, + KEX_DH = 3, + KEX_ECC = 4, + KEX_GSS = 5, + KEX_RSA = 6, + ENCRYPTED = 7, +}; + +# diffie-hellman-group1-sha1 [RFC4253] Section 8.1 +# diffie-hellman-group14-sha1 [RFC4253] Section 8.2 +enum KEX_DH_message_id { + SSH_MSG_KEXDH_INIT = 30, + SSH_MSG_KEXDH_REPLY = 31, +}; + +# diffie-hellman-group-exchange-sha1 [RFC4419] Section 4.1 +# diffie-hellman-group-exchange-sha256 [RFC4419] Section 4.2 +enum KEX_DH_GEX_message_id { + SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, + SSH_MSG_KEX_DH_GEX_GROUP = 31, + SSH_MSG_KEX_DH_GEX_INIT = 32, + SSH_MSG_KEX_DH_GEX_REPLY = 33, + SSH_MSG_KEX_DH_GEX_REQUEST = 34, +}; + +# rsa1024-sha1 [RFC4432] +# rsa2048-sha256 [RFC4432] +enum KEX_RSA_message_id { + SSH_MSG_KEXRSA_PUBKEY = 30, + SSH_MSG_KEXRSA_SECRET = 31, + SSH_MSG_KEXRSA_DONE = 32, +}; + +# gss-group1-sha1-* [RFC4462] Section 2.3 +# gss-group14-sha1-* [RFC4462] Section 2.4 +# gss-gex-sha1-* [RFC4462] Section 2.5 +# gss-* [RFC4462] Section 2.6 +enum KEX_GSS_message_id { + SSH_MSG_KEXGSS_INIT = 30, + SSH_MSG_KEXGSS_CONTINUE = 31, + SSH_MSG_KEXGSS_COMPLETE = 32, + SSH_MSG_KEXGSS_HOSTKEY = 33, + SSH_MSG_KEXGSS_ERROR = 34, + SSH_MSG_KEXGSS_GROUPREQ = 40, + SSH_MSG_KEXGSS_GROUP = 41, +}; + +# ecdh-sha2-* [RFC5656] +enum KEX_ECDH_message_id { + SSH_MSG_KEX_ECDH_INIT = 30, + SSH_MSG_KEX_ECDH_REPLY = 31, +}; + +# ecmqv-sha2 [RFC5656] +enum KEX_ECMQV_message_id { + SSH_MSG_ECMQV_INIT = 30, + SSH_MSG_ECMQV_REPLY = 31, }; enum ssh1_message_id { - SSH_MSG_NONE = 0, - SSH_MSG_DISCONNECT = 1, - SSH_SMSG_PUBLIC_KEY = 2, - SSH_CMSG_SESSION_KEY = 3, - SSH_CMSG_USER = 4, - SSH_CMSG_AUTH_RHOSTS = 5, - SSH_CMSG_AUTH_RSA = 6, - SSH_SMSG_AUTH_RSA_CHALLENGE = 7, - SSH_CMSG_AUTH_RSA_RESPONSE = 8, - SSH_CMSG_AUTH_PASSWORD = 9, - SSH_CMSG_REQUEST_PTY = 10, - SSH_CMSG_WINDOW_SIZE = 11, - SSH_CMSG_EXEC_SHELL = 12, - SSH_CMSG_EXEC_CMD = 13, - SSH_SMSG_SUCCESS = 14, - SSH_SMSG_FAILURE = 15, - SSH_CMSG_STDIN_DATA = 16, - SSH_SMSG_STDOUT_DATA = 17, - SSH_SMSG_STDERR_DATA = 18, - SSH_CMSG_EOF = 19, - SSH_SMSG_EXITSTATUS = 20, + SSH_MSG_NONE = 0, + SSH_MSG_DISCONNECT = 1, + SSH_SMSG_PUBLIC_KEY = 2, + SSH_CMSG_SESSION_KEY = 3, + SSH_CMSG_USER = 4, + SSH_CMSG_AUTH_RHOSTS = 5, + SSH_CMSG_AUTH_RSA = 6, + SSH_SMSG_AUTH_RSA_CHALLENGE = 7, + SSH_CMSG_AUTH_RSA_RESPONSE = 8, + SSH_CMSG_AUTH_PASSWORD = 9, + SSH_CMSG_REQUEST_PTY = 10, + SSH_CMSG_WINDOW_SIZE = 11, + SSH_CMSG_EXEC_SHELL = 12, + SSH_CMSG_EXEC_CMD = 13, + SSH_SMSG_SUCCESS = 14, + SSH_SMSG_FAILURE = 15, + SSH_CMSG_STDIN_DATA = 16, + SSH_SMSG_STDOUT_DATA = 17, + SSH_SMSG_STDERR_DATA = 18, + SSH_CMSG_EOF = 19, + SSH_SMSG_EXITSTATUS = 20, SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 21, SSH_MSG_CHANNEL_OPEN_FAILURE = 22, - SSH_MSG_CHANNEL_DATA = 23, - SSH_MSG_CHANNEL_CLOSE = 24, + SSH_MSG_CHANNEL_DATA = 23, + SSH_MSG_CHANNEL_CLOSE = 24, SSH_MSG_CHANNEL_CLOSE_CONFIRMATION = 25, SSH_CMSG_X11_REQUEST_FORWARDING_OLD = 26, - SSH_SMSG_X11_OPEN = 27, + SSH_SMSG_X11_OPEN = 27, SSH_CMSG_PORT_FORWARD_REQUEST = 28, - SSH_MSG_PORT_OPEN = 29, + SSH_MSG_PORT_OPEN = 29, SSH_CMSG_AGENT_REQUEST_FORWARDING = 30, - SSH_SMSG_AGENT_OPEN = 31, - SSH_MSG_IGNORE = 32, - SSH_CMSG_EXIT_CONFIRMATION = 33, + SSH_SMSG_AGENT_OPEN = 31, + SSH_MSG_IGNORE = 32, + SSH_CMSG_EXIT_CONFIRMATION = 33, SSH_CMSG_X11_REQUEST_FORWARDING = 34, - SSH_CMSG_AUTH_RHOSTS_RSA = 35, - SSH_MSG_DEBUG = 36, + SSH_CMSG_AUTH_RHOSTS_RSA = 35, + SSH_MSG_DEBUG = 36, SSH_CMSG_REQUEST_COMPRESSION = 37, - SSH_CMSG_MAX_PACKET_SIZE = 38, - SSH_CMSG_AUTH_TIS = 39, - SSH_SMSG_AUTH_TIS_CHALLENGE = 40, - SSH_CMSG_AUTH_TIS_RESPONSE = 41, - SSH_CMSG_AUTH_KERBEROS = 42, + SSH_CMSG_MAX_PACKET_SIZE = 38, + SSH_CMSG_AUTH_TIS = 39, + SSH_SMSG_AUTH_TIS_CHALLENGE = 40, + SSH_CMSG_AUTH_TIS_RESPONSE = 41, + SSH_CMSG_AUTH_KERBEROS = 42, SSH_SMSG_AUTH_KERBEROS_RESPONSE = 43, - SSH_CMSG_HAVE_KERBEROS_TGT = 44, + SSH_CMSG_HAVE_KERBEROS_TGT = 44, }; enum ssh2_message_id { - MSG_DISCONNECT = 1, - MSG_IGNORE = 2, - MSG_UNIMPLEMENTED = 3, - MSG_DEBUG = 4, - MSG_SERVICE_REQUEST = 5, - MSG_SERVICE_ACCEPT = 6, - MSG_KEXINIT = 20, - MSG_NEWKEYS = 21, - MSG_KEX_DH_GEX_REQUEST_OLD = 30, - MSG_KEX_DH_GEX_GROUP = 31, - MSG_KEX_DH_GEX_INIT = 32, - MSG_KEX_DH_GEX_REPLY = 33, - MSG_KEX_DH_GEX_REQUEST = 34, - MSG_USERAUTH_REQUEST = 50, - MSG_USERAUTH_FAILURE = 51, - MSG_USERAUTH_SUCCESS = 52, - MSG_USERAUTH_BANNER = 53, - MSG_GLOBAL_REQUEST = 80, - MSG_REQUEST_SUCCESS = 81, - MSG_REQUEST_FAILURE = 82, - MSG_CHANNEL_OPEN = 90, - MSG_CHANNEL_OPEN_CONFIRMATION = 91, - MSG_CHANNEL_OPEN_FAILURE = 92, - MSG_CHANNEL_WINDOW_ADJUST = 93, - MSG_CHANNEL_DATA = 94, - MSG_CHANNEL_EXTENDED_DATA = 95, - MSG_CHANNEL_EOF = 96, - MSG_CHANNEL_CLOSE = 97, - MSG_CHANNEL_REQUEST = 98, - MSG_CHANNEL_SUCCESS = 99, - MSG_CHANNEL_FAILURE = 100, + MSG_DISCONNECT = 1, + MSG_IGNORE = 2, + MSG_UNIMPLEMENTED = 3, + MSG_DEBUG = 4, + MSG_SERVICE_REQUEST = 5, + MSG_SERVICE_ACCEPT = 6, + MSG_KEXINIT = 20, + MSG_NEWKEYS = 21, }; +## SSH Generic + type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { - VERSION_EXCHANGE -> version: SSH_Version(is_orig); - KEY_EXCHANGE_CLEARTEXT -> kex: SSH_Key_Exchange(is_orig); - ENCRYPTED -> ciphertext: bytestring &length=1 &transient; + VERSION_EXCHANGE -> version: SSH_Version(is_orig); + KEX_INIT -> kex: SSH_Key_Exchange(is_orig); + KEX_DH_GEX -> kex_dh_gex: SSH_Key_Exchange_DH_GEX(is_orig); + KEX_DH -> kex_dh: SSH_Key_Exchange_DH(is_orig); + KEX_ECC -> kex_ecc: SSH_Key_Exchange_ECC(is_orig); + KEX_GSS -> kex_gss: SSH_Key_Exchange_GSS(is_orig); + KEX_RSA -> kex_rsa: SSH_Key_Exchange_RSA(is_orig); } &byteorder=bigendian; type SSH_Version(is_orig: bool) = record { version: bytestring &oneline; pad: bytestring &length=0 &transient; } &let { - update_state : bool = $context.connection.update_state(KEY_EXCHANGE_CLEARTEXT, is_orig); + update_state : bool = $context.connection.update_state(KEX_INIT, is_orig); update_version: bool = $context.connection.update_version(version, is_orig); }; @@ -111,6 +150,8 @@ type SSH_Key_Exchange(is_orig: bool) = case $context.connection.get_version() of SSH2 -> ssh2_msg: SSH2_Key_Exchange(is_orig); }; +## SSH1 + type SSH1_Key_Exchange(is_orig: bool) = record { packet_length: uint32; pad_fill : bytestring &length = 8 - (packet_length % 8); @@ -119,20 +160,6 @@ type SSH1_Key_Exchange(is_orig: bool) = record { crc : uint32; } &length = packet_length + 4 + 8 - (packet_length % 8); -type SSH2_Key_Exchange_Header = record { - packet_length : uint32; - padding_length: uint8; - msg_type : uint8; -} &let { - payload_length: uint32 = packet_length - padding_length - 2; -} &length=6; - -type SSH2_Key_Exchange(is_orig: bool) = record { - header : SSH2_Key_Exchange_Header; - payload : SSH2_Message(is_orig, header.msg_type, header.payload_length); - pad : bytestring &length=header.padding_length; -} &length=header.packet_length + 4; - type SSH1_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { SSH_SMSG_PUBLIC_KEY -> public_key: SSH1_PUBLIC_KEY(length); SSH_CMSG_SESSION_KEY -> session_key: SSH1_SESSION_KEY(length); @@ -160,19 +187,35 @@ type SSH1_SESSION_KEY(length: uint32) = record { flags : uint32; } &length=length; +type ssh1_mp_int = record { + len: uint16; + val: bytestring &length=(len+7)/8; +}; + +## SSH2 + +type SSH2_Key_Exchange_Header = record { + packet_length : uint32; + padding_length: uint8; + msg_type : uint8; +} &let { + payload_length: uint32 = packet_length - padding_length - 2; +} &length=6; + +type SSH2_Key_Exchange(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH2_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + type SSH2_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { - MSG_KEXINIT -> kexinit: SSH_KEXINIT(length); - MSG_KEX_DH_GEX_REQUEST -> dh_gex_request: SSH_DH_GEX_REQUEST(length); - MSG_KEX_DH_GEX_REQUEST_OLD -> dh_gex_request_old: SSH_DH_GEX_REQUEST_OLD(length); - MSG_KEX_DH_GEX_GROUP -> dh_gex_group: SSH_DH_GEX_GROUP(length); - MSG_KEX_DH_GEX_INIT -> dh_gex_init: SSH_DH_GEX_INIT(length); - MSG_KEX_DH_GEX_REPLY -> dh_gex_reply: SSH_DH_GEX_REPLY(length); - MSG_NEWKEYS -> new_keys: bytestring &length=length; + MSG_KEXINIT -> kexinit: SSH_KEXINIT(length, is_orig); + default -> unknown: bytestring &length=length; } &let { detach: bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == MSG_NEWKEYS); }; -type SSH_KEXINIT(length: uint32) = record { +type SSH_KEXINIT(length: uint32, is_orig: bool) = record { cookie : bytestring &length=16; kex_algorithms : ssh_string; server_host_key_algorithms : ssh_string; @@ -182,21 +225,52 @@ type SSH_KEXINIT(length: uint32) = record { mac_algorithms_server_to_client : ssh_string; compression_algorithms_client_to_server : ssh_string; compression_algorithms_server_to_client : ssh_string; - languages_client_to_server : ssh_string; - languages_server_to_client : ssh_string; - first_kex_packet_follows : uint8; - reserved : uint32; + languages_client_to_server : ssh_string; + languages_server_to_client : ssh_string; + first_kex_packet_follows : uint8; + reserved : uint32; +} &let { + proc_kex : bool = $context.connection.update_kex(kex_algorithms.val, is_orig); } &length=length; -type SSH_DH_GEX_REQUEST(length: uint32) = record { +# KEX_DH exchanges + +type SSH_Key_Exchange_DH(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH_Key_Exchange_DH_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH_Key_Exchange_DH_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_MSG_KEXDH_INIT -> init : SSH_DH_GEX_INIT(length); + SSH_MSG_KEXDH_REPLY -> reply : SSH_DH_GEX_REPLY(length); +}; + +# KEX_DH_GEX exchanges + +type SSH_Key_Exchange_DH_GEX(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH_Key_Exchange_DH_GEX_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH_Key_Exchange_DH_GEX_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_MSG_KEX_DH_GEX_REQUEST_OLD -> request_old : SSH_DH_GEX_REQUEST_OLD; + SSH_MSG_KEX_DH_GEX_REQUEST -> request : SSH_DH_GEX_REQUEST; + SSH_MSG_KEX_DH_GEX_GROUP -> group : SSH_DH_GEX_GROUP(length); + SSH_MSG_KEX_DH_GEX_INIT -> init : SSH_DH_GEX_INIT(length); + SSH_MSG_KEX_DH_GEX_REPLY -> reply : SSH_DH_GEX_REPLY(length); +}; + +type SSH_DH_GEX_REQUEST = record { min: uint32; n : uint32; max: uint32; } &length=12; -type SSH_DH_GEX_REQUEST_OLD(length: uint32) = record { - payload: bytestring &length=length; -} &length=length; +type SSH_DH_GEX_REQUEST_OLD = record { + n: uint32; +} &length=4; type SSH_DH_GEX_GROUP(length: uint32) = record { p: ssh_string; @@ -213,9 +287,106 @@ type SSH_DH_GEX_REPLY(length: uint32) = record { signature: ssh_string; } &length=length; -type ssh1_mp_int = record { - len: uint16; - val: bytestring &length=(len+7)/8; +# KEX_RSA exchanges + +type SSH_Key_Exchange_RSA(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH_Key_Exchange_RSA_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH_Key_Exchange_RSA_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_MSG_KEXRSA_PUBKEY -> pubkey : SSH_RSA_PUBKEY(length); + SSH_MSG_KEXRSA_SECRET -> secret : SSH_RSA_SECRET(length); + SSH_MSG_KEXRSA_DONE -> done : SSH_RSA_DONE(length); +}; + +type SSH_RSA_PUBKEY(length: uint32) = record { + k_s: ssh_string; + k_t: ssh_string; +} &length=length; + +type SSH_RSA_SECRET(length: uint32) = record { + encrypted_payload: ssh_string; +} &length=length; + +type SSH_RSA_DONE(length: uint32) = record { + signature: ssh_string; +} &length=length; + +# KEX_GSS exchanges + +type SSH_Key_Exchange_GSS(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH_Key_Exchange_GSS_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH_Key_Exchange_GSS_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_MSG_KEXGSS_INIT -> init : SSH_GSS_INIT(length); + SSH_MSG_KEXGSS_CONTINUE -> cont : SSH_GSS_CONTINUE(length); + SSH_MSG_KEXGSS_COMPLETE -> complete : SSH_GSS_COMPLETE(length); + SSH_MSG_KEXGSS_HOSTKEY -> hostkey : SSH_GSS_HOSTKEY(length); + SSH_MSG_KEXGSS_ERROR -> error : SSH_GSS_ERROR(length); + SSH_MSG_KEXGSS_GROUPREQ -> groupreq : SSH_DH_GEX_REQUEST; + SSH_MSG_KEXGSS_GROUP -> group : SSH_DH_GEX_GROUP(length); +}; + +type SSH_GSS_INIT(length: uint32) = record { + output_token: ssh_string; + e : ssh_string; +} &length=length; + +type SSH_GSS_CONTINUE(length: uint32) = record { + output_token: ssh_string; +} &length=length; + +type SSH_GSS_COMPLETE(length: uint32) = record { + f : ssh_string; + per_msg_token : ssh_string; + have_token : uint8; + parse_token : case have_token of { + 0 -> no_token: empty; + default -> token: ssh_string; + }; +} &length=length; + +type SSH_GSS_HOSTKEY(length: uint32) = record { + k_s: ssh_string; +} &length=length; + +type SSH_GSS_ERROR(length: uint32) = record { + major_status: uint32; + minor_status: uint32; + message : ssh_string; + language : ssh_string; +} &length=length; + +# KEX_ECDH and KEX_ECMQV exchanges + +type SSH_Key_Exchange_ECC(is_orig: bool) = record { + header : SSH2_Key_Exchange_Header; + payload : SSH_Key_Exchange_ECC_Message(is_orig, header.msg_type, header.payload_length); + pad : bytestring &length=header.padding_length; +} &length=header.packet_length + 4; + +type SSH_Key_Exchange_ECC_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of { + SSH_MSG_KEX_ECDH_INIT -> init : SSH_ECC_INIT(length); + SSH_MSG_KEX_ECDH_REPLY -> reply : SSH_ECC_REPLY(length); +}; + +# This deviates from the RFC. SSH_MSG_KEX_ECDH_INIT and +# SSH_MSG_KEX_ECMQV_INIT can be parsed the same way. +type SSH_ECC_INIT(length: uint32) = record { + q_c: ssh_string; +}; + +# This deviates from the RFC. SSH_MSG_KEX_ECDH_REPLY and +# SSH_MSG_KEX_ECMQV_REPLY can be parsed the same way. +type SSH_ECC_REPLY(length: uint32) = record { + k_s : ssh_string; + q_s : ssh_string; + signature : ssh_string; }; type ssh_string = record { @@ -223,17 +394,35 @@ type ssh_string = record { val: bytestring &length=len; }; +type ssh_host_key = record { + len: uint32; + key_type: ssh_string; + key: ssh_string; +} &length=(len + 4); + +## Done with types + refine connection SSH_Conn += { %member{ int state_up_; int state_down_; int version_; + + bool kex_orig_; + bool kex_seen_; + bytestring kex_algs_cache_; + bytestring kex_algorithm_; %} %init{ state_up_ = VERSION_EXCHANGE; state_down_ = VERSION_EXCHANGE; version_ = UNK; + + kex_seen_ = false; + kex_orig_ = false; + kex_algs_cache_ = bytestring(); + kex_algorithm_ = bytestring(); %} function get_state(is_orig: bool): int @@ -274,4 +463,103 @@ refine connection SSH_Conn += { return true; %} + function update_kex_state_if_equal(s: string, to_state: state): bool + %{ + if ( strcmp(c_str(kex_algorithm_), s.c_str()) == 0 ) + { + update_state(to_state, true); + update_state(to_state, false); + return true; + } + return false; + %} + + function update_kex_state_if_startswith(s: string, to_state: state): bool + %{ + if ( (uint) kex_algorithm_.length() < s.length() ) + return false; + + if ( strcmp(std_str(kex_algorithm_).substr(0, s.length()).c_str(), s.c_str()) == 0 ) + { + update_state(to_state, true); + update_state(to_state, false); + return true; + } + return false; + %} + + function update_kex(algs: bytestring, orig: bool): bool + %{ + if ( !kex_seen_ ) + { + kex_seen_ = true; + kex_orig_ = orig; + kex_algs_cache_.init(${algs}.data(), ${algs}.length()); + + return false; + } + else if ( kex_orig_ == orig ) + return false; + + VectorVal* client_list = name_list_to_vector(orig ? algs : kex_algs_cache_); + VectorVal* server_list = name_list_to_vector(orig ? kex_algs_cache_ : algs); + + for ( unsigned int i = 0; i < client_list->Size(); ++i) + { + for ( unsigned int j = 0; j < server_list->Size(); ++j) + { + if ( strcmp((const char *) client_list->Lookup(i)->AsStringVal()->Bytes(), + (const char *) server_list->Lookup(j)->AsStringVal()->Bytes()) == 0 ) + { + kex_algorithm_.init((const uint8 *) client_list->Lookup(i)->AsStringVal()->Bytes(), + client_list->Lookup(i)->AsStringVal()->Len()); + + // UNTESTED + if ( update_kex_state_if_equal("rsa1024-sha1", KEX_RSA) ) + return true; + // UNTESTED + if ( update_kex_state_if_equal("rsa2048-sha256", KEX_RSA) ) + return true; + + // UNTESTED + if ( update_kex_state_if_equal("diffie-hellman-group1-sha1", KEX_DH) ) + return true; + // UNTESTED + if ( update_kex_state_if_equal("diffie-hellman-group14-sha1", KEX_DH) ) + return true; + + if ( update_kex_state_if_equal("diffie-hellman-group-exchange-sha1", KEX_DH_GEX) ) + return true; + if ( update_kex_state_if_equal("diffie-hellman-group-exchange-sha256", KEX_DH_GEX) ) + return true; + + if ( update_kex_state_if_startswith("gss-group1-sha1-", KEX_GSS) ) + return true; + if ( update_kex_state_if_startswith("gss-group14-sha1-", KEX_GSS) ) + return true; + if ( update_kex_state_if_startswith("gss-gex-sha1-", KEX_GSS) ) + return true; + if ( update_kex_state_if_startswith("gss-", KEX_GSS) ) + return true; + + if ( update_kex_state_if_startswith("ecdh-sha2-", KEX_ECC) ) + return true; + if ( update_kex_state_if_equal("ecmqv-sha2", KEX_ECC) ) + return true; + if ( update_kex_state_if_equal("curve25519-sha256@libssh.org", KEX_ECC) ) + return true; + + + bro_analyzer()->Weird(fmt("ssh_unknown_kex_algorithm=%s", c_str(kex_algorithm_))); + return true; + + } + } + } + + return true; + + %} + + }; \ No newline at end of file diff --git a/src/analyzer/protocol/ssh/ssh.pac b/src/analyzer/protocol/ssh/ssh.pac index b3181c4fa1..2358f056da 100644 --- a/src/analyzer/protocol/ssh/ssh.pac +++ b/src/analyzer/protocol/ssh/ssh.pac @@ -8,6 +8,7 @@ %include bro.pac %extern{ + #include "types.bif.h" #include "events.bif.h" %} diff --git a/src/analyzer/protocol/ssh/types.bif b/src/analyzer/protocol/ssh/types.bif new file mode 100644 index 0000000000..38e51600f3 --- /dev/null +++ b/src/analyzer/protocol/ssh/types.bif @@ -0,0 +1,5 @@ +module SSH; + +type Capabilities: record; + +module GLOBAL; \ No newline at end of file From 1e8d6cd917d7d2a6f81c873d9113e6a18fb43df9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 13 Jan 2015 17:14:21 -0600 Subject: [PATCH 021/256] broker integration: add API for connecting to peers --- CMakeLists.txt | 2 + aux/broker | 2 +- src/CMakeLists.txt | 4 ++ src/comm/CMakeLists.txt | 15 ++++++ src/comm/Manager.cc | 115 ++++++++++++++++++++++++++++++++++++++++ src/comm/Manager.h | 52 ++++++++++++++++++ src/comm/comm.bif | 43 +++++++++++++++ src/main.cc | 22 ++++++++ 8 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 src/comm/CMakeLists.txt create mode 100644 src/comm/Manager.cc create mode 100644 src/comm/Manager.h create mode 100644 src/comm/comm.bif diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f0fcf8d07..b31e60ac01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,6 +181,8 @@ if ( ENABLE_BROKER ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") add_subdirectory(aux/broker) set(brodeps ${brodeps} broker) + add_definitions(-DENABLE_BROKER) + include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/aux/broker) endif () add_subdirectory(src) diff --git a/aux/broker b/aux/broker index a1b51def07..331966d1f3 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit a1b51def07cfb191d0a83a78c7102560740dbcb3 +Subproject commit 331966d1f3d24c63bedbda79e477f759c4d267f9 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 13c6e45006..55ca12c873 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,6 +161,10 @@ add_subdirectory(iosource) add_subdirectory(logging) add_subdirectory(probabilistic) +if ( ENABLE_BROKER ) + add_subdirectory(comm) +endif () + set(bro_SUBDIRS # Order is important here. ${bro_PLUGIN_LIBS} diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt new file mode 100644 index 0000000000..c152adc49a --- /dev/null +++ b/src/comm/CMakeLists.txt @@ -0,0 +1,15 @@ +include(BroSubdir) + +include_directories(BEFORE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +set(comm_SRCS + Manager.cc +) + +bif_target(comm.bif) + +bro_add_subdir_library(comm ${comm_SRCS} ${BIF_OUTPUT_CC}) +add_dependencies(bro_comm generate_outputs) diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc new file mode 100644 index 0000000000..ac67208ca6 --- /dev/null +++ b/src/comm/Manager.cc @@ -0,0 +1,115 @@ +#include "Manager.h" +#include +#include +#include +#include "util.h" +#include "Reporter.h" + +bool comm::Manager::InitPreScript() + { + auto res = broker::init(); + + if ( res ) + { + fprintf(stderr, "broker::init failed: %s\n", broker::strerror(res)); + return false; + } + + char host[256]; + const char* name; + + if ( gethostname(host, sizeof(host)) == 0 ) + name = fmt("bro@%s.%ld", host, static_cast(getpid())); + else + name = fmt("bro@.%ld", static_cast(getpid())); + + endpoint = std::unique_ptr(new broker::endpoint(name)); + return true; + } + +bool comm::Manager::InitPostScript() + { + return true; + } + +bool comm::Manager::Listen(uint16_t port, const char* addr) + { + auto rval = endpoint->listen(port, addr); + + if ( ! rval ) + { + reporter->Error("Failed to listen on %s:%" PRIu16 " : %s", + addr ? addr : "INADDR_ANY", port, + endpoint->last_error().data()); + } + + return rval; + } + +bool comm::Manager::Connect(string addr, uint16_t port, + std::chrono::duration retry_interval) + { + auto& peer = peers[std::make_pair(addr, port)]; + + if ( peer ) + return false; + + peer = endpoint->peer(std::move(addr), port, retry_interval); + return true; + } + +bool comm::Manager::Disconnect(const string& addr, uint16_t port) + { + auto it = peers.find(std::make_pair(addr, port)); + + if ( it == peers.end() ) + return false; + + return endpoint->unpeer(it->second); + } + +void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) + { + read->Insert(endpoint->peer_status().fd()); + } + +double comm::Manager::NextTimestamp(double* local_network_time) + { + // TODO: do something better? + return timer_mgr->Time(); + } + +void comm::Manager::Process() + { + bool idle = true; + auto peer_status_updates = endpoint->peer_status().want_pop(); + + if ( ! peer_status_updates.empty() ) + idle = false; + + for ( auto& u : peer_status_updates ) + { + if ( ! u.relation.remote() ) + continue; + + // TODO: generate events + switch ( u.status ) { + case broker::peer_status::tag::established: + printf("established\n"); + break; + case broker::peer_status::tag::disconnected: + printf("disconnected\n"); + break; + case broker::peer_status::tag::incompatible: + printf("incompatible\n"); + break; + default: + reporter->InternalWarning("unknown broker::peer_status::tag : %d", + static_cast(u.status)); + break; + } + } + + SetIdle(idle); + } diff --git a/src/comm/Manager.h b/src/comm/Manager.h new file mode 100644 index 0000000000..412c125d14 --- /dev/null +++ b/src/comm/Manager.h @@ -0,0 +1,52 @@ +#ifndef BRO_COMM_MANAGER_H +#define BRO_COMM_MANAGER_H + +#include +#include +#include +#include +#include "Reporter.h" +#include "iosource/IOSource.h" + +namespace comm { + +// TODO: documentation + +// Manages various forms of communication between peer Bro processes +// or possibly between different parts of a single Bro process. +class Manager : public iosource::IOSource { +public: + + bool InitPreScript(); + + bool InitPostScript(); + + bool Listen(uint16_t port, const char* addr = nullptr); + + bool Connect(std::string addr, uint16_t port, + std::chrono::duration retry_interval); + + bool Disconnect(const std::string& addr, uint16_t port); + +private: + + // IOSource interface overrides: + void GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) override; + + double NextTimestamp(double* local_network_time) override; + + void Process() override; + + const char* Tag() override + { return "Comm::Manager"; } + + std::unique_ptr endpoint; + std::map, broker::peering> peers; +}; + +} // namespace comm + +extern comm::Manager* comm_mgr; + +#endif // BRO_COMM_MANAGER_H diff --git a/src/comm/comm.bif b/src/comm/comm.bif new file mode 100644 index 0000000000..ce54b916ca --- /dev/null +++ b/src/comm/comm.bif @@ -0,0 +1,43 @@ + +module Comm; + +%%{ +#include "comm/Manager.h" +%%} + +function Comm::listen%(p: port, a: string &default=""%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("listen port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::connect%(a: string, p: port, retry: interval%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Connect(a->CheckString(), p->Port(), + std::chrono::duration(retry)); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::disconnect%(a: string, p: port%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); + return new Val(rval, TYPE_BOOL); + %} diff --git a/src/main.cc b/src/main.cc index 15aea3d3fe..a7099cb90b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -63,6 +63,10 @@ extern "C" void OPENSSL_add_all_algorithms_conf(void); #include "3rdparty/sqlite3.h" +#ifdef ENABLE_BROKER +#include +#endif + Brofiler brofiler; #ifndef HAVE_STRSEP @@ -94,6 +98,9 @@ analyzer::Manager* analyzer_mgr = 0; file_analysis::Manager* file_mgr = 0; broxygen::Manager* broxygen_mgr = 0; iosource::Manager* iosource_mgr = 0; +#ifdef ENABLE_BROKER +comm::Manager* comm_mgr = 0; +#endif Stmt* stmts; EventHandlerPtr net_done = 0; RuleMatcher* rule_matcher = 0; @@ -851,6 +858,16 @@ int main(int argc, char** argv) input_mgr = new input::Manager(); file_mgr = new file_analysis::Manager(); +#ifdef ENABLE_BROKER + comm_mgr = new comm::Manager(); + + if ( ! comm_mgr->InitPreScript() ) + { + fprintf(stderr, "Failed to initialize communication manager."); + exit(1); + } +#endif + plugin_mgr->InitPreScript(); analyzer_mgr->InitPreScript(); file_mgr->InitPreScript(); @@ -925,6 +942,11 @@ int main(int argc, char** argv) exit(rc); } +#ifdef ENABLE_BROKER + comm_mgr->InitPostScript(); + iosource_mgr->Register(comm_mgr); +#endif + #ifdef USE_PERFTOOLS_DEBUG } #endif From 0daa954ddbff2bdb991b3ade0312a7fcf03b76aa Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 14 Jan 2015 10:40:11 -0600 Subject: [PATCH 022/256] broker integration: add remote connection status events. --- scripts/base/frameworks/comm/__load__.bro | 1 + scripts/base/frameworks/comm/main.bro | 7 +++ scripts/base/init-bare.bro | 1 + src/comm/Manager.cc | 62 ++++++++++++++++++----- src/comm/comm.bif | 8 +++ 5 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 scripts/base/frameworks/comm/__load__.bro create mode 100644 scripts/base/frameworks/comm/main.bro diff --git a/scripts/base/frameworks/comm/__load__.bro b/scripts/base/frameworks/comm/__load__.bro new file mode 100644 index 0000000000..a10fe855df --- /dev/null +++ b/scripts/base/frameworks/comm/__load__.bro @@ -0,0 +1 @@ +@load ./main diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro new file mode 100644 index 0000000000..af4225f5dd --- /dev/null +++ b/scripts/base/frameworks/comm/main.bro @@ -0,0 +1,7 @@ + +module Comm; + +export { + + const endpoint_name = "" &redef; +} diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 4a1bcfbe72..9d790e1e09 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3358,6 +3358,7 @@ const bits_per_uid: count = 96 &redef; # Load these frameworks here because they use fairly deep integration with # BiFs and script-land defined types. +@load base/frameworks/comm @load base/frameworks/logging @load base/frameworks/input @load base/frameworks/analyzer diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index ac67208ca6..29ff71d7e0 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -3,9 +3,16 @@ #include #include #include "util.h" +#include "Var.h" #include "Reporter.h" +#include "comm/comm.bif.h" bool comm::Manager::InitPreScript() + { + return true; + } + +bool comm::Manager::InitPostScript() { auto res = broker::init(); @@ -15,23 +22,25 @@ bool comm::Manager::InitPreScript() return false; } - char host[256]; const char* name; + auto name_from_script = internal_val("Comm::endpoint_name")->AsString(); - if ( gethostname(host, sizeof(host)) == 0 ) - name = fmt("bro@%s.%ld", host, static_cast(getpid())); + if ( name_from_script->Len() ) + name = name_from_script->CheckString(); else - name = fmt("bro@.%ld", static_cast(getpid())); + { + char host[256]; + + if ( gethostname(host, sizeof(host)) == 0 ) + name = fmt("bro@%s.%ld", host, static_cast(getpid())); + else + name = fmt("bro@.%ld", static_cast(getpid())); + } endpoint = std::unique_ptr(new broker::endpoint(name)); return true; } -bool comm::Manager::InitPostScript() - { - return true; - } - bool comm::Manager::Listen(uint16_t port, const char* addr) { auto rval = endpoint->listen(port, addr); @@ -93,17 +102,44 @@ void comm::Manager::Process() if ( ! u.relation.remote() ) continue; - // TODO: generate events switch ( u.status ) { case broker::peer_status::tag::established: - printf("established\n"); + if ( Comm::remote_connection_established ) + { + val_list* vl = new val_list; + vl->append(new StringVal(u.relation.remote_tuple().first)); + vl->append(new PortVal(u.relation.remote_tuple().second, + TRANSPORT_TCP)); + vl->append(new StringVal(u.peer_name)); + mgr.QueueEvent(Comm::remote_connection_established, vl); + } + break; + case broker::peer_status::tag::disconnected: - printf("disconnected\n"); + if ( Comm::remote_connection_broken ) + { + val_list* vl = new val_list; + vl->append(new StringVal(u.relation.remote_tuple().first)); + vl->append(new PortVal(u.relation.remote_tuple().second, + TRANSPORT_TCP)); + mgr.QueueEvent(Comm::remote_connection_broken, vl); + } + break; + case broker::peer_status::tag::incompatible: - printf("incompatible\n"); + if ( Comm::remote_connection_incompatible ) + { + val_list* vl = new val_list; + vl->append(new StringVal(u.relation.remote_tuple().first)); + vl->append(new PortVal(u.relation.remote_tuple().second, + TRANSPORT_TCP)); + mgr.QueueEvent(Comm::remote_connection_incompatible, vl); + } + break; + default: reporter->InternalWarning("unknown broker::peer_status::tag : %d", static_cast(u.status)); diff --git a/src/comm/comm.bif b/src/comm/comm.bif index ce54b916ca..67933df20e 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -5,6 +5,14 @@ module Comm; #include "comm/Manager.h" %%} +event Comm::remote_connection_established%(peer_address: string, + peer_port: port, + peer_name: string%); +event Comm::remote_connection_broken%(peer_address: string, + peer_port: port%); +event Comm::remote_connection_incompatible%(peer_address: string, + peer_port: port%); + function Comm::listen%(p: port, a: string &default=""%): bool %{ if ( ! p->IsTCP() ) From 1e462481dc2e3106431ac9cd71c4ea1644c7881b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 14 Jan 2015 13:28:34 -0600 Subject: [PATCH 023/256] broker integration: add remote printing --- aux/broker | 2 +- scripts/base/frameworks/comm/main.bro | 6 ++ src/comm/Manager.cc | 116 ++++++++++++++++++++++++-- src/comm/Manager.h | 14 ++++ src/comm/comm.bif | 30 ++++++- 5 files changed, 158 insertions(+), 10 deletions(-) diff --git a/aux/broker b/aux/broker index 331966d1f3..1e8d675790 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 331966d1f3d24c63bedbda79e477f759c4d267f9 +Subproject commit 1e8d6757909750524c15f8eaf3c297243bc55425 diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index af4225f5dd..c69d36db52 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -4,4 +4,10 @@ module Comm; export { const endpoint_name = "" &redef; + + type SendFlags: record { + self: bool &default = F; + peers: bool &default = T; + unsolicited: bool &default = F; + }; } diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 29ff71d7e0..7027daa79e 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -7,13 +7,31 @@ #include "Reporter.h" #include "comm/comm.bif.h" +using namespace std; + bool comm::Manager::InitPreScript() { return true; } +static int require_field(const RecordType* rt, const char* name) + { + auto rval = rt->FieldOffset(name); + + if ( rval < 0 ) + reporter->InternalError("no field named '%s' in record type '%s'", name, + rt->GetName().data()); + + return rval; + } + bool comm::Manager::InitPostScript() { + auto send_flags_type = internal_type("Comm::SendFlags")->AsRecordType(); + send_flags_self_idx = require_field(send_flags_type, "self"); + send_flags_peers_idx = require_field(send_flags_type, "peers"); + send_flags_unsolicited_idx = require_field(send_flags_type, "unsolicited"); + auto res = broker::init(); if ( res ) @@ -37,7 +55,7 @@ bool comm::Manager::InitPostScript() name = fmt("bro@.%ld", static_cast(getpid())); } - endpoint = std::unique_ptr(new broker::endpoint(name)); + endpoint = unique_ptr(new broker::endpoint(name)); return true; } @@ -56,31 +74,81 @@ bool comm::Manager::Listen(uint16_t port, const char* addr) } bool comm::Manager::Connect(string addr, uint16_t port, - std::chrono::duration retry_interval) + chrono::duration retry_interval) { - auto& peer = peers[std::make_pair(addr, port)]; + auto& peer = peers[make_pair(addr, port)]; if ( peer ) return false; - peer = endpoint->peer(std::move(addr), port, retry_interval); + peer = endpoint->peer(move(addr), port, retry_interval); return true; } bool comm::Manager::Disconnect(const string& addr, uint16_t port) { - auto it = peers.find(std::make_pair(addr, port)); + auto it = peers.find(make_pair(addr, port)); if ( it == peers.end() ) return false; - return endpoint->unpeer(it->second); + auto rval = endpoint->unpeer(it->second); + peers.erase(it); + return rval; + } + +bool comm::Manager::Print(string topic, string msg, const Val* flags) + { + endpoint->send(move(topic), broker::message{move(msg)}, get_flags(flags)); + return true; + } + +bool comm::Manager::SubscribeToPrints(string topic_prefix) + { + auto& q = print_subscriptions[topic_prefix]; + + if ( q ) + return false; + + q = broker::message_queue(move(topic_prefix), *endpoint); + return true; + } + +bool comm::Manager::UnsubscribeToPrints(const string& topic_prefix) + { + return print_subscriptions.erase(topic_prefix); + } + +int comm::Manager::get_flags(const Val* flags) + { + auto r = flags->AsRecordVal(); + int rval = 0; + Val* self_flag = r->LookupWithDefault(send_flags_self_idx); + Val* peers_flag = r->LookupWithDefault(send_flags_peers_idx); + Val* unsolicited_flag = r->LookupWithDefault(send_flags_unsolicited_idx); + + if ( self_flag->AsBool() ) + rval |= broker::SELF; + + if ( peers_flag->AsBool() ) + rval |= broker::PEERS; + + if ( unsolicited_flag->AsBool() ) + rval |= broker::UNSOLICITED; + + Unref(self_flag); + Unref(peers_flag); + Unref(unsolicited_flag); + return rval; } void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, iosource::FD_Set* except) { read->Insert(endpoint->peer_status().fd()); + + for ( const auto& ps : print_subscriptions ) + read->Insert(ps.second.fd()); } double comm::Manager::NextTimestamp(double* local_network_time) @@ -147,5 +215,41 @@ void comm::Manager::Process() } } + for ( const auto& ps : print_subscriptions ) + { + auto print_messages = ps.second.want_pop(); + + if ( print_messages.empty() ) + continue; + + idle = false; + + if ( ! Comm::print_handler ) + continue; + + for ( auto& pm : print_messages ) + { + if ( pm.size() != 1 ) + { + reporter->Warning("got print message of invalid size: %zd", + pm.size()); + continue; + } + + std::string* msg = broker::get(pm[0]); + + if ( ! msg ) + { + reporter->Warning("got print message of invalid type: %d", + static_cast(broker::which(pm[0]))); + continue; + } + + val_list* vl = new val_list; + vl->append(new StringVal(move(*msg))); + mgr.QueueEvent(Comm::print_handler, vl); + } + } + SetIdle(idle); } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 412c125d14..0f7d5a4a1c 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -2,6 +2,7 @@ #define BRO_COMM_MANAGER_H #include +#include #include #include #include @@ -28,8 +29,16 @@ public: bool Disconnect(const std::string& addr, uint16_t port); + bool Print(std::string topic, std::string msg, const Val* flags); + + bool SubscribeToPrints(std::string topic_prefix); + + bool UnsubscribeToPrints(const std::string& topic_prefix); + private: + int get_flags(const Val* flags); + // IOSource interface overrides: void GetFds(iosource::FD_Set* read, iosource::FD_Set* write, iosource::FD_Set* except) override; @@ -43,6 +52,11 @@ private: std::unique_ptr endpoint; std::map, broker::peering> peers; + std::map print_subscriptions; + + int send_flags_self_idx; + int send_flags_peers_idx; + int send_flags_unsolicited_idx; }; } // namespace comm diff --git a/src/comm/comm.bif b/src/comm/comm.bif index 67933df20e..6294864bba 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -1,10 +1,12 @@ -module Comm; - %%{ #include "comm/Manager.h" %%} +module Comm; + +type Comm::SendFlags: record; + event Comm::remote_connection_established%(peer_address: string, peer_port: port, peer_name: string%); @@ -13,7 +15,7 @@ event Comm::remote_connection_broken%(peer_address: string, event Comm::remote_connection_incompatible%(peer_address: string, peer_port: port%); -function Comm::listen%(p: port, a: string &default=""%): bool +function Comm::listen%(p: port, a: string &default = ""%): bool %{ if ( ! p->IsTCP() ) { @@ -49,3 +51,25 @@ function Comm::disconnect%(a: string, p: port%): bool auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); return new Val(rval, TYPE_BOOL); %} + +event Comm::print_handler%(msg: string%); + +function Comm::print%(topic: string, msg: string, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->Print(topic->CheckString(), msg->CheckString(), + flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_prints%(topic_prefix: string &default = ""%): bool + %{ + auto rval = comm_mgr->SubscribeToPrints(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_prints%(topic_prefix: string &default = ""%): bool + %{ + auto rval = comm_mgr->UnsubscribeToPrints(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} From 7e563b7275394dcb72d44c288cdb5bd96f4dffb9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 15 Jan 2015 15:45:08 -0600 Subject: [PATCH 024/256] broker integration: add remote events --- scripts/base/frameworks/comm/main.bro | 9 + src/comm/CMakeLists.txt | 1 + src/comm/Data.cc | 533 ++++++++++++++++++++++++++ src/comm/Data.h | 29 ++ src/comm/Manager.cc | 177 +++++++++ src/comm/Manager.h | 11 + src/comm/comm.bif | 42 +- 7 files changed, 800 insertions(+), 2 deletions(-) create mode 100644 src/comm/Data.cc create mode 100644 src/comm/Data.h diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index c69d36db52..efe3069a1c 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -10,4 +10,13 @@ export { peers: bool &default = T; unsolicited: bool &default = F; }; + + type Data: record { + d: opaque of Comm::Data &optional; + }; + + type EventArgs: record { + name: string &optional; # nil for invalid event/args. + args: vector of Comm::Data; + }; } diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt index c152adc49a..95ad701d71 100644 --- a/src/comm/CMakeLists.txt +++ b/src/comm/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(BEFORE ) set(comm_SRCS + Data.cc Manager.cc ) diff --git a/src/comm/Data.cc b/src/comm/Data.cc new file mode 100644 index 0000000000..58d5b30085 --- /dev/null +++ b/src/comm/Data.cc @@ -0,0 +1,533 @@ +#include "Data.h" +#include "comm/comm.bif.h" + +using namespace std; + +OpaqueType* comm::opaque_of_data_type; + +static broker::port::protocol to_broker_port_proto(TransportProto tp) + { + switch ( tp ) { + case TRANSPORT_TCP: + return broker::port::protocol::tcp; + case TRANSPORT_UDP: + return broker::port::protocol::udp; + case TRANSPORT_ICMP: + return broker::port::protocol::icmp; + case TRANSPORT_UNKNOWN: + default: + return broker::port::protocol::unknown; + } + } + +static TransportProto to_bro_port_proto(broker::port::protocol tp) + { + switch ( tp ) { + case broker::port::protocol::tcp: + return TRANSPORT_TCP; + case broker::port::protocol::udp: + return TRANSPORT_UDP; + case broker::port::protocol::icmp: + return TRANSPORT_ICMP; + case broker::port::protocol::unknown: + default: + return TRANSPORT_UNKNOWN; + } + } + +struct val_converter { + using result_type = Val*; + + BroType* type; + + result_type operator()(bool a) + { + if ( type->Tag() == TYPE_BOOL ) + return new Val(a, TYPE_BOOL); + return nullptr; + } + + result_type operator()(uint64_t a) + { + if ( type->Tag() == TYPE_COUNT ) + return new Val(a, TYPE_COUNT); + if ( type->Tag() == TYPE_COUNTER ) + return new Val(a, TYPE_COUNTER); + return nullptr; + } + + result_type operator()(int64_t a) + { + if ( type->Tag() == TYPE_INT ) + return new Val(a, TYPE_INT); + return nullptr; + } + + result_type operator()(double a) + { + if ( type->Tag() == TYPE_DOUBLE ) + return new Val(a, TYPE_DOUBLE); + return nullptr; + } + + result_type operator()(const std::string& a) + { + switch ( type->Tag() ) { + case TYPE_STRING: + return new StringVal(a.size(), a.data()); + case TYPE_FILE: + { + auto file = BroFile::GetFile(a.data()); + + if ( file ) + { + Ref(file); + return new Val(file); + } + + return nullptr; + } + case TYPE_FUNC: + { + auto id = lookup_ID(a.data(), GLOBAL_MODULE_NAME); + auto rval = id ? id->ID_Val() : nullptr; + Unref(id); + + if ( rval && rval->Type()->Tag() == TYPE_FUNC ) + return rval; + + return nullptr; + } + default: + return nullptr; + } + } + + result_type operator()(const broker::address& a) + { + if ( type->Tag() == TYPE_ADDR ) + { + auto bits = reinterpret_cast(&a.bytes()); + return new AddrVal(IPAddr(*bits)); + } + + return nullptr; + } + + result_type operator()(const broker::subnet& a) + { + if ( type->Tag() == TYPE_SUBNET ) + { + auto bits = reinterpret_cast(&a.network().bytes()); + return new SubNetVal(IPPrefix(IPAddr(*bits), a.length())); + } + + return nullptr; + } + + result_type operator()(const broker::port& a) + { + if ( type->Tag() == TYPE_PORT ) + return new PortVal(a.number(), to_bro_port_proto(a.type())); + + return nullptr; + } + + result_type operator()(const broker::time_point& a) + { + if ( type->Tag() == TYPE_TIME ) + return new Val(a.value, TYPE_TIME); + + return nullptr; + } + + result_type operator()(const broker::time_duration& a) + { + if ( type->Tag() == TYPE_INTERVAL ) + return new Val(a.value, TYPE_INTERVAL); + + return nullptr; + } + + result_type operator()(const broker::enum_value& a) + { + if ( type->Tag() == TYPE_ENUM ) + { + auto etype = type->AsEnumType(); + auto i = etype->Lookup(GLOBAL_MODULE_NAME, a.name.data()); + + if ( i == -1 ) + return nullptr; + + return new EnumVal(i, etype); + } + + return nullptr; + } + + result_type operator()(broker::set& a) + { + if ( ! type->IsSet() ) + return nullptr; + + auto tt = type->AsTableType(); + auto rval = new TableVal(tt); + + for ( auto& item : a ) + { + auto indices = broker::get(item); + + if ( ! indices ) + { + Unref(rval); + return nullptr; + } + + auto expected_index_types = tt->Indices()->Types(); + + if ( expected_index_types->length() != indices->size() ) + { + Unref(rval); + return nullptr; + } + + auto list_val = new ListVal(TYPE_ANY); + + for ( auto i = 0u; i < indices->size(); ++i ) + { + auto index_val = comm::data_to_val(move((*indices)[i]), + (*expected_index_types)[i]); + + if ( ! index_val ) + { + Unref(rval); + Unref(list_val); + return nullptr; + } + + list_val->Append(index_val); + } + + + rval->Assign(list_val, nullptr); + Unref(list_val); + } + + return rval; + } + + result_type operator()(broker::table& a) + { + if ( ! type->IsTable() ) + return nullptr; + + auto tt = type->AsTableType(); + auto rval = new TableVal(tt); + + for ( auto& item : a ) + { + auto indices = broker::get(item.first); + + if ( ! indices ) + { + Unref(rval); + return nullptr; + } + + auto expected_index_types = tt->Indices()->Types(); + + if ( expected_index_types->length() != indices->size() ) + { + Unref(rval); + return nullptr; + } + + auto list_val = new ListVal(TYPE_ANY); + + for ( auto i = 0u; i < indices->size(); ++i ) + { + auto index_val = comm::data_to_val(move((*indices)[i]), + (*expected_index_types)[i]); + + if ( ! index_val ) + { + Unref(rval); + Unref(list_val); + return nullptr; + } + + list_val->Append(index_val); + } + + auto value_val = comm::data_to_val(move(item.second), + tt->YieldType()); + + if ( ! value_val ) + { + Unref(rval); + Unref(list_val); + return nullptr; + } + + rval->Assign(list_val, value_val); + Unref(list_val); + } + + return rval; + } + + result_type operator()(broker::vector& a) + { + if ( type->Tag() != TYPE_VECTOR ) + return nullptr; + + auto vt = type->AsVectorType(); + auto rval = new VectorVal(vt); + + for ( auto& item : a ) + { + auto item_val = comm::data_to_val(move(item), vt->YieldType()); + + if ( ! item_val ) + { + Unref(rval); + return nullptr; + } + + rval->Assign(rval->Size(), item_val); + } + + return rval; + } + + result_type operator()(broker::record& a) + { + if ( type->Tag() != TYPE_RECORD ) + return nullptr; + + auto rt = type->AsRecordType(); + + if ( a.fields.size() != rt->NumFields() ) + return nullptr; + + auto rval = new RecordVal(rt); + + for ( auto i = 0u; i < a.fields.size(); ++i ) + { + if ( ! a.fields[i] ) + { + rval->Assign(i, nullptr); + continue; + } + + auto item_val = comm::data_to_val(move(*a.fields[i]), + rt->FieldType(i)); + + if ( ! item_val ) + { + Unref(rval); + return nullptr; + } + + rval->Assign(i, item_val); + } + + return nullptr; + } +}; + +Val* comm::data_to_val(broker::data d, BroType* type) + { + return broker::visit(val_converter{type}, d); + } + +broker::util::optional comm::val_to_data(const Val* v) + { + switch ( v->Type()->Tag() ) { + case TYPE_BOOL: + return {v->AsBool()}; + case TYPE_INT: + return {v->AsInt()}; + case TYPE_COUNT: + return {v->AsCount()}; + case TYPE_COUNTER: + return {v->AsCounter()}; + case TYPE_PORT: + { + auto p = v->AsPortVal(); + return {broker::port(p->Port(), to_broker_port_proto(p->PortType()))}; + } + case TYPE_ADDR: + { + auto a = v->AsAddr(); + in6_addr tmp; + a.CopyIPv6(&tmp); + return {broker::address(reinterpret_cast(&tmp), + broker::address::family::ipv6, + broker::address::byte_order::network)}; + } + break; + case TYPE_SUBNET: + { + auto s = v->AsSubNet(); + in6_addr tmp; + s.Prefix().CopyIPv6(&tmp); + auto a = broker::address(reinterpret_cast(&tmp), + broker::address::family::ipv6, + broker::address::byte_order::network); + return {broker::subnet(a, s.Length())}; + } + break; + case TYPE_DOUBLE: + return {v->AsDouble()}; + case TYPE_TIME: + return {broker::time_point(v->AsTime())}; + case TYPE_INTERVAL: + return {broker::time_duration(v->AsInterval())}; + case TYPE_ENUM: + { + auto enum_type = v->Type()->AsEnumType(); + auto enum_name = enum_type->Lookup(v->AsEnum()); + return {broker::enum_value(enum_name ? "" : enum_name)}; + } + case TYPE_STRING: + { + auto s = v->AsString(); + return {string(reinterpret_cast(s->Bytes()), s->Len())}; + } + case TYPE_FILE: + return {string(v->AsFile()->Name())}; + case TYPE_FUNC: + return {string(v->AsFunc()->Name())}; + case TYPE_TABLE: + { + auto is_set = v->Type()->IsSet(); + auto table = v->AsTable(); + auto table_val = v->AsTableVal(); + auto c = table->InitForIteration(); + broker::data rval; + + if ( is_set ) + rval = broker::set(); + else + rval = broker::table(); + + struct iter_guard { + iter_guard(HashKey* arg_k, ListVal* arg_lv) + : k(arg_k), lv(arg_lv) + {} + + ~iter_guard() + { + delete k; + Unref(lv); + } + + HashKey* k; + ListVal* lv; + }; + + for ( auto i = 0; i < table->Length(); ++i ) + { + HashKey* k; + auto entry = table->NextEntry(k, c); + auto vl = table_val->RecoverIndex(k); + iter_guard ig(k, vl); + broker::vector key; + + for ( auto k = 0; k < vl->Length(); ++k ) + { + auto key_part = val_to_data((*vl->Vals())[k]); + + if ( ! key_part ) + return {}; + + key.emplace_back(move(*key_part)); + } + + if ( is_set ) + broker::get(rval)->emplace(move(key)); + else + { + auto val = val_to_data(entry->Value()); + + if ( ! val ) + return {}; + + broker::get(rval)->emplace(move(key), + move(*val)); + } + } + + return {rval}; + } + case TYPE_VECTOR: + { + auto vec = v->AsVectorVal(); + broker::vector rval; + rval.reserve(vec->Size()); + + for ( auto i = 0u; i < vec->Size(); ++i ) + { + auto item_val = vec->Lookup(i); + + if ( ! item_val ) + continue; + + auto item = val_to_data(item_val); + + if ( ! item ) + return {}; + + rval.emplace_back(move(*item)); + } + + return {rval}; + } + case TYPE_RECORD: + { + auto rec = v->AsRecordVal(); + broker::record rval; + auto num_fields = v->Type()->AsRecordType()->NumFields(); + rval.fields.reserve(num_fields); + + for ( auto i = 0u; i < num_fields; ++i ) + { + auto item_val = rec->LookupWithDefault(i); + + if ( ! item_val ) + { + rval.fields.emplace_back(broker::record::field{}); + continue; + } + + auto item = val_to_data(item_val); + Unref(item_val); + + if ( ! item ) + return {}; + + rval.fields.emplace_back(broker::record::field{move(*item)}); + } + + return {rval}; + } + default: + reporter->Error("unsupported Comm::Data type: %s", + type_name(v->Type()->Tag())); + break; + } + + return {}; + } + +RecordVal* comm::make_data_val(const Val* v) + { + auto rval = new RecordVal(BifType::Record::Comm::Data); + auto data = val_to_data(v); + + if ( data ) + rval->Assign(0, new DataVal(move(*data))); + + return rval; + } diff --git a/src/comm/Data.h b/src/comm/Data.h new file mode 100644 index 0000000000..e3197b61da --- /dev/null +++ b/src/comm/Data.h @@ -0,0 +1,29 @@ +#ifndef BRO_COMM_DATA_H +#define BRO_COMM_DATA_H + +#include +#include "Val.h" + +namespace comm { + +extern OpaqueType* opaque_of_data_type; + +RecordVal* make_data_val(const Val* v); + +broker::util::optional val_to_data(const Val* v); + +Val* data_to_val(broker::data d, BroType* type); + +class DataVal : public OpaqueVal { +public: + + DataVal(broker::data arg_data) + : OpaqueVal(comm::opaque_of_data_type), data(std::move(arg_data)) + {} + + broker::data data; +}; + +} // namespace comm + +#endif // BRO_COMM_DATA_H diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 7027daa79e..b4f118706a 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -1,4 +1,5 @@ #include "Manager.h" +#include "Data.h" #include #include #include @@ -32,6 +33,9 @@ bool comm::Manager::InitPostScript() send_flags_peers_idx = require_field(send_flags_type, "peers"); send_flags_unsolicited_idx = require_field(send_flags_type, "unsolicited"); + comm::opaque_of_data_type = new OpaqueType("Comm::Data"); + vector_of_data_type = new VectorType(internal_type("Comm::Data")->Ref()); + auto res = broker::init(); if ( res ) @@ -103,6 +107,96 @@ bool comm::Manager::Print(string topic, string msg, const Val* flags) return true; } +bool comm::Manager::Event(std::string topic, const RecordVal* args, + const Val* flags) + { + if ( ! args->Lookup(0) ) + return false; + + auto event_name = args->Lookup(0)->AsString()->CheckString(); + auto vv = args->Lookup(1)->AsVectorVal(); + broker::message msg; + msg.reserve(vv->Size() + 1); + msg.emplace_back(event_name); + + for ( auto i = 0u; i < vv->Size(); ++i ) + { + auto val = vv->Lookup(i)->AsRecordVal()->Lookup(0); + auto data_val = dynamic_cast(val); + msg.emplace_back(data_val->data); + } + + endpoint->send(move(topic), move(msg), get_flags(flags)); + return true; + } + +RecordVal* comm::Manager::MakeEventArgs(const val_list* args) + { + auto rval = new RecordVal(BifType::Record::Comm::EventArgs); + auto arg_vec = new VectorVal(vector_of_data_type); + rval->Assign(1, arg_vec); + const Func* func; + + for ( auto i = 0u; i < args->length(); ++i ) + { + auto arg_val = (*args)[i]; + + if ( i == 0 ) + { + // Event val must come first. + + if ( arg_val->Type()->Tag() != TYPE_FUNC ) + { + reporter->Error("1st param of Comm::event_args must be event"); + return rval; + } + + func = arg_val->AsFunc(); + + if ( func->Flavor() != FUNC_FLAVOR_EVENT ) + { + reporter->Error("1st param of Comm::event_args must be event"); + return rval; + } + + auto num_args = func->FType()->Args()->NumFields(); + + if ( num_args != args->length() - 1 ) + { + reporter->Error("bad # of Comm::event_args: got %d, expect %d", + args->length(), num_args + 1); + return rval; + } + + rval->Assign(0, new StringVal(func->Name())); + continue; + } + + auto expected_type = (*func->FType()->ArgTypes()->Types())[i - 1]; + + if ( ! same_type((*args)[i]->Type(), expected_type) ) + { + rval->Assign(0, 0); + reporter->Error("Comm::event_args param %d type mismatch", i); + return rval; + } + + auto data_val = make_data_val((*args)[i]); + + if ( ! data_val->Lookup(0) ) + { + Unref(data_val); + rval->Assign(0, 0); + reporter->Error("Comm::event_args unsupported event/params"); + return rval; + } + + arg_vec->Assign(i - 1, data_val); + } + + return rval; + } + bool comm::Manager::SubscribeToPrints(string topic_prefix) { auto& q = print_subscriptions[topic_prefix]; @@ -119,6 +213,22 @@ bool comm::Manager::UnsubscribeToPrints(const string& topic_prefix) return print_subscriptions.erase(topic_prefix); } +bool comm::Manager::SubscribeToEvents(string topic_prefix) + { + auto& q = event_subscriptions[topic_prefix]; + + if ( q ) + return false; + + q = broker::message_queue(move(topic_prefix), *endpoint); + return true; + } + +bool comm::Manager::UnsubscribeToEvents(const string& topic_prefix) + { + return event_subscriptions.erase(topic_prefix); + } + int comm::Manager::get_flags(const Val* flags) { auto r = flags->AsRecordVal(); @@ -149,6 +259,9 @@ void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, for ( const auto& ps : print_subscriptions ) read->Insert(ps.second.fd()); + + for ( const auto& ps : event_subscriptions ) + read->Insert(ps.second.fd()); } double comm::Manager::NextTimestamp(double* local_network_time) @@ -251,5 +364,69 @@ void comm::Manager::Process() } } + for ( const auto& es : event_subscriptions ) + { + auto event_messages = es.second.want_pop(); + + if ( event_messages.empty() ) + continue; + + idle = false; + + for ( auto& em : event_messages ) + { + if ( em.empty() ) + { + reporter->Warning("got empty event message"); + continue; + } + + std::string* event_name = broker::get(em[0]); + + if ( ! event_name ) + { + reporter->Warning("got event message w/o event name: %d", + static_cast(broker::which(em[0]))); + continue; + } + + EventHandlerPtr ehp = event_registry->Lookup(event_name->data()); + + if ( ! ehp ) + continue; + + auto arg_types = ehp->FType()->ArgTypes()->Types(); + + if ( arg_types->length() != em.size() - 1 ) + { + reporter->Warning("got event message with invalid # of args," + " got %zd, expected %d", em.size() - 1, + arg_types->length()); + continue; + } + + val_list* vl = new val_list; + + for ( auto i = 1u; i < em.size(); ++i ) + { + auto val = data_to_val(move(em[i]), (*arg_types)[i - 1]); + + if ( val ) + vl->append(val); + else + { + reporter->Warning("failed to convert remote event arg # %d", + i - 1); + break; + } + } + + if ( vl->length() == em.size() - 1 ) + mgr.QueueEvent(ehp, vl); + else + delete_vals(vl); + } + } + SetIdle(idle); } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 0f7d5a4a1c..020f78a03b 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -31,10 +31,18 @@ public: bool Print(std::string topic, std::string msg, const Val* flags); + bool Event(std::string topic, const RecordVal* args, const Val* flags); + + RecordVal* MakeEventArgs(const val_list* args); + bool SubscribeToPrints(std::string topic_prefix); bool UnsubscribeToPrints(const std::string& topic_prefix); + bool SubscribeToEvents(std::string topic_prefix); + + bool UnsubscribeToEvents(const std::string& topic_prefix); + private: int get_flags(const Val* flags); @@ -53,10 +61,13 @@ private: std::unique_ptr endpoint; std::map, broker::peering> peers; std::map print_subscriptions; + std::map event_subscriptions; int send_flags_self_idx; int send_flags_peers_idx; int send_flags_unsolicited_idx; + + VectorType* vector_of_data_type; }; } // namespace comm diff --git a/src/comm/comm.bif b/src/comm/comm.bif index 6294864bba..fe405222cc 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -1,17 +1,29 @@ %%{ #include "comm/Manager.h" +#include "comm/Data.h" %%} module Comm; type Comm::SendFlags: record; +type Comm::Data: record; + +type Comm::EventArgs: record; + +function Comm::data%(d: any%): Comm::Data + %{ + return comm::make_data_val(d); + %} + event Comm::remote_connection_established%(peer_address: string, peer_port: port, peer_name: string%); + event Comm::remote_connection_broken%(peer_address: string, peer_port: port%); + event Comm::remote_connection_incompatible%(peer_address: string, peer_port: port%); @@ -62,14 +74,40 @@ function Comm::print%(topic: string, msg: string, return new Val(rval, TYPE_BOOL); %} -function Comm::subscribe_to_prints%(topic_prefix: string &default = ""%): bool +function Comm::subscribe_to_prints%(topic_prefix: string%): bool %{ auto rval = comm_mgr->SubscribeToPrints(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} -function Comm::unsubscribe_to_prints%(topic_prefix: string &default = ""%): bool +function Comm::unsubscribe_to_prints%(topic_prefix: string%): bool %{ auto rval = comm_mgr->UnsubscribeToPrints(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} + +function Comm::event_args%(...%): Comm::EventArgs + %{ + auto rval = comm_mgr->MakeEventArgs(@ARGS@); + return rval; + %} + +function Comm::event%(topic: string, args: Comm::EventArgs, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->Event(topic->CheckString(), args->AsRecordVal(), + flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_events%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->SubscribeToEvents(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_events%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->UnsubscribeToEvents(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} From 5df71ddc911a87234371121146e8d382efde9192 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 22 Jan 2015 11:29:53 -0600 Subject: [PATCH 025/256] broker integration: add auto sending remote events i.e. ability to toggle whether all local dispatches of an event also generate a remote event message to peers. --- src/EventHandler.cc | 50 +++++++++++++++++++++++++++++++++- src/EventHandler.h | 19 ++++++++++++- src/comm/Manager.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++ src/comm/Manager.h | 5 ++++ src/comm/comm.bif | 13 +++++++++ 5 files changed, 150 insertions(+), 2 deletions(-) diff --git a/src/EventHandler.cc b/src/EventHandler.cc index 0f25d63ba8..d623f43b66 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -5,6 +5,11 @@ #include "RemoteSerializer.h" #include "NetVar.h" +#ifdef ENABLE_BROKER +#include "comm/Manager.h" +#include "comm/Data.h" +#endif + EventHandler::EventHandler(const char* arg_name) { name = copy_string(arg_name); @@ -26,7 +31,12 @@ EventHandler::operator bool() const { return enabled && ((local && local->HasBodies()) || receivers.length() - || generate_always); + || generate_always +#ifdef ENABLE_BROKER + || ! auto_remote_send.empty() + // TODO: and require a subscriber interested in a topic or unsolicited flags? +#endif + ); } FuncType* EventHandler::FType() @@ -73,6 +83,44 @@ void EventHandler::Call(val_list* vl, bool no_remote) SerialInfo info(remote_serializer); remote_serializer->SendCall(&info, receivers[i], name, vl); } + +#ifdef ENABLE_BROKER + + if ( ! auto_remote_send.empty() ) + { + // TODO: also short-circuit based on interested subscribers/flags? + broker::message msg; + msg.reserve(vl->length() + 1); + msg.emplace_back(Name()); + bool valid_args = true; + + for ( auto i = 0u; i < vl->length(); ++i ) + { + auto opt_data = comm::val_to_data((*vl)[i]); + + if ( opt_data ) + msg.emplace_back(move(*opt_data)); + else + { + valid_args = false; + auto_remote_send.clear(); + reporter->Error("failed auto-remote event '%s', disabled", + Name()); + break; + } + } + + if ( valid_args ) + for ( auto it = auto_remote_send.begin(); + it != auto_remote_send.end(); ++it ) + { + if ( std::next(it) == auto_remote_send.end() ) + comm_mgr->Event(it->first, move(msg), it->second); + else + comm_mgr->Event(it->first, msg, it->second); + } + } +#endif } if ( local ) diff --git a/src/EventHandler.h b/src/EventHandler.h index 55ac33cffd..7729e2af27 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -4,7 +4,8 @@ #define EVENTHANDLER #include - +#include +#include #include "List.h" #include "BroList.h" @@ -28,6 +29,18 @@ public: void AddRemoteHandler(SourceID peer); void RemoveRemoteHandler(SourceID peer); +#ifdef ENABLE_BROKER + void AutoRemote(std::string topic, int flags) + { + auto_remote_send[std::move(topic)] = flags; + } + + void AutoRemoteStop(const std::string& topic) + { + auto_remote_send.erase(topic); + } +#endif + void Call(val_list* vl, bool no_remote = false); // Returns true if there is at least one local or remote handler. @@ -67,6 +80,10 @@ private: declare(List, SourceID); typedef List(SourceID) receiver_list; receiver_list receivers; + +#ifdef ENABLE_BROKER + std::map auto_remote_send; // topic -> flags +#endif }; // Encapsulates a ptr to an event handler to overload the boolean operator. diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index b4f118706a..d803d64ae7 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -107,6 +107,12 @@ bool comm::Manager::Print(string topic, string msg, const Val* flags) return true; } +bool comm::Manager::Event(std::string topic, broker::message msg, int flags) + { + endpoint->send(move(topic), move(msg), flags); + return true; + } + bool comm::Manager::Event(std::string topic, const RecordVal* args, const Val* flags) { @@ -130,6 +136,65 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args, return true; } +bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags) + { + if ( event->Type()->Tag() != TYPE_FUNC ) + { + reporter->Error("Comm::auto_event must operate on an event"); + return false; + } + + auto event_val = event->AsFunc(); + + if ( event_val->Flavor() != FUNC_FLAVOR_EVENT ) + { + reporter->Error("Comm::auto_event must operate on an event"); + return false; + } + + auto handler = event_registry->Lookup(event_val->Name()); + + if ( ! handler ) + { + reporter->Error("Comm::auto_event failed to lookup event '%s'", + event_val->Name()); + return false; + } + + handler->AutoRemote(move(topic), get_flags(flags)); + return true; + } + +bool comm::Manager::AutoEventStop(const string& topic, const Val* event) + { + if ( event->Type()->Tag() != TYPE_FUNC ) + { + reporter->Error("Comm::auto_event_stop must operate on an event"); + return false; + } + + auto event_val = event->AsFunc(); + + if ( event_val->Flavor() != FUNC_FLAVOR_EVENT ) + { + reporter->Error("Comm::auto_event_stop must operate on an event"); + return false; + } + + auto handler = event_registry->Lookup(event_val->Name()); + + if ( ! handler ) + { + reporter->Error("Comm::auto_event_stop failed to lookup event '%s'", + event_val->Name()); + return false; + } + + + handler->AutoRemoteStop(topic); + return true; + } + RecordVal* comm::Manager::MakeEventArgs(const val_list* args) { auto rval = new RecordVal(BifType::Record::Comm::EventArgs); diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 020f78a03b..70bec51ded 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -31,8 +31,13 @@ public: bool Print(std::string topic, std::string msg, const Val* flags); + bool Event(std::string topic, broker::message msg, int flags); bool Event(std::string topic, const RecordVal* args, const Val* flags); + bool AutoEvent(std::string topic, const Val* event, const Val* flags); + + bool AutoEventStop(const std::string& topic, const Val* event); + RecordVal* MakeEventArgs(const val_list* args); bool SubscribeToPrints(std::string topic_prefix); diff --git a/src/comm/comm.bif b/src/comm/comm.bif index fe405222cc..c185120126 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -100,6 +100,19 @@ function Comm::event%(topic: string, args: Comm::EventArgs, return new Val(rval, TYPE_BOOL); %} +function Comm::auto_event%(topic: string, ev: any, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->AutoEvent(topic->CheckString(), ev, flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::auto_event_stop%(topic: string, ev: any%): bool + %{ + auto rval = comm_mgr->AutoEventStop(topic->CheckString(), ev); + return new Val(rval, TYPE_BOOL); + %} + function Comm::subscribe_to_events%(topic_prefix: string%): bool %{ auto rval = comm_mgr->SubscribeToEvents(topic_prefix->CheckString()); From 2b598e3d5a582b61ab43d43d52134a95e7e45336 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 26 Jan 2015 14:24:42 -0600 Subject: [PATCH 026/256] broker integration: add remote logging It now works a bit differently than before: whether to send a remote log write is now a property of the logging stream, not the logging filter and it's now up the the receiver side filters to instantiate the desired writer. i.e. the sender now has no say in what the receiver should use as the log writer backend. Under the new style of remote logging, the "Log::enable_remote_logging" option is repurposed to set the default behavior for new logging streams. There's also "Comm::{enable,disable}_remote_logging()" to explicitly set the desired behavior for a given logging stream. To receive remote logs, one calls "Comm::subscribe_to_logs()", where senders implicitly use topics of the form "bro/log/". --- aux/broker | 2 +- src/comm/Data.cc | 2 +- src/comm/Manager.cc | 137 +++++++++++++++++++++++++++++++++++++++-- src/comm/Manager.h | 21 +++++-- src/comm/comm.bif | 34 ++++++++++ src/logging/Manager.cc | 66 ++++++++++++++++++++ src/logging/Manager.h | 10 +++ 7 files changed, 260 insertions(+), 12 deletions(-) diff --git a/aux/broker b/aux/broker index 1e8d675790..425bab3bf4 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 1e8d6757909750524c15f8eaf3c297243bc55425 +Subproject commit 425bab3bf420898d8dbd14280f94aee9d420f617 diff --git a/src/comm/Data.cc b/src/comm/Data.cc index 58d5b30085..b279b97529 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -332,7 +332,7 @@ struct val_converter { rval->Assign(i, item_val); } - return nullptr; + return rval; } }; diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index d803d64ae7..ffe68970a8 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -7,9 +7,16 @@ #include "Var.h" #include "Reporter.h" #include "comm/comm.bif.h" +#include "logging/Manager.h" using namespace std; +VectorType* comm::Manager::vector_of_data_type; +EnumType* comm::Manager::log_id_type; +int comm::Manager::send_flags_self_idx; +int comm::Manager::send_flags_peers_idx; +int comm::Manager::send_flags_unsolicited_idx; + bool comm::Manager::InitPreScript() { return true; @@ -33,6 +40,8 @@ bool comm::Manager::InitPostScript() send_flags_peers_idx = require_field(send_flags_type, "peers"); send_flags_unsolicited_idx = require_field(send_flags_type, "unsolicited"); + log_id_type = internal_type("Log::ID")->AsEnumType(); + comm::opaque_of_data_type = new OpaqueType("Comm::Data"); vector_of_data_type = new VectorType(internal_type("Comm::Data")->Ref()); @@ -103,7 +112,7 @@ bool comm::Manager::Disconnect(const string& addr, uint16_t port) bool comm::Manager::Print(string topic, string msg, const Val* flags) { - endpoint->send(move(topic), broker::message{move(msg)}, get_flags(flags)); + endpoint->send(move(topic), broker::message{move(msg)}, GetFlags(flags)); return true; } @@ -113,6 +122,34 @@ bool comm::Manager::Event(std::string topic, broker::message msg, int flags) return true; } +bool comm::Manager::Log(const EnumVal* stream, const RecordVal* columns, + int flags) + { + auto stream_name = stream->Type()->AsEnumType()->Lookup(stream->AsEnum()); + + if ( ! stream_name ) + { + reporter->Error("Failed to remotely log: stream %d doesn't have name", + stream->AsEnum()); + return false; + } + + auto opt_column_data = val_to_data(columns); + + if ( ! opt_column_data ) + { + reporter->Error("Failed to remotely log stream %s: unsupported types", + stream_name); + return false; + } + + broker::message msg{broker::enum_value{stream_name}, + move(*opt_column_data)}; + std::string topic = std::string("bro/log/") + stream_name; + endpoint->send(move(topic), move(msg), flags); + return true; + } + bool comm::Manager::Event(std::string topic, const RecordVal* args, const Val* flags) { @@ -132,7 +169,7 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args, msg.emplace_back(data_val->data); } - endpoint->send(move(topic), move(msg), get_flags(flags)); + endpoint->send(move(topic), move(msg), GetFlags(flags)); return true; } @@ -161,7 +198,7 @@ bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags) return false; } - handler->AutoRemote(move(topic), get_flags(flags)); + handler->AutoRemote(move(topic), GetFlags(flags)); return true; } @@ -294,7 +331,23 @@ bool comm::Manager::UnsubscribeToEvents(const string& topic_prefix) return event_subscriptions.erase(topic_prefix); } -int comm::Manager::get_flags(const Val* flags) +bool comm::Manager::SubscribeToLogs(string topic_prefix) + { + auto& q = log_subscriptions[topic_prefix]; + + if ( q ) + return false; + + q = broker::message_queue(move(topic_prefix), *endpoint); + return true; + } + +bool comm::Manager::UnsubscribeToLogs(const string& topic_prefix) + { + return log_subscriptions.erase(topic_prefix); + } + +int comm::Manager::GetFlags(const Val* flags) { auto r = flags->AsRecordVal(); int rval = 0; @@ -327,6 +380,9 @@ void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, for ( const auto& ps : event_subscriptions ) read->Insert(ps.second.fd()); + + for ( const auto& ps : log_subscriptions ) + read->Insert(ps.second.fd()); } double comm::Manager::NextTimestamp(double* local_network_time) @@ -493,5 +549,78 @@ void comm::Manager::Process() } } + struct unref_guard { + unref_guard(Val* v) : val(v) {} + ~unref_guard() { Unref(val); } + Val* val; + }; + + for ( const auto& ls : log_subscriptions ) + { + auto log_messages = ls.second.want_pop(); + + if ( log_messages.empty() ) + continue; + + idle = false; + + for ( auto& lm : log_messages ) + { + if ( lm.size() != 2 ) + { + reporter->Warning("got bad remote log size: %zd (expect 2)", + lm.size()); + continue; + } + + if ( ! broker::get(lm[0]) ) + { + reporter->Warning("got remote log w/o stream id: %d", + static_cast(broker::which(lm[0]))); + continue; + } + + if ( ! broker::get(lm[1]) ) + { + reporter->Warning("got remote log w/o columns: %d", + static_cast(broker::which(lm[1]))); + continue; + } + + auto stream_id = data_to_val(move(lm[0]), log_id_type); + + if ( ! stream_id ) + { + reporter->Warning("failed to unpack remote log stream id"); + continue; + } + + unref_guard stream_id_unreffer{stream_id}; + auto columns_type = log_mgr->StreamColumns(stream_id->AsEnumVal()); + + if ( ! columns_type ) + { + reporter->Warning("got remote log for unknown stream: %s", + stream_id->Type()->AsEnumType()->Lookup( + stream_id->AsEnum())); + continue; + } + + auto columns = data_to_val(move(lm[1]), columns_type); + + if ( ! columns ) + { + reporter->Warning("failed to unpack remote log stream columns" + " for stream: %s", + stream_id->Type()->AsEnumType()->Lookup( + stream_id->AsEnum())); + continue; + } + + log_mgr->Write(stream_id->AsEnumVal(), columns->AsRecordVal()); + Unref(columns); + } + } + SetIdle(idle); } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 70bec51ded..3c1e80827b 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -8,6 +8,7 @@ #include #include "Reporter.h" #include "iosource/IOSource.h" +#include "Val.h" namespace comm { @@ -34,6 +35,8 @@ public: bool Event(std::string topic, broker::message msg, int flags); bool Event(std::string topic, const RecordVal* args, const Val* flags); + bool Log(const EnumVal* stream_id, const RecordVal* columns, int flags); + bool AutoEvent(std::string topic, const Val* event, const Val* flags); bool AutoEventStop(const std::string& topic, const Val* event); @@ -48,9 +51,13 @@ public: bool UnsubscribeToEvents(const std::string& topic_prefix); -private: + bool SubscribeToLogs(std::string topic_prefix); - int get_flags(const Val* flags); + bool UnsubscribeToLogs(const std::string& topic_prefix); + + static int GetFlags(const Val* flags); + +private: // IOSource interface overrides: void GetFds(iosource::FD_Set* read, iosource::FD_Set* write, @@ -67,12 +74,14 @@ private: std::map, broker::peering> peers; std::map print_subscriptions; std::map event_subscriptions; + std::map log_subscriptions; - int send_flags_self_idx; - int send_flags_peers_idx; - int send_flags_unsolicited_idx; + static VectorType* vector_of_data_type; + static EnumType* log_id_type; + static int send_flags_self_idx; + static int send_flags_peers_idx; + static int send_flags_unsolicited_idx; - VectorType* vector_of_data_type; }; } // namespace comm diff --git a/src/comm/comm.bif b/src/comm/comm.bif index c185120126..e1c2bc533f 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -2,6 +2,7 @@ %%{ #include "comm/Manager.h" #include "comm/Data.h" +#include "logging/Manager.h" %%} module Comm; @@ -124,3 +125,36 @@ function Comm::unsubscribe_to_events%(topic_prefix: string%): bool auto rval = comm_mgr->UnsubscribeToEvents(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} + +function +Comm::enable_remote_logs%(id: Log::ID, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = log_mgr->EnableRemoteLogs(id->AsEnumVal(), + comm::Manager::GetFlags(flags)); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::disable_remote_logs%(id: Log::ID%): bool + %{ + auto rval = log_mgr->DisableRemoteLogs(id->AsEnumVal()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::remote_logs_enabled%(id: Log::ID%): bool + %{ + auto rval = log_mgr->RemoteLogsAreEnabled(id->AsEnumVal()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_logs%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->SubscribeToLogs(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_logs%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->UnsubscribeToLogs(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 1fe5db3b26..d6d7fbb908 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -16,6 +16,10 @@ #include "WriterBackend.h" #include "logging.bif.h" +#ifdef ENABLE_BROKER +#include "comm/Manager.h" +#endif + using namespace logging; struct Manager::Filter { @@ -69,6 +73,11 @@ struct Manager::Stream { WriterMap writers; // Writers indexed by id/path pair. +#ifdef ENABLE_BROKER + bool enable_remote; + int remote_flags; +#endif + ~Stream(); }; @@ -287,6 +296,11 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval) streams[idx]->event = event ? event_registry->Lookup(event->Name()) : 0; streams[idx]->columns = columns->Ref()->AsRecordType(); +#ifdef ENABLE_BROKER + streams[idx]->enable_remote = internal_val("Log::enable_remote_logging")->AsBool(); + streams[idx]->remote_flags = broker::PEERS; +#endif + DBG_LOG(DBG_LOGGING, "Created new logging stream '%s', raising event %s", streams[idx]->name.c_str(), event ? streams[idx]->event->Name() : ""); @@ -828,6 +842,11 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) #endif } +#ifdef ENABLE_BROKER + if ( stream->enable_remote ) + comm_mgr->Log(id, columns, stream->remote_flags); +#endif + Unref(columns); if ( error ) @@ -1206,6 +1225,53 @@ void Manager::Terminate() } } +#ifdef ENABLE_BROKER + +bool Manager::EnableRemoteLogs(EnumVal* stream_id, int flags) + { + auto stream = FindStream(stream_id); + + if ( ! stream ) + return false; + + stream->enable_remote = true; + stream->remote_flags = flags; + return true; + } + +bool Manager::DisableRemoteLogs(EnumVal* stream_id) + { + auto stream = FindStream(stream_id); + + if ( ! stream ) + return false; + + stream->enable_remote = false; + return true; + } + +bool Manager::RemoteLogsAreEnabled(EnumVal* stream_id) + { + auto stream = FindStream(stream_id); + + if ( ! stream ) + return false; + + return stream->enable_remote; + } + +RecordType* Manager::StreamColumns(EnumVal* stream_id) + { + auto stream = FindStream(stream_id); + + if ( ! stream ) + return nullptr; + + return stream->columns; + } + +#endif + // Timer which on dispatching rotates the filter. class RotationTimer : public Timer { public: diff --git a/src/logging/Manager.h b/src/logging/Manager.h index b8264927a3..8130a1ddd4 100644 --- a/src/logging/Manager.h +++ b/src/logging/Manager.h @@ -157,6 +157,16 @@ public: */ void Terminate(); +#ifdef ENABLE_BROKER + bool EnableRemoteLogs(EnumVal* stream_id, int flags); + + bool DisableRemoteLogs(EnumVal* stream_id); + + bool RemoteLogsAreEnabled(EnumVal* stream_id); + + RecordType* StreamColumns(EnumVal* stream_id); +#endif + protected: friend class WriterFrontend; friend class RotationFinishedMessage; From 55275436016f96e0fd77ffd1e921fd7a96fe1e0d Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 26 Jan 2015 16:53:13 -0600 Subject: [PATCH 027/256] broker integration: add unit tests for remote log/print/event --- aux/broker | 2 +- src/comm/Manager.cc | 4 +- src/comm/Manager.h | 3 +- src/comm/comm.bif | 6 +- src/main.cc | 2 +- .../Baseline/comm.remote_event/recv.recv.out | 6 ++ .../Baseline/comm.remote_event/send.send.out | 13 +++ .../Baseline/comm.remote_log/recv.recv.out | 6 ++ .../Baseline/comm.remote_log/recv.test.log | 15 +++ .../Baseline/comm.remote_log/send.send.out | 1 + .../Baseline/comm.remote_log/send.test.log | 15 +++ .../Baseline/comm.remote_print/recv.recv.out | 6 ++ .../Baseline/comm.remote_print/send.send.out | 7 ++ testing/btest/btest.cfg | 2 +- testing/btest/comm/remote_event.test | 100 ++++++++++++++++++ testing/btest/comm/remote_log.test | 87 +++++++++++++++ testing/btest/comm/remote_print.test | 66 ++++++++++++ 17 files changed, 333 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/comm.remote_event/recv.recv.out create mode 100644 testing/btest/Baseline/comm.remote_event/send.send.out create mode 100644 testing/btest/Baseline/comm.remote_log/recv.recv.out create mode 100644 testing/btest/Baseline/comm.remote_log/recv.test.log create mode 100644 testing/btest/Baseline/comm.remote_log/send.send.out create mode 100644 testing/btest/Baseline/comm.remote_log/send.test.log create mode 100644 testing/btest/Baseline/comm.remote_print/recv.recv.out create mode 100644 testing/btest/Baseline/comm.remote_print/send.send.out create mode 100644 testing/btest/comm/remote_event.test create mode 100644 testing/btest/comm/remote_log.test create mode 100644 testing/btest/comm/remote_print.test diff --git a/aux/broker b/aux/broker index 425bab3bf4..ebc66f484a 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 425bab3bf420898d8dbd14280f94aee9d420f617 +Subproject commit ebc66f484af27a32dc5d91b1c985638847e35cf6 diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index ffe68970a8..bc0bc3f8a8 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -72,9 +72,9 @@ bool comm::Manager::InitPostScript() return true; } -bool comm::Manager::Listen(uint16_t port, const char* addr) +bool comm::Manager::Listen(uint16_t port, const char* addr, bool reuse_addr) { - auto rval = endpoint->listen(port, addr); + auto rval = endpoint->listen(port, addr, reuse_addr); if ( ! rval ) { diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 3c1e80827b..5e3ec350b8 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -23,7 +23,8 @@ public: bool InitPostScript(); - bool Listen(uint16_t port, const char* addr = nullptr); + bool Listen(uint16_t port, const char* addr = nullptr, + bool reuse_addr = true); bool Connect(std::string addr, uint16_t port, std::chrono::duration retry_interval); diff --git a/src/comm/comm.bif b/src/comm/comm.bif index e1c2bc533f..ebe206d266 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -28,7 +28,8 @@ event Comm::remote_connection_broken%(peer_address: string, event Comm::remote_connection_incompatible%(peer_address: string, peer_port: port%); -function Comm::listen%(p: port, a: string &default = ""%): bool +function Comm::listen%(p: port, a: string &default = "", + reuse: bool &default = T%): bool %{ if ( ! p->IsTCP() ) { @@ -36,7 +37,8 @@ function Comm::listen%(p: port, a: string &default = ""%): bool return new Val(false, TYPE_BOOL); } - auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0); + auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0, + reuse); return new Val(rval, TYPE_BOOL); %} diff --git a/src/main.cc b/src/main.cc index a7099cb90b..5385ca7993 100644 --- a/src/main.cc +++ b/src/main.cc @@ -944,7 +944,7 @@ int main(int argc, char** argv) #ifdef ENABLE_BROKER comm_mgr->InitPostScript(); - iosource_mgr->Register(comm_mgr); + iosource_mgr->Register(comm_mgr, true); #endif #ifdef USE_PERFTOOLS_DEBUG diff --git a/testing/btest/Baseline/comm.remote_event/recv.recv.out b/testing/btest/Baseline/comm.remote_event/recv.recv.out new file mode 100644 index 0000000000..7dab0284ea --- /dev/null +++ b/testing/btest/Baseline/comm.remote_event/recv.recv.out @@ -0,0 +1,6 @@ +got event msg, ping, 0 +got event msg, ping, 1 +got event msg, ping, 2 +got event msg, ping, 3 +got event msg, ping, 4 +got event msg, ping, 5 diff --git a/testing/btest/Baseline/comm.remote_event/send.send.out b/testing/btest/Baseline/comm.remote_event/send.send.out new file mode 100644 index 0000000000..ef1f7bc7e1 --- /dev/null +++ b/testing/btest/Baseline/comm.remote_event/send.send.out @@ -0,0 +1,13 @@ +Comm::remote_connection_established, 127.0.0.1, 9999/tcp +got event msg, pong, 0 +got auto event msg, ping, 0 +got event msg, pong, 1 +got auto event msg, ping, 1 +got event msg, pong, 2 +got auto event msg, ping, 2 +got event msg, pong, 3 +got auto event msg, ping, 3 +got event msg, pong, 4 +got auto event msg, ping, 4 +got event msg, pong, 5 +got auto event msg, ping, 5 diff --git a/testing/btest/Baseline/comm.remote_log/recv.recv.out b/testing/btest/Baseline/comm.remote_log/recv.recv.out new file mode 100644 index 0000000000..3e0957442d --- /dev/null +++ b/testing/btest/Baseline/comm.remote_log/recv.recv.out @@ -0,0 +1,6 @@ +wrote log, [msg=ping, num=0] +wrote log, [msg=ping, num=1] +wrote log, [msg=ping, num=2] +wrote log, [msg=ping, num=3] +wrote log, [msg=ping, num=4] +wrote log, [msg=ping, num=5] diff --git a/testing/btest/Baseline/comm.remote_log/recv.test.log b/testing/btest/Baseline/comm.remote_log/recv.test.log new file mode 100644 index 0000000000..0d6dae756c --- /dev/null +++ b/testing/btest/Baseline/comm.remote_log/recv.test.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path test +#open 2015-01-26-22-47-11 +#fields msg num +#types string count +ping 0 +ping 1 +ping 2 +ping 3 +ping 4 +ping 5 +#close 2015-01-26-22-47-11 diff --git a/testing/btest/Baseline/comm.remote_log/send.send.out b/testing/btest/Baseline/comm.remote_log/send.send.out new file mode 100644 index 0000000000..0968e6beb9 --- /dev/null +++ b/testing/btest/Baseline/comm.remote_log/send.send.out @@ -0,0 +1 @@ +Comm::remote_connection_established, 127.0.0.1, 9999/tcp diff --git a/testing/btest/Baseline/comm.remote_log/send.test.log b/testing/btest/Baseline/comm.remote_log/send.test.log new file mode 100644 index 0000000000..0d6dae756c --- /dev/null +++ b/testing/btest/Baseline/comm.remote_log/send.test.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path test +#open 2015-01-26-22-47-11 +#fields msg num +#types string count +ping 0 +ping 1 +ping 2 +ping 3 +ping 4 +ping 5 +#close 2015-01-26-22-47-11 diff --git a/testing/btest/Baseline/comm.remote_print/recv.recv.out b/testing/btest/Baseline/comm.remote_print/recv.recv.out new file mode 100644 index 0000000000..6e5a37abbf --- /dev/null +++ b/testing/btest/Baseline/comm.remote_print/recv.recv.out @@ -0,0 +1,6 @@ +got print msg, ping 0 +got print msg, ping 1 +got print msg, ping 2 +got print msg, ping 3 +got print msg, ping 4 +got print msg, ping 5 diff --git a/testing/btest/Baseline/comm.remote_print/send.send.out b/testing/btest/Baseline/comm.remote_print/send.send.out new file mode 100644 index 0000000000..982ee993f6 --- /dev/null +++ b/testing/btest/Baseline/comm.remote_print/send.send.out @@ -0,0 +1,7 @@ +Comm::remote_connection_established, 127.0.0.1, 9999/tcp +got print msg, pong 0 +got print msg, pong 1 +got print msg, pong 2 +got print msg, pong 3 +got print msg, pong 4 +got print msg, pong 5 diff --git a/testing/btest/btest.cfg b/testing/btest/btest.cfg index 43f29d40a1..2eea514357 100644 --- a/testing/btest/btest.cfg +++ b/testing/btest/btest.cfg @@ -1,5 +1,5 @@ [btest] -TestDirs = doc bifs language core scripts istate coverage signatures plugins +TestDirs = doc bifs language core scripts istate coverage signatures plugins comm TmpDir = %(testbase)s/.tmp BaselineDir = %(testbase)s/Baseline IgnoreDirs = .svn CVS .tmp diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test new file mode 100644 index 0000000000..9ab9a6b224 --- /dev/null +++ b/testing/btest/comm/remote_event.test @@ -0,0 +1,100 @@ +# @TEST_SERIALIZE: brokercomm +# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE recv.bro + +redef exit_only_after_terminate = T; + +global event_handler: event(msg: string, c: count); +global auto_event_handler: event(msg: string, c: count); + +event bro_init() + { + Comm::listen(9999/tcp, "127.0.0.1"); + Comm::subscribe_to_events("bro/event/"); + Comm::auto_event("bro/event/my_topic", auto_event_handler); + } + +global event_count = 0; + +event event_handler(msg: string, n: count) + { + event auto_event_handler(msg, n); + print "got event msg", msg, n; + local args = Comm::event_args(event_handler, "pong", event_count); + Comm::event("bro/event/my_topic", args); + ++event_count; + + if ( n == 5 ) + terminate(); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +redef exit_only_after_terminate = T; + +global event_handler: event(msg: string, c: count); +global auto_event_handler: event(msg: string, c: count); + +event bro_init() + { + Comm::subscribe_to_events("bro/event/my_topic"); + Comm::connect("127.0.0.1", 9999/tcp, 1secs); + } + +global event_count = 0; + +event Comm::remote_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::remote_connection_established", peer_address, peer_port; + local args = Comm::event_args(event_handler, "ping", event_count); + Comm::event("bro/event/hi", args); + ++event_count; + } + +global done = F; +global done_auto = F; + +function check_terminate() + { + if ( done && done_auto ) + terminate(); + } + +event event_handler(msg: string, n: count) + { + print "got event msg", msg, n; + local args = Comm::event_args(event_handler, "ping", event_count); + Comm::event("bro/event/hi", args); + ++event_count; + + if ( n == 5 ) + { + done = T; + check_terminate(); + } + } + +event auto_event_handler(msg: string, n: count) + { + print "got auto event msg", msg, n; + + if ( n == 5 ) + { + done_auto = T; + check_terminate(); + } + } + +@TEST-END-FILE diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test new file mode 100644 index 0000000000..aea88cdc25 --- /dev/null +++ b/testing/btest/comm/remote_log.test @@ -0,0 +1,87 @@ +# @TEST_SERIALIZE: brokercomm +# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + +# @TEST-EXEC: btest-bg-run recv "bro -b ../common.bro ../recv.bro >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../common.bro ../send.bro >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff recv/test.log +# @TEST-EXEC: btest-diff send/send.out +# @TEST-EXEC: btest-diff send/test.log + +@TEST-START-FILE common.bro + +module Test; + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + msg: string &log; + num: count &log; + }; + + global log_test: event(rec: Test::Info); + + event bro_init() &priority=5 + { + Log::create_stream(Test::LOG, [$columns=Test::Info, $ev=log_test]); + } +} + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::listen(9999/tcp, "127.0.0.1"); + Comm::subscribe_to_logs("bro/log/"); + } + +event Test::log_test(rec: Test::Info) + { + print "wrote log", rec; + + if ( rec$num == 5 ) + terminate(); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::enable_remote_logs(Test::LOG); + Comm::connect("127.0.0.1", 9999/tcp, 1secs); + } + +global n = 0; + +event do_write() + { + if ( n == 6 ) + terminate(); + else + { + Log::write(Test::LOG, [$msg = "ping", $num = n]); + ++n; + event do_write(); + } + } + +event Comm::remote_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::remote_connection_established", peer_address, peer_port; + event do_write(); + } + +@TEST-END-FILE diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test new file mode 100644 index 0000000000..48dfd98bed --- /dev/null +++ b/testing/btest/comm/remote_print.test @@ -0,0 +1,66 @@ +# @TEST_SERIALIZE: brokercomm +# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE recv.bro + +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::listen(9999/tcp, "127.0.0.1"); + Comm::subscribe_to_prints("bro/print/"); + } + +global n = 0; + +event Comm::print_handler(msg: string) + { + print "got print msg", msg; + Comm::print("bro/print/my_topic", fmt("pong %d", n)); + ++n; + + if ( msg == "ping 5" ) + terminate(); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::subscribe_to_prints("bro/print/my_topic"); + Comm::connect("127.0.0.1", 9999/tcp, 1secs); + } + +global n = 0; + +event Comm::remote_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::remote_connection_established", peer_address, peer_port; + Comm::print("bro/print/hi", fmt("ping %d", n)); + ++n; + } + +event Comm::print_handler(msg: string) + { + print "got print msg", msg; + Comm::print("bro/print/hi", fmt("ping %d", n)); + ++n; + + if ( msg == "pong 5" ) + terminate(); + } + +@TEST-END-FILE From 0537711fd4b83ded01e430bd8d6192fcc3619bdd Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 27 Jan 2015 10:48:05 -0600 Subject: [PATCH 028/256] update broker submodule --- aux/broker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broker b/aux/broker index ebc66f484a..177bdfac2c 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit ebc66f484af27a32dc5d91b1c985638847e35cf6 +Subproject commit 177bdfac2c768d9ed8f3edb10e9e2dbd0d6f8723 From d2ea87735a5a9cb34c5df4a4d4de83d399681e53 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 29 Jan 2015 10:42:48 -0600 Subject: [PATCH 029/256] broker integration: add bifs to inspect/manipulate broker data i.e. script-layer functions to convert between bro values and broker values; mostly for use w/ Bro's data store interface (coming soon). --- scripts/base/frameworks/comm/main.bro | 5 + src/Reporter.cc | 13 + src/Reporter.h | 4 + src/comm/Data.cc | 168 ++++++++- src/comm/Data.h | 155 +++++++- src/comm/Manager.cc | 26 +- src/comm/Manager.h | 15 +- src/comm/comm.bif | 490 ++++++++++++++++++++++++++ testing/btest/Baseline/comm.data/out | 99 ++++++ testing/btest/comm/data.bro | 219 ++++++++++++ 10 files changed, 1154 insertions(+), 40 deletions(-) create mode 100644 testing/btest/Baseline/comm.data/out create mode 100644 testing/btest/comm/data.bro diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index efe3069a1c..974e5e43af 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -19,4 +19,9 @@ export { name: string &optional; # nil for invalid event/args. args: vector of Comm::Data; }; + + type Comm::TableItem : record { + key: Comm::Data; + val: Comm::Data; + }; } diff --git a/src/Reporter.cc b/src/Reporter.cc index 9002633b10..cd1aa09d4c 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -123,6 +123,19 @@ void Reporter::ExprRuntimeError(const Expr* expr, const char* fmt, ...) throw InterpreterException(); } +void Reporter::RuntimeError(const Location* location, const char* fmt, ...) + { + ++errors; + PushLocation(location); + va_list ap; + va_start(ap, fmt); + FILE* out = errors_to_stderr ? stderr : 0; + DoLog("runtime error", reporter_error, out, 0, 0, true, true, "", fmt, ap); + va_end(ap); + PopLocation(); + throw InterpreterException(); + } + void Reporter::InternalError(const char* fmt, ...) { va_list ap; diff --git a/src/Reporter.h b/src/Reporter.h index e477ad8934..52bcd7d02a 100644 --- a/src/Reporter.h +++ b/src/Reporter.h @@ -73,6 +73,10 @@ public: // function will not return but raise an InterpreterException. void ExprRuntimeError(const Expr* expr, const char* fmt, ...); + // Report a runtime error in evaluating a Bro script expression. This + // function will not return but raise an InterpreterException. + void RuntimeError(const Location* location, const char* fmt, ...); + // Report a traffic weirdness, i.e., an unexpected protocol situation // that may lead to incorrectly processing a connnection. void Weird(const char* name); // Raises net_weird(). diff --git a/src/comm/Data.cc b/src/comm/Data.cc index b279b97529..f32bedd885 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -4,6 +4,10 @@ using namespace std; OpaqueType* comm::opaque_of_data_type; +OpaqueType* comm::opaque_of_set_iterator; +OpaqueType* comm::opaque_of_table_iterator; +OpaqueType* comm::opaque_of_vector_iterator; +OpaqueType* comm::opaque_of_record_iterator; static broker::port::protocol to_broker_port_proto(TransportProto tp) { @@ -20,7 +24,7 @@ static broker::port::protocol to_broker_port_proto(TransportProto tp) } } -static TransportProto to_bro_port_proto(broker::port::protocol tp) +TransportProto comm::to_bro_port_proto(broker::port::protocol tp) { switch ( tp ) { case broker::port::protocol::tcp: @@ -70,7 +74,7 @@ struct val_converter { return nullptr; } - result_type operator()(const std::string& a) + result_type operator()(std::string& a) { switch ( type->Tag() ) { case TYPE_STRING: @@ -103,7 +107,7 @@ struct val_converter { } } - result_type operator()(const broker::address& a) + result_type operator()(broker::address& a) { if ( type->Tag() == TYPE_ADDR ) { @@ -114,7 +118,7 @@ struct val_converter { return nullptr; } - result_type operator()(const broker::subnet& a) + result_type operator()(broker::subnet& a) { if ( type->Tag() == TYPE_SUBNET ) { @@ -125,15 +129,15 @@ struct val_converter { return nullptr; } - result_type operator()(const broker::port& a) + result_type operator()(broker::port& a) { if ( type->Tag() == TYPE_PORT ) - return new PortVal(a.number(), to_bro_port_proto(a.type())); + return new PortVal(a.number(), comm::to_bro_port_proto(a.type())); return nullptr; } - result_type operator()(const broker::time_point& a) + result_type operator()(broker::time_point& a) { if ( type->Tag() == TYPE_TIME ) return new Val(a.value, TYPE_TIME); @@ -141,7 +145,7 @@ struct val_converter { return nullptr; } - result_type operator()(const broker::time_duration& a) + result_type operator()(broker::time_duration& a) { if ( type->Tag() == TYPE_INTERVAL ) return new Val(a.value, TYPE_INTERVAL); @@ -149,7 +153,7 @@ struct val_converter { return nullptr; } - result_type operator()(const broker::enum_value& a) + result_type operator()(broker::enum_value& a) { if ( type->Tag() == TYPE_ENUM ) { @@ -175,12 +179,13 @@ struct val_converter { for ( auto& item : a ) { + broker::vector composite_key; auto indices = broker::get(item); if ( ! indices ) { - Unref(rval); - return nullptr; + composite_key.emplace_back(move(item)); + indices = &composite_key; } auto expected_index_types = tt->Indices()->Types(); @@ -226,12 +231,13 @@ struct val_converter { for ( auto& item : a ) { + broker::vector composite_key; auto indices = broker::get(item.first); if ( ! indices ) { - Unref(rval); - return nullptr; + composite_key.emplace_back(move(item.first)); + indices = &composite_key; } auto expected_index_types = tt->Indices()->Types(); @@ -341,7 +347,7 @@ Val* comm::data_to_val(broker::data d, BroType* type) return broker::visit(val_converter{type}, d); } -broker::util::optional comm::val_to_data(const Val* v) +broker::util::optional comm::val_to_data(Val* v) { switch ( v->Type()->Tag() ) { case TYPE_BOOL: @@ -388,7 +394,7 @@ broker::util::optional comm::val_to_data(const Val* v) { auto enum_type = v->Type()->AsEnumType(); auto enum_name = enum_type->Lookup(v->AsEnum()); - return {broker::enum_value(enum_name ? "" : enum_name)}; + return {broker::enum_value(enum_name ? enum_name : "")}; } case TYPE_STRING: { @@ -433,7 +439,9 @@ broker::util::optional comm::val_to_data(const Val* v) auto entry = table->NextEntry(k, c); auto vl = table_val->RecoverIndex(k); iter_guard ig(k, vl); - broker::vector key; + + broker::vector composite_key; + composite_key.reserve(vl->Length()); for ( auto k = 0; k < vl->Length(); ++k ) { @@ -442,9 +450,16 @@ broker::util::optional comm::val_to_data(const Val* v) if ( ! key_part ) return {}; - key.emplace_back(move(*key_part)); + composite_key.emplace_back(move(*key_part)); } + broker::data key; + + if ( composite_key.size() == 1 ) + key = move(composite_key[0]); + else + key = move(composite_key); + if ( is_set ) broker::get(rval)->emplace(move(key)); else @@ -521,7 +536,7 @@ broker::util::optional comm::val_to_data(const Val* v) return {}; } -RecordVal* comm::make_data_val(const Val* v) +RecordVal* comm::make_data_val(Val* v) { auto rval = new RecordVal(BifType::Record::Comm::Data); auto data = val_to_data(v); @@ -531,3 +546,120 @@ RecordVal* comm::make_data_val(const Val* v) return rval; } + +RecordVal* comm::make_data_val(broker::data d) + { + auto rval = new RecordVal(BifType::Record::Comm::Data); + rval->Assign(0, new DataVal(move(d))); + return rval; + } + +struct data_type_getter { + using result_type = EnumVal*; + + result_type operator()(bool a) + { + return new EnumVal(BifEnum::Comm::BOOL, + BifType::Enum::Comm::DataType); + } + + result_type operator()(uint64_t a) + { + return new EnumVal(BifEnum::Comm::COUNT, + BifType::Enum::Comm::DataType); + } + + result_type operator()(int64_t a) + { + return new EnumVal(BifEnum::Comm::INT, + BifType::Enum::Comm::DataType); + } + + result_type operator()(double a) + { + return new EnumVal(BifEnum::Comm::DOUBLE, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const std::string& a) + { + return new EnumVal(BifEnum::Comm::STRING, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::address& a) + { + return new EnumVal(BifEnum::Comm::ADDR, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::subnet& a) + { + return new EnumVal(BifEnum::Comm::SUBNET, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::port& a) + { + return new EnumVal(BifEnum::Comm::PORT, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::time_point& a) + { + return new EnumVal(BifEnum::Comm::TIME, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::time_duration& a) + { + return new EnumVal(BifEnum::Comm::INTERVAL, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::enum_value& a) + { + return new EnumVal(BifEnum::Comm::ENUM, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::set& a) + { + return new EnumVal(BifEnum::Comm::SET, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::table& a) + { + return new EnumVal(BifEnum::Comm::TABLE, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::vector& a) + { + return new EnumVal(BifEnum::Comm::VECTOR, + BifType::Enum::Comm::DataType); + } + + result_type operator()(const broker::record& a) + { + return new EnumVal(BifEnum::Comm::RECORD, + BifType::Enum::Comm::DataType); + } +}; + +EnumVal* comm::get_data_type(RecordVal* v, Frame* frame) + { + return broker::visit(data_type_getter{}, opaque_field_to_data(v, frame)); + } + +broker::data& comm::opaque_field_to_data(RecordVal* v, Frame* f) + { + Val* d = v->Lookup(0); + + if ( ! d ) + reporter->RuntimeError(f->GetCall()->GetLocationInfo(), + "Comm::Data's opaque field is not set"); + + return static_cast(d)->data; + } diff --git a/src/comm/Data.h b/src/comm/Data.h index e3197b61da..c720dcda71 100644 --- a/src/comm/Data.h +++ b/src/comm/Data.h @@ -3,14 +3,27 @@ #include #include "Val.h" +#include "Reporter.h" +#include "Frame.h" +#include "Expr.h" namespace comm { extern OpaqueType* opaque_of_data_type; +extern OpaqueType* opaque_of_set_iterator; +extern OpaqueType* opaque_of_table_iterator; +extern OpaqueType* opaque_of_vector_iterator; +extern OpaqueType* opaque_of_record_iterator; -RecordVal* make_data_val(const Val* v); +TransportProto to_bro_port_proto(broker::port::protocol tp); -broker::util::optional val_to_data(const Val* v); +RecordVal* make_data_val(Val* v); + +RecordVal* make_data_val(broker::data d); + +EnumVal* get_data_type(RecordVal* v, Frame* frame); + +broker::util::optional val_to_data(Val* v); Val* data_to_val(broker::data d, BroType* type); @@ -21,9 +34,147 @@ public: : OpaqueVal(comm::opaque_of_data_type), data(std::move(arg_data)) {} + void ValDescribe(ODesc* d) const override + { + d->Add("broker::data{"); + d->Add(broker::to_string(data)); + d->Add("}"); + } + broker::data data; }; +struct type_name_getter { + using result_type = const char*; + + result_type operator()(bool a) + { return "bool"; } + + result_type operator()(uint64_t a) + { return "uint64_t"; } + + result_type operator()(int64_t a) + { return "int64_t"; } + + result_type operator()(double a) + { return "double"; } + + result_type operator()(const std::string& a) + { return "string"; } + + result_type operator()(const broker::address& a) + { return "address"; } + + result_type operator()(const broker::subnet& a) + { return "subnet"; } + + result_type operator()(const broker::port& a) + { return "port"; } + + result_type operator()(const broker::time_point& a) + { return "time"; } + + result_type operator()(const broker::time_duration& a) + { return "interval"; } + + result_type operator()(const broker::enum_value& a) + { return "enum"; } + + result_type operator()(const broker::set& a) + { return "set"; } + + result_type operator()(const broker::table& a) + { return "table"; } + + result_type operator()(const broker::vector& a) + { return "vector"; } + + result_type operator()(const broker::record& a) + { return "record"; } +}; + +broker::data& opaque_field_to_data(RecordVal* v, Frame* f); + +template +T& require_data_type(broker::data& d, TypeTag tag, Frame* f) + { + auto ptr = broker::get(d); + + if ( ! ptr ) + reporter->RuntimeError(f->GetCall()->GetLocationInfo(), + "data is of type '%s' not of type '%s'", + broker::visit(type_name_getter{}, d), + type_name(tag)); + + return *ptr; + } + +template +inline T& require_data_type(RecordVal* v, TypeTag tag, Frame* f) + { + return require_data_type(opaque_field_to_data(v, f), tag, f); + } + +template +inline Val* refine(RecordVal* v, TypeTag tag, Frame* f) + { + return new Val(require_data_type(v, tag, f), tag); + } + +// Copying data in to iterator vals is not the fastest approach, but safer... + +class SetIterator : public OpaqueVal { +public: + + SetIterator(RecordVal* v, TypeTag tag, Frame* f) + : OpaqueVal(comm::opaque_of_set_iterator), + dat(require_data_type(v, TYPE_TABLE, f)), + it(dat.begin()) + {} + + broker::set dat; + broker::set::iterator it; +}; + +class TableIterator : public OpaqueVal { +public: + + TableIterator(RecordVal* v, TypeTag tag, Frame* f) + : OpaqueVal(comm::opaque_of_table_iterator), + dat(require_data_type(v, TYPE_TABLE, f)), + it(dat.begin()) + {} + + broker::table dat; + broker::table::iterator it; +}; + +class VectorIterator : public OpaqueVal { +public: + + VectorIterator(RecordVal* v, TypeTag tag, Frame* f) + : OpaqueVal(comm::opaque_of_vector_iterator), + dat(require_data_type(v, TYPE_VECTOR, f)), + it(dat.begin()) + {} + + broker::vector dat; + broker::vector::iterator it; +}; + +class RecordIterator : public OpaqueVal { +public: + + RecordIterator(RecordVal* v, TypeTag tag, Frame* f) + : OpaqueVal(comm::opaque_of_record_iterator), + dat(require_data_type(v, TYPE_VECTOR, f)), + it(dat.fields.begin()) + {} + + broker::record dat; + decltype(broker::record::fields)::iterator it; +}; + } // namespace comm #endif // BRO_COMM_DATA_H diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index bc0bc3f8a8..e64c74c377 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -22,7 +22,7 @@ bool comm::Manager::InitPreScript() return true; } -static int require_field(const RecordType* rt, const char* name) +static int require_field(RecordType* rt, const char* name) { auto rval = rt->FieldOffset(name); @@ -43,6 +43,10 @@ bool comm::Manager::InitPostScript() log_id_type = internal_type("Log::ID")->AsEnumType(); comm::opaque_of_data_type = new OpaqueType("Comm::Data"); + comm::opaque_of_set_iterator = new OpaqueType("Comm::SetIterator"); + comm::opaque_of_table_iterator = new OpaqueType("Comm::TableIterator"); + comm::opaque_of_vector_iterator = new OpaqueType("Comm::VectorIterator"); + comm::opaque_of_record_iterator = new OpaqueType("Comm::RecordIterator"); vector_of_data_type = new VectorType(internal_type("Comm::Data")->Ref()); auto res = broker::init(); @@ -110,7 +114,7 @@ bool comm::Manager::Disconnect(const string& addr, uint16_t port) return rval; } -bool comm::Manager::Print(string topic, string msg, const Val* flags) +bool comm::Manager::Print(string topic, string msg, Val* flags) { endpoint->send(move(topic), broker::message{move(msg)}, GetFlags(flags)); return true; @@ -122,8 +126,7 @@ bool comm::Manager::Event(std::string topic, broker::message msg, int flags) return true; } -bool comm::Manager::Log(const EnumVal* stream, const RecordVal* columns, - int flags) +bool comm::Manager::Log(EnumVal* stream, RecordVal* columns, int flags) { auto stream_name = stream->Type()->AsEnumType()->Lookup(stream->AsEnum()); @@ -150,8 +153,7 @@ bool comm::Manager::Log(const EnumVal* stream, const RecordVal* columns, return true; } -bool comm::Manager::Event(std::string topic, const RecordVal* args, - const Val* flags) +bool comm::Manager::Event(std::string topic, RecordVal* args, Val* flags) { if ( ! args->Lookup(0) ) return false; @@ -165,7 +167,7 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args, for ( auto i = 0u; i < vv->Size(); ++i ) { auto val = vv->Lookup(i)->AsRecordVal()->Lookup(0); - auto data_val = dynamic_cast(val); + auto data_val = static_cast(val); msg.emplace_back(data_val->data); } @@ -173,7 +175,7 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args, return true; } -bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags) +bool comm::Manager::AutoEvent(string topic, Val* event, Val* flags) { if ( event->Type()->Tag() != TYPE_FUNC ) { @@ -202,7 +204,7 @@ bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags) return true; } -bool comm::Manager::AutoEventStop(const string& topic, const Val* event) +bool comm::Manager::AutoEventStop(const string& topic, Val* event) { if ( event->Type()->Tag() != TYPE_FUNC ) { @@ -232,12 +234,12 @@ bool comm::Manager::AutoEventStop(const string& topic, const Val* event) return true; } -RecordVal* comm::Manager::MakeEventArgs(const val_list* args) +RecordVal* comm::Manager::MakeEventArgs(val_list* args) { auto rval = new RecordVal(BifType::Record::Comm::EventArgs); auto arg_vec = new VectorVal(vector_of_data_type); rval->Assign(1, arg_vec); - const Func* func; + Func* func; for ( auto i = 0u; i < args->length(); ++i ) { @@ -347,7 +349,7 @@ bool comm::Manager::UnsubscribeToLogs(const string& topic_prefix) return log_subscriptions.erase(topic_prefix); } -int comm::Manager::GetFlags(const Val* flags) +int comm::Manager::GetFlags(Val* flags) { auto r = flags->AsRecordVal(); int rval = 0; diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 5e3ec350b8..44f5eb0f2b 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -31,18 +31,18 @@ public: bool Disconnect(const std::string& addr, uint16_t port); - bool Print(std::string topic, std::string msg, const Val* flags); + bool Print(std::string topic, std::string msg, Val* flags); bool Event(std::string topic, broker::message msg, int flags); - bool Event(std::string topic, const RecordVal* args, const Val* flags); + bool Event(std::string topic, RecordVal* args, Val* flags); - bool Log(const EnumVal* stream_id, const RecordVal* columns, int flags); + bool Log(EnumVal* stream_id, RecordVal* columns, int flags); - bool AutoEvent(std::string topic, const Val* event, const Val* flags); + bool AutoEvent(std::string topic, Val* event, Val* flags); - bool AutoEventStop(const std::string& topic, const Val* event); + bool AutoEventStop(const std::string& topic, Val* event); - RecordVal* MakeEventArgs(const val_list* args); + RecordVal* MakeEventArgs(val_list* args); bool SubscribeToPrints(std::string topic_prefix); @@ -56,7 +56,7 @@ public: bool UnsubscribeToLogs(const std::string& topic_prefix); - static int GetFlags(const Val* flags); + static int GetFlags(Val* flags); private: @@ -82,7 +82,6 @@ private: static int send_flags_self_idx; static int send_flags_peers_idx; static int send_flags_unsolicited_idx; - }; } // namespace comm diff --git a/src/comm/comm.bif b/src/comm/comm.bif index ebe206d266..b2ce0fb415 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -7,17 +7,507 @@ module Comm; +enum DataType %{ + BOOL, + INT, + COUNT, + DOUBLE, + STRING, + ADDR, + SUBNET, + PORT, + TIME, + INTERVAL, + ENUM, + SET, + TABLE, + VECTOR, + RECORD, +%} + type Comm::SendFlags: record; type Comm::Data: record; type Comm::EventArgs: record; +type Comm::TableItem: record; + function Comm::data%(d: any%): Comm::Data %{ return comm::make_data_val(d); %} +function Comm::data_type%(d: Comm::Data%): Comm::DataType + %{ + return comm::get_data_type(d->AsRecordVal(), frame); + %} + +function Comm::refine_to_bool%(d: Comm::Data%): bool + %{ + return comm::refine(d->AsRecordVal(), TYPE_BOOL, frame); + %} + +function Comm::refine_to_int%(d: Comm::Data%): int + %{ + return comm::refine(d->AsRecordVal(), TYPE_INT, frame); + %} + +function Comm::refine_to_count%(d: Comm::Data%): count + %{ + return comm::refine(d->AsRecordVal(), TYPE_COUNT, frame); + %} + +function Comm::refine_to_double%(d: Comm::Data%): double + %{ + return comm::refine(d->AsRecordVal(), TYPE_DOUBLE, frame); + %} + +function Comm::refine_to_string%(d: Comm::Data%): string + %{ + return new StringVal(comm::require_data_type(d->AsRecordVal(), + TYPE_STRING, + frame)); + %} + +function Comm::refine_to_addr%(d: Comm::Data%): addr + %{ + auto& a = comm::require_data_type(d->AsRecordVal(), + TYPE_ADDR, frame); + auto bits = reinterpret_cast(&a.bytes()); + return new AddrVal(IPAddr(*bits)); + %} + +function Comm::refine_to_subnet%(d: Comm::Data%): subnet + %{ + auto& a = comm::require_data_type(d->AsRecordVal(), + TYPE_SUBNET, frame); + auto bits = reinterpret_cast(&a.network().bytes()); + return new SubNetVal(IPPrefix(IPAddr(*bits), a.length())); + %} + +function Comm::refine_to_port%(d: Comm::Data%): port + %{ + auto& a = comm::require_data_type(d->AsRecordVal(), + TYPE_SUBNET, frame); + return new PortVal(a.number(), comm::to_bro_port_proto(a.type())); + %} + +function Comm::refine_to_time%(d: Comm::Data%): time + %{ + auto v = comm::require_data_type(d->AsRecordVal(), + TYPE_TIME, frame).value; + return new Val(v, TYPE_TIME); + %} + +function Comm::refine_to_interval%(d: Comm::Data%): interval + %{ + auto v = comm::require_data_type(d->AsRecordVal(), + TYPE_TIME, frame).value; + return new Val(v, TYPE_INTERVAL); + %} + +function Comm::refine_to_enum_name%(d: Comm::Data%): string + %{ + auto& v = comm::require_data_type(d->AsRecordVal(), + TYPE_ENUM, frame).name; + return new StringVal(v); + %} + +function Comm::set_create%(%): Comm::Data + %{ + return comm::make_data_val(broker::set()); + %} + +function Comm::set_clear%(s: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, + frame); + v.clear(); + return new Val(true, TYPE_BOOL); + %} + +function Comm::set_size%(s: Comm::Data%): count + %{ + auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, + frame); + return new Val(static_cast(v.size()), TYPE_COUNT); + %} + +function Comm::set_contains%(s: Comm::Data, key: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, + frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + return new Val(v.find(k) != v.end(), TYPE_BOOL); + %} + +function Comm::set_insert%(s: Comm::Data, key: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, + frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + return new Val(v.insert(k).second, TYPE_BOOL); + %} + +function Comm::set_remove%(s: Comm::Data, key: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, + frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + return new Val(v.erase(k) > 0, TYPE_BOOL); + %} + +function Comm::set_iterator%(s: Comm::Data%): opaque of Comm::SetIterator + %{ + return new comm::SetIterator(s->AsRecordVal(), TYPE_TABLE, frame); + %} + +function Comm::set_iterator_last%(it: opaque of Comm::SetIterator%): bool + %{ + auto set_it = static_cast(it); + return new Val(set_it->it == set_it->dat.end(), TYPE_BOOL); + %} + +function Comm::set_iterator_next%(it: opaque of Comm::SetIterator%): bool + %{ + auto set_it = static_cast(it); + + if ( set_it->it == set_it->dat.end() ) + return new Val(false, TYPE_BOOL); + + ++set_it->it; + return new Val(set_it->it != set_it->dat.end(), TYPE_BOOL); + %} + +function Comm::set_iterator_value%(it: opaque of Comm::SetIterator%): Comm::Data + %{ + auto set_it = static_cast(it); + auto rval = new RecordVal(BifType::Record::Comm::Data); + + if ( set_it->it == set_it->dat.end() ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Warning("attempt to retrieve value of invalid set iterator"); + reporter->PopLocation(); + return rval; + } + + rval->Assign(0, new comm::DataVal(*set_it->it)); + return rval; + %} + +function Comm::table_create%(%): Comm::Data + %{ + return comm::make_data_val(broker::table()); + %} + +function Comm::table_clear%(t: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + v.clear(); + return new Val(true, TYPE_BOOL); + %} + +function Comm::table_size%(t: Comm::Data%): count + %{ + auto& v = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + return new Val(static_cast(v.size()), TYPE_COUNT); + %} + +function Comm::table_contains%(t: Comm::Data, key: Comm::Data%): bool + %{ + auto& v = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + return new Val(v.find(k) != v.end(), TYPE_BOOL); + %} + +function Comm::table_insert%(t: Comm::Data, key: Comm::Data, val: Comm::Data%): Comm::Data + %{ + auto& table = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + auto& v = comm::opaque_field_to_data(val->AsRecordVal(), frame); + + try + { + auto& prev = table.at(k); + auto rval = comm::make_data_val(move(prev)); + prev = v; + return rval; + } + catch (const std::out_of_range&) + { + table[k] = v; + return new RecordVal(BifType::Record::Comm::Data); + } + %} + +function Comm::table_remove%(t: Comm::Data, key: Comm::Data%): Comm::Data + %{ + auto& table = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + auto it = table.find(k); + + if ( it == table.end() ) + return new RecordVal(BifType::Record::Comm::Data); + else + { + auto rval = comm::make_data_val(move(it->second)); + table.erase(it); + return rval; + } + %} + +function Comm::table_lookup%(t: Comm::Data, key: Comm::Data%): Comm::Data + %{ + auto& table = comm::require_data_type(t->AsRecordVal(), + TYPE_TABLE, frame); + auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame); + auto it = table.find(k); + + if ( it == table.end() ) + return new RecordVal(BifType::Record::Comm::Data); + else + return comm::make_data_val(it->second); + %} + +function Comm::table_iterator%(t: Comm::Data%): opaque of Comm::TableIterator + %{ + return new comm::TableIterator(t->AsRecordVal(), TYPE_TABLE, frame); + %} + +function Comm::table_iterator_last%(it: opaque of Comm::TableIterator%): bool + %{ + auto ti = static_cast(it); + return new Val(ti->it == ti->dat.end(), TYPE_BOOL); + %} + +function Comm::table_iterator_next%(it: opaque of Comm::TableIterator%): bool + %{ + auto ti = static_cast(it); + + if ( ti->it == ti->dat.end() ) + return new Val(false, TYPE_BOOL); + + ++ti->it; + return new Val(ti->it != ti->dat.end(), TYPE_BOOL); + %} + +function Comm::table_iterator_value%(it: opaque of Comm::TableIterator%): Comm::TableItem + %{ + auto ti = static_cast(it); + auto rval = new RecordVal(BifType::Record::Comm::TableItem); + auto key_val = new RecordVal(BifType::Record::Comm::Data); + auto val_val = new RecordVal(BifType::Record::Comm::Data); + rval->Assign(0, key_val); + rval->Assign(1, val_val); + + if ( ti->it == ti->dat.end() ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Warning("attempt to retrieve value of invalid table iterator"); + reporter->PopLocation(); + return rval; + } + + key_val->Assign(0, new comm::DataVal(ti->it->first)); + val_val->Assign(0, new comm::DataVal(ti->it->second)); + return rval; + %} + +function Comm::vector_create%(%): Comm::Data + %{ + return comm::make_data_val(broker::vector()); + %} + +function Comm::vector_clear%(v: Comm::Data%): bool + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + vec.clear(); + return new Val(true, TYPE_BOOL); + %} + +function Comm::vector_size%(v: Comm::Data%): count + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + return new Val(static_cast(vec.size()), TYPE_COUNT); + %} + +function Comm::vector_insert%(v: Comm::Data, d: Comm::Data, idx: count%): bool + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame); + idx = min(idx, static_cast(vec.size())); + vec.insert(vec.begin() + idx, item); + return new Val(true, TYPE_BOOL); + %} + +function Comm::vector_replace%(v: Comm::Data, d: Comm::Data, idx: count%): Comm::Data + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame); + + if ( idx >= vec.size() ) + return new RecordVal(BifType::Record::Comm::Data); + + auto rval = comm::make_data_val(move(vec[idx])); + vec[idx] = item; + return rval; + %} + +function Comm::vector_remove%(v: Comm::Data, idx: count%): Comm::Data + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + + if ( idx >= vec.size() ) + return new RecordVal(BifType::Record::Comm::Data); + + auto rval = comm::make_data_val(move(vec[idx])); + vec.erase(vec.begin() + idx); + return rval; + %} + +function Comm::vector_lookup%(v: Comm::Data, idx: count%): Comm::Data + %{ + auto& vec = comm::require_data_type(v->AsRecordVal(), + TYPE_VECTOR, frame); + + if ( idx >= vec.size() ) + return new RecordVal(BifType::Record::Comm::Data); + + return comm::make_data_val(vec[idx]); + %} + +function Comm::vector_iterator%(v: Comm::Data%): opaque of Comm::VectorIterator + %{ + return new comm::VectorIterator(v->AsRecordVal(), TYPE_VECTOR, frame); + %} + +function Comm::vector_iterator_last%(it: opaque of Comm::VectorIterator%): bool + %{ + auto vi = static_cast(it); + return new Val(vi->it == vi->dat.end(), TYPE_BOOL); + %} + +function Comm::vector_iterator_next%(it: opaque of Comm::VectorIterator%): bool + %{ + auto vi = static_cast(it); + + if ( vi->it == vi->dat.end() ) + return new Val(false, TYPE_BOOL); + + ++vi->it; + return new Val(vi->it != vi->dat.end(), TYPE_BOOL); + %} + +function Comm::vector_iterator_value%(it: opaque of Comm::VectorIterator%): Comm::Data + %{ + auto vi = static_cast(it); + auto rval = new RecordVal(BifType::Record::Comm::Data); + + if ( vi->it == vi->dat.end() ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Warning("attempt to retrieve value of invalid table iterator"); + reporter->PopLocation(); + return rval; + } + + rval->Assign(0, new comm::DataVal(*vi->it)); + return rval; + %} + +function Comm::record_create%(sz: count%): Comm::Data + %{ + return comm::make_data_val(broker::record(std::vector(sz))); + %} + +function Comm::record_size%(r: Comm::Data%): count + %{ + auto& v = comm::require_data_type(r->AsRecordVal(), + TYPE_RECORD, frame); + return new Val(static_cast(v.fields.size()), TYPE_COUNT); + %} + +function Comm::record_assign%(r: Comm::Data, d: Comm::Data, idx: count%): bool + %{ + auto& v = comm::require_data_type(r->AsRecordVal(), + TYPE_RECORD, frame); + auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame); + + if ( idx >= v.fields.size() ) + return new Val(false, TYPE_BOOL); + + v.fields[idx] = item; + return new Val(true, TYPE_BOOL); + %} + +function Comm::record_lookup%(r: Comm::Data, idx: count%): Comm::Data + %{ + auto& v = comm::require_data_type(r->AsRecordVal(), + TYPE_RECORD, frame); + + if ( idx >= v.size() ) + return new RecordVal(BifType::Record::Comm::Data); + + if ( ! v.fields[idx] ) + return new RecordVal(BifType::Record::Comm::Data); + + return comm::make_data_val(*v.fields[idx]); + %} + +function Comm::record_iterator%(r: Comm::Data%): opaque of Comm::RecordIterator + %{ + return new comm::RecordIterator(r->AsRecordVal(), TYPE_RECORD, frame); + %} + +function Comm::record_iterator_last%(it: opaque of Comm::RecordIterator%): bool + %{ + auto ri = static_cast(it); + return new Val(ri->it == ri->dat.fields.end(), TYPE_BOOL); + %} + +function Comm::record_iterator_next%(it: opaque of Comm::RecordIterator%): bool + %{ + auto ri = static_cast(it); + + if ( ri->it == ri->dat.fields.end() ) + return new Val(false, TYPE_BOOL); + + ++ri->it; + return new Val(ri->it != ri->dat.fields.end(), TYPE_BOOL); + %} + +function Comm::record_iterator_value%(it: opaque of Comm::RecordIterator%): Comm::Data + %{ + auto ri = static_cast(it); + auto rval = new RecordVal(BifType::Record::Comm::Data); + + if ( ri->it == ri->dat.fields.end() ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Warning("attempt to retrieve value of invalid record iterator"); + reporter->PopLocation(); + return rval; + } + + if ( ! *ri->it ) + return rval; // field isn't set + + rval->Assign(0, new comm::DataVal(**ri->it)); + return rval; + %} + event Comm::remote_connection_established%(peer_address: string, peer_port: port, peer_name: string%); diff --git a/testing/btest/Baseline/comm.data/out b/testing/btest/Baseline/comm.data/out new file mode 100644 index 0000000000..eea78d39a2 --- /dev/null +++ b/testing/btest/Baseline/comm.data/out @@ -0,0 +1,99 @@ +Comm::BOOL +Comm::INT +Comm::COUNT +Comm::DOUBLE +Comm::STRING +Comm::ADDR +Comm::SUBNET +Comm::PORT +Comm::TIME +Comm::INTERVAL +Comm::ENUM +Comm::SET +Comm::TABLE +Comm::VECTOR +Comm::RECORD +*************************** +T +F +1 +0 +-1 +1 +0 +1.1 +-11.1 +hello +1.2.3.4 +192.168.0.0/16 +22/tcp +42.0 +180.0 +Comm::BOOL +*************************** +{ +two, +one, +three +} +0 +T +1 +T +F +T +2 +T +1 +F +{ +bye +} +0 +*************************** +{ +[two] = 2, +[one] = 1, +[three] = 3 +} +0 +[d=] +1 +T +42 +F +[d=] +2 +[d=broker::data{7}] +2 +37 +[d=broker::data{42}] +1 +*************************** +[zero, one, two] +0 +T +T +T +T +[hi, salutations, hello, greetings] +4 +[d=broker::data{hello}] +[d=broker::data{bah}] +[d=broker::data{hi}] +[hi, salutations, bah, greetings] +[d=broker::data{bah}] +[hi, salutations, greetings] +3 +*************************** +[a=, b=bee, c=1] +[a=test, b=bee, c=1] +[a=test, b=testagain, c=1] +3 +T +T +T +[d=broker::data{hi}] +[d=broker::data{hello}] +[d=broker::data{37}] +3 diff --git a/testing/btest/comm/data.bro b/testing/btest/comm/data.bro new file mode 100644 index 0000000000..3fb9dcd86e --- /dev/null +++ b/testing/btest/comm/data.bro @@ -0,0 +1,219 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +type bro_set: set[string]; +type bro_table: table[string] of count; +type bro_vector: vector of string; + +type bro_record : record { + a: string &optional; + b: string &default = "bee"; + c: count; +}; + +function comm_record_to_bro_record_recurse(it: opaque of Comm::RecordIterator, + rval: bro_record, + idx: count): bro_record + { + if ( Comm::record_iterator_last(it) ) + return rval; + + local field_value = Comm::record_iterator_value(it); + + if ( field_value?$d ) + switch ( idx ) { + case 0: + rval$a = Comm::refine_to_string(field_value); + break; + case 1: + rval$b = Comm::refine_to_string(field_value); + break; + case 2: + rval$c = Comm::refine_to_count(field_value); + break; + }; + + ++idx; + Comm::record_iterator_next(it); + return comm_record_to_bro_record_recurse(it, rval, idx); + } + +function comm_record_to_bro_record(d: Comm::Data): bro_record + { + return comm_record_to_bro_record_recurse(Comm::record_iterator(d), + bro_record($c = 0), 0); + } + +function +comm_set_to_bro_set_recurse(it: opaque of Comm::SetIterator, + rval: bro_set): bro_set + { + if ( Comm::set_iterator_last(it) ) + return rval; + + add rval[Comm::refine_to_string(Comm::set_iterator_value(it))]; + Comm::set_iterator_next(it); + return comm_set_to_bro_set_recurse(it, rval); + } + + +function comm_set_to_bro_set(d: Comm::Data): bro_set + { + return comm_set_to_bro_set_recurse(Comm::set_iterator(d), bro_set()); + } + +function +comm_table_to_bro_table_recurse(it: opaque of Comm::TableIterator, + rval: bro_table): bro_table + { + if ( Comm::table_iterator_last(it) ) + return rval; + + local item = Comm::table_iterator_value(it); + rval[Comm::refine_to_string(item$key)] = Comm::refine_to_count(item$val); + Comm::table_iterator_next(it); + return comm_table_to_bro_table_recurse(it, rval); + } + +function comm_table_to_bro_table(d: Comm::Data): bro_table + { + return comm_table_to_bro_table_recurse(Comm::table_iterator(d), + bro_table()); + } + +function comm_vector_to_bro_vector_recurse(it: opaque of Comm::VectorIterator, + rval: bro_vector): bro_vector + { + if ( Comm::vector_iterator_last(it) ) + return rval; + + rval[|rval|] = Comm::refine_to_string(Comm::vector_iterator_value(it)); + Comm::vector_iterator_next(it); + return comm_vector_to_bro_vector_recurse(it, rval); + } + +function comm_vector_to_bro_vector(d: Comm::Data): bro_vector + { + return comm_vector_to_bro_vector_recurse(Comm::vector_iterator(d), + bro_vector()); + } + +event bro_init() +{ +print Comm::data_type(Comm::data(T)); +print Comm::data_type(Comm::data(+1)); +print Comm::data_type(Comm::data(1)); +print Comm::data_type(Comm::data(1.1)); +print Comm::data_type(Comm::data("1 (how creative)")); +print Comm::data_type(Comm::data(1.1.1.1)); +print Comm::data_type(Comm::data(1.1.1.1/1)); +print Comm::data_type(Comm::data(1/udp)); +print Comm::data_type(Comm::data(double_to_time(1))); +print Comm::data_type(Comm::data(1sec)); +print Comm::data_type(Comm::data(Comm::BOOL)); +local s: bro_set = bro_set("one", "two", "three"); +local t: bro_table = bro_table(["one"] = 1, ["two"] = 2, ["three"] = 3); +local v: bro_vector = bro_vector("zero", "one", "two"); +local r: bro_record = bro_record($c = 1); +print Comm::data_type(Comm::data(s)); +print Comm::data_type(Comm::data(t)); +print Comm::data_type(Comm::data(v)); +print Comm::data_type(Comm::data(r)); + +print "***************************"; + +print Comm::refine_to_bool(Comm::data(T)); +print Comm::refine_to_bool(Comm::data(F)); +print Comm::refine_to_int(Comm::data(+1)); +print Comm::refine_to_int(Comm::data(+0)); +print Comm::refine_to_int(Comm::data(-1)); +print Comm::refine_to_count(Comm::data(1)); +print Comm::refine_to_count(Comm::data(0)); +print Comm::refine_to_double(Comm::data(1.1)); +print Comm::refine_to_double(Comm::data(-11.1)); +print Comm::refine_to_string(Comm::data("hello")); +print Comm::refine_to_addr(Comm::data(1.2.3.4)); +print Comm::refine_to_subnet(Comm::data(192.168.1.1/16)); +print Comm::refine_to_port(Comm::data(22/tcp)); +print Comm::refine_to_time(Comm::data(double_to_time(42))); +print Comm::refine_to_interval(Comm::data(3min)); +print Comm::refine_to_enum_name(Comm::data(Comm::BOOL)); + +print "***************************"; + +local cs = Comm::data(s); +print comm_set_to_bro_set(cs); +cs = Comm::set_create(); +print Comm::set_size(cs); +print Comm::set_insert(cs, Comm::data("hi")); +print Comm::set_size(cs); +print Comm::set_contains(cs, Comm::data("hi")); +print Comm::set_contains(cs, Comm::data("bye")); +print Comm::set_insert(cs, Comm::data("bye")); +print Comm::set_size(cs); +print Comm::set_remove(cs, Comm::data("hi")); +print Comm::set_size(cs); +print Comm::set_remove(cs, Comm::data("hi")); +print comm_set_to_bro_set(cs); +Comm::set_clear(cs); +print Comm::set_size(cs); + +print "***************************"; + +local ct = Comm::data(t); +print comm_table_to_bro_table(ct); +ct = Comm::table_create(); +print Comm::table_size(ct); +print Comm::table_insert(ct, Comm::data("hi"), Comm::data(42)); +print Comm::table_size(ct); +print Comm::table_contains(ct, Comm::data("hi")); +print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("hi"))); +print Comm::table_contains(ct, Comm::data("bye")); +print Comm::table_insert(ct, Comm::data("bye"), Comm::data(7)); +print Comm::table_size(ct); +print Comm::table_insert(ct, Comm::data("bye"), Comm::data(37)); +print Comm::table_size(ct); +print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("bye"))); +print Comm::table_remove(ct, Comm::data("hi")); +print Comm::table_size(ct); + +print "***************************"; + +local cv = Comm::data(v); +print comm_vector_to_bro_vector(cv); +cv = Comm::vector_create(); +print Comm::vector_size(cv); +print Comm::vector_insert(cv, Comm::data("hi"), 0); +print Comm::vector_insert(cv, Comm::data("hello"), 1); +print Comm::vector_insert(cv, Comm::data("greetings"), 2); +print Comm::vector_insert(cv, Comm::data("salutations"), 1); +print comm_vector_to_bro_vector(cv); +print Comm::vector_size(cv); +print Comm::vector_replace(cv, Comm::data("bah"), 2); +print Comm::vector_lookup(cv, 2); +print Comm::vector_lookup(cv, 0); +print comm_vector_to_bro_vector(cv); +print Comm::vector_remove(cv, 2); +print comm_vector_to_bro_vector(cv); +print Comm::vector_size(cv); + +print "***************************"; + +local cr = Comm::data(r); +print comm_record_to_bro_record(cr); +r$a = "test"; +cr = Comm::data(r); +print comm_record_to_bro_record(cr); +r$b = "testagain"; +cr = Comm::data(r); +print comm_record_to_bro_record(cr); +cr = Comm::record_create(3); +print Comm::record_size(cr); +print Comm::record_assign(cr, Comm::data("hi"), 0); +print Comm::record_assign(cr, Comm::data("hello"), 1); +print Comm::record_assign(cr, Comm::data(37), 2); +print Comm::record_lookup(cr, 0); +print Comm::record_lookup(cr, 1); +print Comm::record_lookup(cr, 2); +print Comm::record_size(cr); +} From 9875f5d3eba7e19506c6b2970d8c8ea444927007 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 30 Jan 2015 14:39:16 -0600 Subject: [PATCH 030/256] broker integration: add distributed data store api But haven't done the full gamut of testing on it yet. --- scripts/base/frameworks/comm/main.bro | 38 ++- src/Trigger.cc | 12 +- src/Trigger.h | 5 + src/comm/CMakeLists.txt | 10 +- src/comm/Data.cc | 2 +- src/comm/Manager.cc | 145 +++++++++- src/comm/Manager.h | 17 ++ src/comm/Store.cc | 141 ++++++++++ src/comm/Store.h | 113 ++++++++ src/comm/{comm.bif => data.bif} | 151 +--------- src/comm/messaging.bif | 156 +++++++++++ src/comm/store.bif | 378 ++++++++++++++++++++++++++ 12 files changed, 1012 insertions(+), 156 deletions(-) create mode 100644 src/comm/Store.cc create mode 100644 src/comm/Store.h rename src/comm/{comm.bif => data.bif} (76%) create mode 100644 src/comm/messaging.bif create mode 100644 src/comm/store.bif diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index 974e5e43af..a2cd1f6ac0 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -15,9 +15,11 @@ export { d: opaque of Comm::Data &optional; }; + type DataVector: vector of Comm::Data; + type EventArgs: record { name: string &optional; # nil for invalid event/args. - args: vector of Comm::Data; + args: DataVector; }; type Comm::TableItem : record { @@ -25,3 +27,37 @@ export { val: Comm::Data; }; } + +module Store; + +export { + + type QueryStatus: enum { + SUCCESS, + FAILURE, + }; + + type ExpiryTime: record { + absolute: time &optional; + since_last_modification: interval &optional; + }; + + type QueryResult: record { + status: Store::QueryStatus; + result: Comm::Data; + }; + + type SQLiteOptions: record { + path: string &default = "store.sqlite"; + }; + + type RocksDBOptions: record { + path: string &default = "store.rocksdb"; + use_merge_operator: bool &default = F; + }; + + type BackendOptions: record { + sqlite: SQLiteOptions &default = SQLiteOptions(); + rocksdb: RocksDBOptions &default = RocksDBOptions(); + }; +} diff --git a/src/Trigger.cc b/src/Trigger.cc index 099027f4e0..772a991791 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -112,6 +112,7 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts, attached = 0; is_return = arg_is_return; location = arg_location; + timeout_value = -1; ++total_triggers; @@ -133,17 +134,22 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts, Val* timeout_val = arg_timeout ? arg_timeout->Eval(arg_frame) : 0; + if ( timeout_val ) + { + Unref(timeout_val); + timeout_value = timeout_val->AsInterval(); + } + // Make sure we don't get deleted if somebody calls a method like // Timeout() while evaluating the trigger. Ref(this); - if ( ! Eval() && timeout_val ) + if ( ! Eval() && timeout_value >= 0 ) { - timer = new TriggerTimer(timeout_val->AsInterval(), this); + timer = new TriggerTimer(timeout_value, this); timer_mgr->Add(timer); } - Unref(timeout_val); Unref(this); } diff --git a/src/Trigger.h b/src/Trigger.h index b752ea8ada..7662901dc5 100644 --- a/src/Trigger.h +++ b/src/Trigger.h @@ -32,6 +32,10 @@ public: // Executes timeout code and deletes the object. void Timeout(); + // Return the timeout interval (negative if none was specified). + double TimeoutValue() const + { return timeout_value; } + // Called if another entity needs to complete its operations first // in any case before this trigger can proceed. void Hold() { delayed = true; } @@ -87,6 +91,7 @@ private: Stmt* body; Stmt* timeout_stmts; Expr* timeout; + double timeout_value; Frame* frame; bool is_return; const Location* location; diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt index 95ad701d71..da726e54d6 100644 --- a/src/comm/CMakeLists.txt +++ b/src/comm/CMakeLists.txt @@ -5,12 +5,20 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ) +if ( ROCKSDB_INCLUDE_DIR ) + add_definitions(-DHAVE_ROCKSDB) + include_directories(BEFORE ${ROCKSDB_INCLUDE_DIR}) +endif () + set(comm_SRCS Data.cc Manager.cc + Store.cc ) -bif_target(comm.bif) +bif_target(data.bif) +bif_target(messaging.bif) +bif_target(store.bif) bro_add_subdir_library(comm ${comm_SRCS} ${BIF_OUTPUT_CC}) add_dependencies(bro_comm generate_outputs) diff --git a/src/comm/Data.cc b/src/comm/Data.cc index f32bedd885..3b1a240988 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -1,5 +1,5 @@ #include "Data.h" -#include "comm/comm.bif.h" +#include "comm/data.bif.h" using namespace std; diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index e64c74c377..9f17878cf6 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -1,12 +1,15 @@ #include "Manager.h" #include "Data.h" +#include "Store.h" #include #include #include #include "util.h" #include "Var.h" #include "Reporter.h" -#include "comm/comm.bif.h" +#include "comm/data.bif.h" +#include "comm/messaging.bif.h" +#include "comm/store.bif.h" #include "logging/Manager.h" using namespace std; @@ -17,6 +20,12 @@ int comm::Manager::send_flags_self_idx; int comm::Manager::send_flags_peers_idx; int comm::Manager::send_flags_unsolicited_idx; +comm::Manager::~Manager() + { + for ( auto& s : data_stores ) + CloseStore(s.first); + } + bool comm::Manager::InitPreScript() { return true; @@ -47,6 +56,7 @@ bool comm::Manager::InitPostScript() comm::opaque_of_table_iterator = new OpaqueType("Comm::TableIterator"); comm::opaque_of_vector_iterator = new OpaqueType("Comm::VectorIterator"); comm::opaque_of_record_iterator = new OpaqueType("Comm::RecordIterator"); + comm::opaque_of_store_handle = new OpaqueType("Store::Handle"); vector_of_data_type = new VectorType(internal_type("Comm::Data")->Ref()); auto res = broker::init(); @@ -385,6 +395,9 @@ void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, for ( const auto& ps : log_subscriptions ) read->Insert(ps.second.fd()); + + for ( const auto& s : data_stores ) + read->Insert(s.second->store->responses().fd()); } double comm::Manager::NextTimestamp(double* local_network_time) @@ -393,6 +406,49 @@ double comm::Manager::NextTimestamp(double* local_network_time) return timer_mgr->Time(); } +struct response_converter { + using result_type = RecordVal*; + + result_type operator()(bool d) + { + return comm::make_data_val(broker::data{d}); + } + + result_type operator()(uint64_t d) + { + return comm::make_data_val(broker::data{d}); + } + + result_type operator()(broker::data& d) + { + return comm::make_data_val(move(d)); + } + + result_type operator()(std::vector& d) + { + return comm::make_data_val(broker::data{move(d)}); + } + + result_type operator()(broker::store::snapshot& d) + { + broker::table table; + + for ( auto& item : d.entries ) + { + auto& key = item.first; + auto& val = item.second.item; + table[move(key)] = move(val); + } + + return comm::make_data_val(broker::data{move(table)}); + } +}; + +static RecordVal* response_to_val(broker::store::response r) + { + return broker::visit(response_converter{}, r.reply.value); + } + void comm::Manager::Process() { bool idle = true; @@ -624,5 +680,92 @@ void comm::Manager::Process() } } + for ( const auto& s : data_stores ) + { + auto responses = s.second->store->responses().want_pop(); + + if ( responses.empty() ) + continue; + + idle = false; + + for ( auto& response : responses ) + { + auto ck = static_cast(response.cookie); + auto it = pending_queries.find(ck); + + if ( it == pending_queries.end() ) + { + reporter->Warning("unmatched response to query on store %s", + s.second->store->id().data()); + continue; + } + + auto query = *it; + + switch ( response.reply.stat ) { + case broker::store::result::status::timeout: + // Fine, trigger's timeout takes care of things. + break; + case broker::store::result::status::failure: + query->Result(query_result()); + break; + case broker::store::result::status::success: + query->Result(query_result(response_to_val(move(response)))); + break; + default: + reporter->InternalWarning("unknown store response status: %d", + static_cast(response.reply.stat)); + break; + } + + pending_queries.erase(it); + } + } + SetIdle(idle); } + +bool comm::Manager::AddStore(StoreHandleVal* handle) + { + if ( ! handle->store ) + return false; + + if ( data_stores.find(handle->store->id()) != data_stores.end() ) + return false; + + data_stores[handle->store->id()] = handle; + Ref(handle); + return true; + } + +bool comm::Manager::CloseStore(const broker::store::identifier& id) + { + auto it = data_stores.find(id); + + if ( it == data_stores.end() ) + return false; + + for ( auto it = pending_queries.begin(); it != pending_queries.end(); ) + { + auto query = *it; + + if ( query->StoreID() == id ) + { + it = pending_queries.erase(it); + query->Abort(); + delete query; + } + else + ++it; + } + + it->second->store = nullptr; + Unref(it->second); + return true; + } + +bool comm::Manager::TrackStoreQuery(StoreQueryCallback* cb) + { + return pending_queries.insert(cb).second; + } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 44f5eb0f2b..c9cc2c8464 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include "comm/Store.h" #include "Reporter.h" #include "iosource/IOSource.h" #include "Val.h" @@ -17,8 +19,11 @@ namespace comm { // Manages various forms of communication between peer Bro processes // or possibly between different parts of a single Bro process. class Manager : public iosource::IOSource { +friend class StoreHandleVal; public: + ~Manager(); + bool InitPreScript(); bool InitPostScript(); @@ -56,6 +61,12 @@ public: bool UnsubscribeToLogs(const std::string& topic_prefix); + bool AddStore(StoreHandleVal* handle); + + bool CloseStore(const broker::store::identifier& id); + + bool TrackStoreQuery(StoreQueryCallback* cb); + static int GetFlags(Val* flags); private: @@ -71,12 +82,18 @@ private: const char* Tag() override { return "Comm::Manager"; } + broker::endpoint& Endpoint() + { return *endpoint; } + std::unique_ptr endpoint; std::map, broker::peering> peers; std::map print_subscriptions; std::map event_subscriptions; std::map log_subscriptions; + std::map data_stores; + std::unordered_set pending_queries; + static VectorType* vector_of_data_type; static EnumType* log_id_type; static int send_flags_self_idx; diff --git a/src/comm/Store.cc b/src/comm/Store.cc new file mode 100644 index 0000000000..0d94795ce8 --- /dev/null +++ b/src/comm/Store.cc @@ -0,0 +1,141 @@ +#include "Store.h" +#include "comm/Manager.h" + +#include +#include +#include + +#ifdef HAVE_ROCKSDB +#include +#include +#endif + +OpaqueType* comm::opaque_of_store_handle; + +comm::StoreHandleVal::StoreHandleVal(broker::store::identifier id, + comm::StoreType arg_type, + broker::util::optional arg_back, + RecordVal* backend_options, std::chrono::duration resync) + : OpaqueVal(opaque_of_store_handle), + store(), store_type(arg_type), backend_type(arg_back) + { + using BifEnum::Store::BackendType; + std::unique_ptr backend; + + if ( backend_type ) + switch ( *backend_type ) { + case BackendType::MEMORY: + backend.reset(new broker::store::memory_backend); + break; + case BackendType::SQLITE: + { + auto sqlite = new broker::store::sqlite_backend; + std::string path = backend_options->Lookup(0)->AsRecordVal() + ->Lookup(0)->AsStringVal()->CheckString(); + + if ( sqlite->open(path) ) + backend.reset(sqlite); + else + { + reporter->Error("failed to open sqlite backend at path %s: %s", + path.data(), sqlite->last_error().data()); + delete sqlite; + } + } + break; + case BackendType::ROCKSDB: + { +#ifdef HAVE_ROCKSDB + std::string path = backend_options->Lookup(1)->AsRecordVal() + ->Lookup(0)->AsStringVal()->CheckString(); + bool use_merge_op = backend_options->Lookup(1)->AsRecordVal() + ->Lookup(1)->AsBool(); + rocksdb::Options rock_op; + rock_op.create_if_missing = true; + + if ( use_merge_op ) + options.merge_operator.reset(new rocksdb_merge_operator); + + auto rocksdb = new broker::store::rocksdb_backend; + + if ( rocksdb->open(path, options).ok() ) + backend.reset(rocksdb); + else + { + reporter->Error("failed to open rocksdb backend at path %s: %s", + path.data(), rocksdb->last_error().data()); + delete rocksdb; + } +#else + reporter->Error("rocksdb backend support is not enabled"); +#endif + } + break; + default: + reporter->FatalError("unknown data store backend: %d", + static_cast(*backend_type)); + } + + switch ( store_type ) { + case StoreType::FRONTEND: + store.reset(new broker::store::frontend(comm_mgr->Endpoint(), + move(id))); + break; + case StoreType::MASTER: + store.reset(new broker::store::master(comm_mgr->Endpoint(), + move(id), move(backend))); + break; + case StoreType::CLONE: + store.reset(new broker::store::clone(comm_mgr->Endpoint(), + move(id), resync, + move(backend))); + break; + default: + reporter->FatalError("unknown data store type: %d", + static_cast(store_type)); + } + } + +void comm::StoreHandleVal::ValDescribe(ODesc* d) const + { + using BifEnum::Store::BackendType; + d->Add("broker::store::"); + + switch ( store_type ) { + case StoreType::FRONTEND: + d->Add("frontend"); + break; + case StoreType::MASTER: + d->Add("master"); + break; + case StoreType::CLONE: + d->Add("clone"); + break; + default: + d->Add("unknown"); + } + + d->Add("{"); + d->Add(store->id()); + + if ( backend_type ) + { + d->Add(", "); + + switch ( *backend_type ) { + case BackendType::MEMORY: + d->Add("memory"); + break; + case BackendType::SQLITE: + d->Add("sqlite"); + break; + case BackendType::ROCKSDB: + d->Add("rocksdb"); + break; + default: + d->Add("unknown"); + } + } + + d->Add("}"); + } diff --git a/src/comm/Store.h b/src/comm/Store.h new file mode 100644 index 0000000000..b3a8ccb339 --- /dev/null +++ b/src/comm/Store.h @@ -0,0 +1,113 @@ +#ifndef BRO_COMM_STORE_H +#define BRO_COMM_STORE_H + +#include "comm/store.bif.h" +#include "comm/data.bif.h" +#include "Reporter.h" +#include "Type.h" +#include "Val.h" +#include "Trigger.h" + +#include + +namespace comm { + +extern OpaqueType* opaque_of_store_handle; + +enum StoreType { + FRONTEND, + MASTER, + CLONE, +}; + +inline EnumVal* query_status(bool success) + { + static EnumType* store_query_status = nullptr; + static int success_val; + static int failure_val; + + if ( ! store_query_status ) + { + store_query_status = internal_type("Store::QueryStatus")->AsEnumType(); + success_val = store_query_status->Lookup("Store", "SUCCESS"); + failure_val = store_query_status->Lookup("Store", "FAILURE"); + } + + return new EnumVal(success ? success_val : failure_val, store_query_status); + } + +inline RecordVal* query_result() + { + auto rval = new RecordVal(BifType::Record::Store::QueryResult); + rval->Assign(0, query_status(false)); + rval->Assign(1, new RecordVal(BifType::Record::Comm::Data)); + return rval; + } + +inline RecordVal* query_result(RecordVal* data) + { + auto rval = new RecordVal(BifType::Record::Store::QueryResult); + rval->Assign(0, query_status(true)); + rval->Assign(1, data); + return rval; + } + +class StoreQueryCallback { +public: + + StoreQueryCallback(Trigger* arg_trigger, const CallExpr* arg_call, + broker::store::identifier arg_store_id) + : trigger(arg_trigger), call(arg_call), store_id(move(arg_store_id)) + { + Ref(trigger); + } + + ~StoreQueryCallback() + { + Unref(trigger); + } + + void Result(RecordVal* result) + { + trigger->Cache(call, result); + trigger->Release(); + Unref(result); + } + + void Abort() + { + auto result = query_result(); + trigger->Cache(call, result); + trigger->Release(); + Unref(result); + } + + const broker::store::identifier& StoreID() const + { return store_id; } + +private: + + Trigger* trigger; + const CallExpr* call; + broker::store::identifier store_id; +}; + +class StoreHandleVal : public OpaqueVal { +public: + + StoreHandleVal(broker::store::identifier id, + comm::StoreType arg_type, + broker::util::optional arg_back, + RecordVal* backend_options, + std::chrono::duration resync = std::chrono::seconds(1)); + + void ValDescribe(ODesc* d) const override; + + std::unique_ptr store; + comm::StoreType store_type; + broker::util::optional backend_type; +}; + +} // namespace comm + +#endif // BRO_COMM_STORE_H diff --git a/src/comm/comm.bif b/src/comm/data.bif similarity index 76% rename from src/comm/comm.bif rename to src/comm/data.bif index b2ce0fb415..2a78a9229a 100644 --- a/src/comm/comm.bif +++ b/src/comm/data.bif @@ -1,8 +1,8 @@ +##! Functions for inspecting and manipulating broker data. + %%{ -#include "comm/Manager.h" #include "comm/Data.h" -#include "logging/Manager.h" %%} module Comm; @@ -25,12 +25,8 @@ enum DataType %{ RECORD, %} -type Comm::SendFlags: record; - type Comm::Data: record; -type Comm::EventArgs: record; - type Comm::TableItem: record; function Comm::data%(d: any%): Comm::Data @@ -507,146 +503,3 @@ function Comm::record_iterator_value%(it: opaque of Comm::RecordIterator%): Comm rval->Assign(0, new comm::DataVal(**ri->it)); return rval; %} - -event Comm::remote_connection_established%(peer_address: string, - peer_port: port, - peer_name: string%); - -event Comm::remote_connection_broken%(peer_address: string, - peer_port: port%); - -event Comm::remote_connection_incompatible%(peer_address: string, - peer_port: port%); - -function Comm::listen%(p: port, a: string &default = "", - reuse: bool &default = T%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("listen port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0, - reuse); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::connect%(a: string, p: port, retry: interval%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("remote connection port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Connect(a->CheckString(), p->Port(), - std::chrono::duration(retry)); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::disconnect%(a: string, p: port%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("remote connection port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); - return new Val(rval, TYPE_BOOL); - %} - -event Comm::print_handler%(msg: string%); - -function Comm::print%(topic: string, msg: string, - flags: SendFlags &default = SendFlags()%): bool - %{ - auto rval = comm_mgr->Print(topic->CheckString(), msg->CheckString(), - flags); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::subscribe_to_prints%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->SubscribeToPrints(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::unsubscribe_to_prints%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->UnsubscribeToPrints(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::event_args%(...%): Comm::EventArgs - %{ - auto rval = comm_mgr->MakeEventArgs(@ARGS@); - return rval; - %} - -function Comm::event%(topic: string, args: Comm::EventArgs, - flags: SendFlags &default = SendFlags()%): bool - %{ - auto rval = comm_mgr->Event(topic->CheckString(), args->AsRecordVal(), - flags); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::auto_event%(topic: string, ev: any, - flags: SendFlags &default = SendFlags()%): bool - %{ - auto rval = comm_mgr->AutoEvent(topic->CheckString(), ev, flags); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::auto_event_stop%(topic: string, ev: any%): bool - %{ - auto rval = comm_mgr->AutoEventStop(topic->CheckString(), ev); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::subscribe_to_events%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->SubscribeToEvents(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::unsubscribe_to_events%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->UnsubscribeToEvents(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} - -function -Comm::enable_remote_logs%(id: Log::ID, - flags: SendFlags &default = SendFlags()%): bool - %{ - auto rval = log_mgr->EnableRemoteLogs(id->AsEnumVal(), - comm::Manager::GetFlags(flags)); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::disable_remote_logs%(id: Log::ID%): bool - %{ - auto rval = log_mgr->DisableRemoteLogs(id->AsEnumVal()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::remote_logs_enabled%(id: Log::ID%): bool - %{ - auto rval = log_mgr->RemoteLogsAreEnabled(id->AsEnumVal()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::subscribe_to_logs%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->SubscribeToLogs(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::unsubscribe_to_logs%(topic_prefix: string%): bool - %{ - auto rval = comm_mgr->UnsubscribeToLogs(topic_prefix->CheckString()); - return new Val(rval, TYPE_BOOL); - %} diff --git a/src/comm/messaging.bif b/src/comm/messaging.bif new file mode 100644 index 0000000000..f5034f842f --- /dev/null +++ b/src/comm/messaging.bif @@ -0,0 +1,156 @@ + +##! Functions for peering and various messaging patterns (e.g. print/log/event). + +%%{ +#include "comm/Manager.h" +#include "logging/Manager.h" +%%} + +module Comm; + +type Comm::SendFlags: record; + +type Comm::EventArgs: record; + +event Comm::remote_connection_established%(peer_address: string, + peer_port: port, + peer_name: string%); + +event Comm::remote_connection_broken%(peer_address: string, + peer_port: port%); + +event Comm::remote_connection_incompatible%(peer_address: string, + peer_port: port%); + +function Comm::listen%(p: port, a: string &default = "", + reuse: bool &default = T%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("listen port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0, + reuse); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::connect%(a: string, p: port, retry: interval%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Connect(a->CheckString(), p->Port(), + std::chrono::duration(retry)); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::disconnect%(a: string, p: port%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); + return new Val(rval, TYPE_BOOL); + %} + +event Comm::print_handler%(msg: string%); + +function Comm::print%(topic: string, msg: string, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->Print(topic->CheckString(), msg->CheckString(), + flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_prints%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->SubscribeToPrints(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_prints%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->UnsubscribeToPrints(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::event_args%(...%): Comm::EventArgs + %{ + auto rval = comm_mgr->MakeEventArgs(@ARGS@); + return rval; + %} + +function Comm::event%(topic: string, args: Comm::EventArgs, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->Event(topic->CheckString(), args->AsRecordVal(), + flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::auto_event%(topic: string, ev: any, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = comm_mgr->AutoEvent(topic->CheckString(), ev, flags); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::auto_event_stop%(topic: string, ev: any%): bool + %{ + auto rval = comm_mgr->AutoEventStop(topic->CheckString(), ev); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_events%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->SubscribeToEvents(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_events%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->UnsubscribeToEvents(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function +Comm::enable_remote_logs%(id: Log::ID, + flags: SendFlags &default = SendFlags()%): bool + %{ + auto rval = log_mgr->EnableRemoteLogs(id->AsEnumVal(), + comm::Manager::GetFlags(flags)); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::disable_remote_logs%(id: Log::ID%): bool + %{ + auto rval = log_mgr->DisableRemoteLogs(id->AsEnumVal()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::remote_logs_enabled%(id: Log::ID%): bool + %{ + auto rval = log_mgr->RemoteLogsAreEnabled(id->AsEnumVal()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::subscribe_to_logs%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->SubscribeToLogs(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::unsubscribe_to_logs%(topic_prefix: string%): bool + %{ + auto rval = comm_mgr->UnsubscribeToLogs(topic_prefix->CheckString()); + return new Val(rval, TYPE_BOOL); + %} diff --git a/src/comm/store.bif b/src/comm/store.bif new file mode 100644 index 0000000000..fb4c8d57ce --- /dev/null +++ b/src/comm/store.bif @@ -0,0 +1,378 @@ + +##! Functions to interface with broker's distributed data store. + +%%{ +#include "comm/Manager.h" +#include "comm/Store.h" +#include "comm/Data.h" +#include "Trigger.h" +%%} + +module Store; + +type Store::ExpiryTime: record; + +type Store::QueryResult: record; + +type Store::BackendOptions: record; + +enum BackendType %{ + MEMORY, + SQLITE, + ROCKSDB, +%} + +function Store::create_master%(id: string, b: BackendType &default = MEMORY, + options: BackendOptions &default = BackendOptions()%): opaque of Store::Handle + %{ + auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::MASTER, + static_cast(b->AsEnum()), + options->AsRecordVal()); + comm_mgr->AddStore(rval); + return rval; + %} + +function Store::create_clone%(id: string, b: BackendType &default = MEMORY, + options: BackendOptions &default = BackendOptions(), + resync: interval &default = 1sec%): opaque of Store::Handle + %{ + auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::CLONE, + static_cast(b->AsEnum()), + options->AsRecordVal(), + std::chrono::duration(resync)); + comm_mgr->AddStore(rval); + return rval; + %} + +function Store::create_frontend%(id: string%): opaque of Store::Handle + %{ + auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::FRONTEND, + {}, nullptr); + comm_mgr->AddStore(rval); + return rval; + %} + +function Store::close_by_name%(id: string%): bool + %{ + return new Val(comm_mgr->CloseStore(id->CheckString()), TYPE_BOOL); + %} + +function Store::close_by_handle%(h: opaque of Store::Handle%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + return new Val(comm_mgr->CloseStore(handle->store->id()), TYPE_BOOL); + %} + +########################### +# non-blocking update API # +########################### + +function Store::insert%(h: opaque of Store::Handle, + k: Comm::Data, v: Comm::Data, + e: Store::ExpiryTime &default = Store::ExpiryTime()%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + auto& val = comm::opaque_field_to_data(v->AsRecordVal(), frame); + + broker::util::optional expiry; + + auto abs_expiry_val = e->AsRecordVal()->Lookup(0); + auto rel_expiry_val = e->AsRecordVal()->Lookup(1); + + if ( abs_expiry_val ) + { + auto tag = broker::store::expiration_time::tag::absolute; + expiry = broker::store::expiration_time(abs_expiry_val->AsTime(), tag); + } + else if ( rel_expiry_val ) + { + auto tag = broker::store::expiration_time::tag::since_last_modification; + expiry = broker::store::expiration_time(rel_expiry_val->AsInterval(), tag); + } + + handle->store->insert(key, val, expiry); + return new Val(true, TYPE_BOOL); + %} + +function Store::erase%(h: opaque of Store::Handle, k: Comm::Data%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + handle->store->erase(key); + return new Val(true, TYPE_BOOL); + %} + +function Store::clear%(h: opaque of Store::Handle%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + handle->store->clear(); + return new Val(true, TYPE_BOOL); + %} + +function Store::increment%(h: opaque of Store::Handle, + k: Comm::Data, by: int%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + handle->store->increment(key, by); + return new Val(true, TYPE_BOOL); + %} + +function Store::decrement%(h: opaque of Store::Handle, + k: Comm::Data, by: int%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + handle->store->decrement(key, by); + return new Val(true, TYPE_BOOL); + %} + +function Store::add_to_set%(h: opaque of Store::Handle, + k: Comm::Data, element: Comm::Data%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + auto& ele = comm::opaque_field_to_data(element->AsRecordVal(), frame); + handle->store->add_to_set(key, ele); + return new Val(true, TYPE_BOOL); + %} + +function Store::remove_from_set%(h: opaque of Store::Handle, + k: Comm::Data, element: Comm::Data%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + auto& ele = comm::opaque_field_to_data(element->AsRecordVal(), frame); + handle->store->remove_from_set(key, ele); + return new Val(true, TYPE_BOOL); + %} + +function Store::push_left%(h: opaque of Store::Handle, k: Comm::Data, + items: Comm::DataVector%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + broker::vector items_vector; + auto items_vv = items->AsVector(); + + for ( auto i = 0u; i < items_vv->size(); ++i ) + { + auto& item = comm::opaque_field_to_data((*items_vv)[i]->AsRecordVal(), + frame); + items_vector.emplace_back(item); + } + + handle->store->push_left(key, move(items_vector)); + return new Val(true, TYPE_BOOL); + %} + +function Store::push_right%(h: opaque of Store::Handle, k: Comm::Data, + items: Comm::DataVector%): bool + %{ + auto handle = static_cast(h); + + if ( ! handle->store ) + return new Val(false, TYPE_BOOL); + + auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); + broker::vector items_vector; + auto items_vv = items->AsVector(); + + for ( auto i = 0u; i < items_vv->size(); ++i ) + { + auto& item = comm::opaque_field_to_data((*items_vv)[i]->AsRecordVal(), + frame); + items_vector.emplace_back(item); + } + + handle->store->push_right(key, move(items_vector)); + return new Val(true, TYPE_BOOL); + %} + +########################## +# non-blocking query API # +########################## + +%%{ +static bool prepare_for_query(Val* opaque, Frame* frame, + comm::StoreHandleVal** handle, + double* timeout, + comm::StoreQueryCallback** cb) + { + *handle = static_cast(opaque); + + if ( ! (*handle)->store ) + return false; + + Trigger* trigger = frame->GetTrigger(); + + if ( ! trigger ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Error("Store queries can only be called inside when-condition"); + reporter->PopLocation(); + return false; + } + + *timeout = trigger->TimeoutValue(); + + if ( *timeout < 0 ) + { + reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->Error("Store queries must specify a timeout block"); + reporter->PopLocation(); + return false; + } + + frame->SetDelayed(); + trigger->Hold(); + *cb = new comm::StoreQueryCallback(trigger, frame->GetCall(), + (*handle)->store->id()); + comm_mgr->TrackStoreQuery(*cb); + return true; + } + +%%} + +function Store::pop_left%(h: opaque of Store::Handle, + k: Comm::Data%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + Val* key = k->AsRecordVal()->Lookup(0); + + if ( ! key ) + return comm::query_result(); + + handle->store->pop_left(static_cast(key)->data, + std::chrono::duration(timeout), cb); + return 0; + %} + +function Store::pop_right%(h: opaque of Store::Handle, + k: Comm::Data%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + Val* key = k->AsRecordVal()->Lookup(0); + + if ( ! key ) + return comm::query_result(); + + handle->store->pop_right(static_cast(key)->data, + std::chrono::duration(timeout), cb); + return 0; + %} + +function Store::lookup%(h: opaque of Store::Handle, + k: Comm::Data%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + Val* key = k->AsRecordVal()->Lookup(0); + + if ( ! key ) + return comm::query_result(); + + handle->store->lookup(static_cast(key)->data, + std::chrono::duration(timeout), cb); + return 0; + %} + +function Store::exists%(h: opaque of Store::Handle, + k: Comm::Data%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + Val* key = k->AsRecordVal()->Lookup(0); + + if ( ! key ) + return comm::query_result(); + + handle->store->exists(static_cast(key)->data, + std::chrono::duration(timeout), cb); + return 0; + %} + +function Store::keys%(h: opaque of Store::Handle%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + handle->store->keys(std::chrono::duration(timeout), cb); + return 0; + %} + +function Store::size%(h: opaque of Store::Handle%): Store::QueryResult + %{ + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + + handle->store->size(std::chrono::duration(timeout), cb); + return 0; + %} From 05a865a907d79b6617dcbb72da3d423636426b82 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 2 Feb 2015 14:56:28 -0600 Subject: [PATCH 031/256] broker integration: add master data store unti test And fix bug w/ looking up nonexistent keys -- the resulting value data should be "null" not "false". --- src/comm/Manager.cc | 14 +- src/comm/store.bif | 4 +- testing/btest/Baseline/comm.master_store/out | 14 ++ testing/btest/comm/master_store.bro | 141 +++++++++++++++++++ 4 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/comm.master_store/out create mode 100644 testing/btest/comm/master_store.bro diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 9f17878cf6..0b887d4f37 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -408,10 +408,20 @@ double comm::Manager::NextTimestamp(double* local_network_time) struct response_converter { using result_type = RecordVal*; + broker::store::query::tag query_tag; result_type operator()(bool d) { - return comm::make_data_val(broker::data{d}); + switch ( query_tag ) { + case broker::store::query::tag::pop_left: + case broker::store::query::tag::pop_right: + case broker::store::query::tag::lookup: + // A boolean result means the key doesn't exist (if it did, then + // the result would contain the broker::data value, not a bool). + return new RecordVal(BifType::Record::Comm::Data); + default: + return comm::make_data_val(broker::data{d}); + } } result_type operator()(uint64_t d) @@ -446,7 +456,7 @@ struct response_converter { static RecordVal* response_to_val(broker::store::response r) { - return broker::visit(response_converter{}, r.reply.value); + return broker::visit(response_converter{r.request.type}, r.reply.value); } void comm::Manager::Process() diff --git a/src/comm/store.bif b/src/comm/store.bif index fb4c8d57ce..176e55268e 100644 --- a/src/comm/store.bif +++ b/src/comm/store.bif @@ -127,7 +127,7 @@ function Store::clear%(h: opaque of Store::Handle%): bool %} function Store::increment%(h: opaque of Store::Handle, - k: Comm::Data, by: int%): bool + k: Comm::Data, by: int &default = +1%): bool %{ auto handle = static_cast(h); @@ -140,7 +140,7 @@ function Store::increment%(h: opaque of Store::Handle, %} function Store::decrement%(h: opaque of Store::Handle, - k: Comm::Data, by: int%): bool + k: Comm::Data, by: int &default = +1%): bool %{ auto handle = static_cast(h); diff --git a/testing/btest/Baseline/comm.master_store/out b/testing/btest/Baseline/comm.master_store/out new file mode 100644 index 0000000000..defdc9a3e1 --- /dev/null +++ b/testing/btest/Baseline/comm.master_store/out @@ -0,0 +1,14 @@ +lookup(two): [status=Store::SUCCESS, result=[d=broker::data{222}]] +lookup(four): [status=Store::SUCCESS, result=[d=]] +lookup(myset): [status=Store::SUCCESS, result=[d=broker::data{{a, c, d}}]] +lookup(one): [status=Store::SUCCESS, result=[d=broker::data{111}]] +lookup(myvec): [status=Store::SUCCESS, result=[d=broker::data{[delta, alpha, beta, gamma, omega]}]] +exists(one): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(two): [status=Store::SUCCESS, result=[d=broker::data{0}]] +exists(myset): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(four): [status=Store::SUCCESS, result=[d=broker::data{0}]] +pop_right(myvec): [status=Store::SUCCESS, result=[d=broker::data{omega}]] +pop_left(myvec): [status=Store::SUCCESS, result=[d=broker::data{delta}]] +keys: [status=Store::SUCCESS, result=[d=broker::data{[myvec, myset, one]}]] +size: [status=Store::SUCCESS, result=[d=broker::data{3}]] +size (after clear): [status=Store::SUCCESS, result=[d=broker::data{0}]] diff --git a/testing/btest/comm/master_store.bro b/testing/btest/comm/master_store.bro new file mode 100644 index 0000000000..84b4ee07a1 --- /dev/null +++ b/testing/btest/comm/master_store.bro @@ -0,0 +1,141 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out + +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; +global lookup_count = 0; +const lookup_expect_count = 5; +global exists_count = 0; +const exists_expect_count = 4; +global pop_count = 0; +const pop_expect_count = 2; + +global test_size: event(where: string &default = ""); + +event test_clear() + { + Store::clear(h); + event test_size("after clear"); + } + +event test_size(where: string) + { + when ( local res = Store::size(h) ) + { + if ( where == "" ) + { + print fmt("size: %s", res); + event test_clear(); + } + else + { + print fmt("size (%s): %s", where, res); + terminate(); + } + } + timeout 10sec + { print "timeout"; } + } + +event test_keys() + { + when ( local res = Store::keys(h) ) + { + print fmt("keys: %s", res); + event test_size(); + } + timeout 10sec + { print "timeout"; } + } + +event test_pop(key: string) + { + when ( local lres = Store::pop_left(h, Comm::data(key)) ) + { + print fmt("pop_left(%s): %s", key, lres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + + when ( local rres = Store::pop_right(h, Comm::data(key)) ) + { + print fmt("pop_right(%s): %s", key, rres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + } + +function do_exists(key: string) + { + when ( local res = Store::exists(h, Comm::data(key)) ) + { + print fmt("exists(%s): %s", key, res); + ++exists_count; + + if ( exists_count == exists_expect_count ) + event test_pop("myvec"); + } + timeout 10sec + { print "timeout"; } + } + +event test_erase() + { + Store::erase(h, Comm::data("two")); + do_exists("one"); + do_exists("two"); + do_exists("myset"); + do_exists("four"); + } + +function do_lookup(key: string) + { + when ( local res = Store::lookup(h, Comm::data(key)) ) + { + print fmt("lookup(%s): %s", key, res); + ++lookup_count; + + if ( lookup_count == lookup_expect_count ) + event test_erase(); + } + timeout 10sec + { print "timeout"; } + } + +function dv(d: Comm::Data): Comm::DataVector + { + local rval: Comm::DataVector; + rval[0] = d; + return rval; + } + +event bro_init() + { + local myset: set[string] = {"a", "b", "c"}; + local myvec: vector of string = {"alpha", "beta", "gamma"}; + h = Store::create_master("master"); + Store::insert(h, Comm::data("one"), Comm::data(110)); + Store::insert(h, Comm::data("two"), Comm::data(223)); + Store::insert(h, Comm::data("myset"), Comm::data(myset)); + Store::insert(h, Comm::data("myvec"), Comm::data(myvec)); + Store::increment(h, Comm::data("one")); + Store::decrement(h, Comm::data("two")); + Store::add_to_set(h, Comm::data("myset"), Comm::data("d")); + Store::remove_from_set(h, Comm::data("myset"), Comm::data("b")); + Store::push_left(h, Comm::data("myvec"), dv(Comm::data("delta"))); + Store::push_right(h, Comm::data("myvec"), dv(Comm::data("omega"))); + do_lookup("one"); + do_lookup("two"); + do_lookup("myset"); + do_lookup("four"); + do_lookup("myvec"); + } From 441c46df76e3a7e0e50877d66d5c9f7dee081ce9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 3 Feb 2015 11:09:39 -0600 Subject: [PATCH 032/256] broker integration: add unit test for store clones --- aux/broker | 2 +- src/comm/Data.h | 1 + src/comm/Manager.cc | 29 ++++- src/comm/Manager.h | 7 +- src/comm/Store.h | 13 +- src/comm/store.bif | 64 +++++++--- .../Baseline/comm.clone_store/clone.clone.out | 5 + .../comm.clone_store/master.master.out | 0 testing/btest/comm/clone_store.bro | 114 ++++++++++++++++++ 9 files changed, 205 insertions(+), 30 deletions(-) create mode 100644 testing/btest/Baseline/comm.clone_store/clone.clone.out create mode 100644 testing/btest/Baseline/comm.clone_store/master.master.out create mode 100644 testing/btest/comm/clone_store.bro diff --git a/aux/broker b/aux/broker index 177bdfac2c..c217119d9a 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 177bdfac2c768d9ed8f3edb10e9e2dbd0d6f8723 +Subproject commit c217119d9a484da941161d182cdc0a1f86a0d40f diff --git a/src/comm/Data.h b/src/comm/Data.h index c720dcda71..da10853127 100644 --- a/src/comm/Data.h +++ b/src/comm/Data.h @@ -27,6 +27,7 @@ broker::util::optional val_to_data(Val* v); Val* data_to_val(broker::data d, BroType* type); +// TODO: actually need to implement Bro's serialization to support copying vals class DataVal : public OpaqueVal { public: diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 0b887d4f37..3d6aad4d1e 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -23,7 +23,7 @@ int comm::Manager::send_flags_unsolicited_idx; comm::Manager::~Manager() { for ( auto& s : data_stores ) - CloseStore(s.first); + CloseStore(s.first.first, s.first.second); } bool comm::Manager::InitPreScript() @@ -741,17 +741,34 @@ bool comm::Manager::AddStore(StoreHandleVal* handle) if ( ! handle->store ) return false; - if ( data_stores.find(handle->store->id()) != data_stores.end() ) + auto key = make_pair(handle->store->id(), handle->store_type); + + if ( data_stores.find(key) != data_stores.end() ) return false; - data_stores[handle->store->id()] = handle; + data_stores[key] = handle; Ref(handle); return true; } -bool comm::Manager::CloseStore(const broker::store::identifier& id) +comm::StoreHandleVal* +comm::Manager::LookupStore(const broker::store::identifier& id, + comm::StoreType type) { - auto it = data_stores.find(id); + auto key = make_pair(id, type); + auto it = data_stores.find(key); + + if ( it == data_stores.end() ) + return nullptr; + + return it->second; + } + +bool comm::Manager::CloseStore(const broker::store::identifier& id, + StoreType type) + { + auto key = make_pair(id, type); + auto it = data_stores.find(key); if ( it == data_stores.end() ) return false; @@ -760,7 +777,7 @@ bool comm::Manager::CloseStore(const broker::store::identifier& id) { auto query = *it; - if ( query->StoreID() == id ) + if ( query->GetStoreType() == type && query->StoreID() == id ) { it = pending_queries.erase(it); query->Abort(); diff --git a/src/comm/Manager.h b/src/comm/Manager.h index c9cc2c8464..31fdfa56c1 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -63,7 +63,9 @@ public: bool AddStore(StoreHandleVal* handle); - bool CloseStore(const broker::store::identifier& id); + StoreHandleVal* LookupStore(const broker::store::identifier& id, StoreType type); + + bool CloseStore(const broker::store::identifier& id, StoreType type); bool TrackStoreQuery(StoreQueryCallback* cb); @@ -91,7 +93,8 @@ private: std::map event_subscriptions; std::map log_subscriptions; - std::map data_stores; + std::map, + StoreHandleVal*> data_stores; std::unordered_set pending_queries; static VectorType* vector_of_data_type; diff --git a/src/comm/Store.h b/src/comm/Store.h index b3a8ccb339..3183afbbb3 100644 --- a/src/comm/Store.h +++ b/src/comm/Store.h @@ -56,8 +56,10 @@ class StoreQueryCallback { public: StoreQueryCallback(Trigger* arg_trigger, const CallExpr* arg_call, - broker::store::identifier arg_store_id) - : trigger(arg_trigger), call(arg_call), store_id(move(arg_store_id)) + broker::store::identifier arg_store_id, + StoreType arg_store_type) + : trigger(arg_trigger), call(arg_call), store_id(move(arg_store_id)), + store_type(arg_store_type) { Ref(trigger); } @@ -85,13 +87,20 @@ public: const broker::store::identifier& StoreID() const { return store_id; } + StoreType GetStoreType() const + { return store_type; } + private: Trigger* trigger; const CallExpr* call; broker::store::identifier store_id; + StoreType store_type; }; +// TODO: actually need to implement Bro's serialization to support copying vals +// but doesn't make sense to "copy" a master data store, so assert we can +// lookup a store by pair locally (i.e. shouldn't send handles remotely). class StoreHandleVal : public OpaqueVal { public: diff --git a/src/comm/store.bif b/src/comm/store.bif index 176e55268e..7d09704d31 100644 --- a/src/comm/store.bif +++ b/src/comm/store.bif @@ -25,10 +25,20 @@ enum BackendType %{ function Store::create_master%(id: string, b: BackendType &default = MEMORY, options: BackendOptions &default = BackendOptions()%): opaque of Store::Handle %{ - auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::MASTER, - static_cast(b->AsEnum()), - options->AsRecordVal()); - comm_mgr->AddStore(rval); + auto id_str = id->CheckString(); + auto type = comm::StoreType::MASTER; + auto rval = comm_mgr->LookupStore(id_str, type); + + if ( rval ) + { + Ref(rval); + return rval; + } + + rval = new comm::StoreHandleVal(id_str, type, + static_cast(b->AsEnum()), + options->AsRecordVal()); + assert(comm_mgr->AddStore(rval)); return rval; %} @@ -36,25 +46,39 @@ function Store::create_clone%(id: string, b: BackendType &default = MEMORY, options: BackendOptions &default = BackendOptions(), resync: interval &default = 1sec%): opaque of Store::Handle %{ - auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::CLONE, - static_cast(b->AsEnum()), - options->AsRecordVal(), - std::chrono::duration(resync)); - comm_mgr->AddStore(rval); + auto id_str = id->CheckString(); + auto type = comm::StoreType::CLONE; + auto rval = comm_mgr->LookupStore(id_str, type); + + if ( rval ) + { + Ref(rval); + return rval; + } + + rval = new comm::StoreHandleVal(id_str, type, + static_cast(b->AsEnum()), + options->AsRecordVal(), + std::chrono::duration(resync)); + assert(comm_mgr->AddStore(rval)); return rval; %} function Store::create_frontend%(id: string%): opaque of Store::Handle %{ - auto rval = new comm::StoreHandleVal(id->CheckString(), comm::StoreType::FRONTEND, - {}, nullptr); - comm_mgr->AddStore(rval); - return rval; - %} + auto id_str = id->CheckString(); + auto type = comm::StoreType::FRONTEND; + auto rval = comm_mgr->LookupStore(id_str, type); -function Store::close_by_name%(id: string%): bool - %{ - return new Val(comm_mgr->CloseStore(id->CheckString()), TYPE_BOOL); + if ( rval ) + { + Ref(rval); + return rval; + } + + rval = new comm::StoreHandleVal(id_str, type, {}, nullptr); + assert(comm_mgr->AddStore(rval)); + return rval; %} function Store::close_by_handle%(h: opaque of Store::Handle%): bool @@ -64,7 +88,8 @@ function Store::close_by_handle%(h: opaque of Store::Handle%): bool if ( ! handle->store ) return new Val(false, TYPE_BOOL); - return new Val(comm_mgr->CloseStore(handle->store->id()), TYPE_BOOL); + return new Val(comm_mgr->CloseStore(handle->store->id(), + handle->store_type), TYPE_BOOL); %} ########################### @@ -264,7 +289,8 @@ static bool prepare_for_query(Val* opaque, Frame* frame, frame->SetDelayed(); trigger->Hold(); *cb = new comm::StoreQueryCallback(trigger, frame->GetCall(), - (*handle)->store->id()); + (*handle)->store->id(), + (*handle)->store_type); comm_mgr->TrackStoreQuery(*cb); return true; } diff --git a/testing/btest/Baseline/comm.clone_store/clone.clone.out b/testing/btest/Baseline/comm.clone_store/clone.clone.out new file mode 100644 index 0000000000..8a7c89a19b --- /dev/null +++ b/testing/btest/Baseline/comm.clone_store/clone.clone.out @@ -0,0 +1,5 @@ +clone keys, [status=Store::SUCCESS, result=[d=broker::data{[one, two, myset, myvec]}]] +lookup, one, [status=Store::SUCCESS, result=[d=broker::data{111}]] +lookup, two, [status=Store::SUCCESS, result=[d=broker::data{222}]] +lookup, myset, [status=Store::SUCCESS, result=[d=broker::data{{a, c, d}}]] +lookup, myvec, [status=Store::SUCCESS, result=[d=broker::data{[delta, alpha, beta, gamma, omega]}]] diff --git a/testing/btest/Baseline/comm.clone_store/master.master.out b/testing/btest/Baseline/comm.clone_store/master.master.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro new file mode 100644 index 0000000000..03e0fe172f --- /dev/null +++ b/testing/btest/comm/clone_store.bro @@ -0,0 +1,114 @@ +# @TEST_SERIALIZE: brokercomm +# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + +# @TEST-EXEC: btest-bg-run clone "bro -b ../clone.bro >clone.out" +# @TEST-EXEC: btest-bg-run master "bro -b ../master.bro >master.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff clone/clone.out +# @TEST-EXEC: btest-diff master/master.out + +@TEST-START-FILE clone.bro + +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; +global expected_key_count = 4; +global key_count = 0; + +event done() + { + terminate(); + } + +function do_lookup(key: string) + { + when ( local res = Store::lookup(h, Comm::data(key)) ) + { + ++key_count; + print "lookup", key, res; + + if ( key_count == expected_key_count ) + event done(); + } + timeout 10sec + { print "timeout"; } + } + +event ready() + { + h = Store::create_clone("mystore"); + + when ( local res = Store::keys(h) ) + { + print "clone keys", res; + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 0))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 1))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 2))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 3))); + } + timeout 10sec + { print "timeout"; } + } + +event bro_init() + { + Comm::listen(9999/tcp, "127.0.0.1"); + Comm::subscribe_to_events("bro/event/ready"); + Comm::auto_event("bro/event/done", done); + } + +@TEST-END-FILE + +@TEST-START-FILE master.bro + +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; + +function dv(d: Comm::Data): Comm::DataVector + { + local rval: Comm::DataVector; + rval[0] = d; + return rval; + } + +global ready: event(); + +event done() + { + terminate(); + } + +event Comm::remote_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + local myset: set[string] = {"a", "b", "c"}; + local myvec: vector of string = {"alpha", "beta", "gamma"}; + h = Store::create_master("mystore"); + Store::insert(h, Comm::data("one"), Comm::data(110)); + Store::insert(h, Comm::data("two"), Comm::data(223)); + Store::insert(h, Comm::data("myset"), Comm::data(myset)); + Store::insert(h, Comm::data("myvec"), Comm::data(myvec)); + Store::increment(h, Comm::data("one")); + Store::decrement(h, Comm::data("two")); + Store::add_to_set(h, Comm::data("myset"), Comm::data("d")); + Store::remove_from_set(h, Comm::data("myset"), Comm::data("b")); + Store::push_left(h, Comm::data("myvec"), dv(Comm::data("delta"))); + Store::push_right(h, Comm::data("myvec"), dv(Comm::data("omega"))); + + when ( local res = Store::size(h) ) + { event ready(); } + timeout 10sec + { print "timeout"; } + } + +event bro_init() + { + Comm::connect("127.0.0.1", 9999/tcp, 1secs); + Comm::auto_event("bro/event/ready", ready); + Comm::subscribe_to_events("bro/event/done"); + } + +@TEST-END-FILE From bb9e6583e0b113aa82553c4f55341034d61d87a2 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 3 Feb 2015 13:54:40 -0600 Subject: [PATCH 033/256] broker integration: Comm::Data/Store::Handle opaque serialization For now, this is needed when locally cloning Vals. E.g. "when" statements will clone an entire frame and data store queries use "when" statements, so it's likely there will be locals of these opaque types that get cloned. --- src/SerialTypes.h | 2 + src/comm/CMakeLists.txt | 3 ++ src/comm/Data.cc | 34 +++++++++++++++++ src/comm/Data.h | 8 +++- src/comm/Manager.cc | 1 + src/comm/Store.cc | 82 +++++++++++++++++++++++++++++++++++++---- src/comm/Store.h | 12 ++++-- 7 files changed, 130 insertions(+), 12 deletions(-) diff --git a/src/SerialTypes.h b/src/SerialTypes.h index d2f227838c..4e6bbb11ac 100644 --- a/src/SerialTypes.h +++ b/src/SerialTypes.h @@ -113,6 +113,8 @@ SERIAL_VAL(TOPK_VAL, 20) SERIAL_VAL(BLOOMFILTER_VAL, 21) SERIAL_VAL(CARDINALITY_VAL, 22) SERIAL_VAL(X509_VAL, 23) +SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24) +SERIAL_VAL(COMM_DATA_VAL, 25) #define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR) SERIAL_EXPR(EXPR, 1) diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt index da726e54d6..6453e006bf 100644 --- a/src/comm/CMakeLists.txt +++ b/src/comm/CMakeLists.txt @@ -10,6 +10,9 @@ if ( ROCKSDB_INCLUDE_DIR ) include_directories(BEFORE ${ROCKSDB_INCLUDE_DIR}) endif () +include_directories(BEFORE ${LIBCAF_INCLUDE_DIR_CORE}) +include_directories(BEFORE ${LIBCAF_INCLUDE_DIR_IO}) + set(comm_SRCS Data.cc Manager.cc diff --git a/src/comm/Data.cc b/src/comm/Data.cc index 3b1a240988..0ea7666f9e 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -1,5 +1,7 @@ #include "Data.h" #include "comm/data.bif.h" +#include +#include using namespace std; @@ -663,3 +665,35 @@ broker::data& comm::opaque_field_to_data(RecordVal* v, Frame* f) return static_cast(d)->data; } + +IMPLEMENT_SERIAL(comm::DataVal, SER_COMM_DATA_VAL); + +bool comm::DataVal::DoSerialize(SerialInfo* info) const + { + DO_SERIALIZE(SER_COMM_DATA_VAL, OpaqueVal); + + std::string serial; + caf::binary_serializer bs(std::back_inserter(serial)); + bs << data; + + if ( ! SERIALIZE_STR(serial.data(), serial.size()) ) + return false; + + return true; + } + +bool comm::DataVal::DoUnserialize(UnserialInfo* info) + { + DO_UNSERIALIZE(OpaqueVal); + + const char* serial; + int len; + + if ( ! UNSERIALIZE_STR(&serial, &len) ) + return false; + + caf::binary_deserializer bd(serial, len); + caf::uniform_typeid()->deserialize(&data, &bd); + delete [] serial; + return true; + } diff --git a/src/comm/Data.h b/src/comm/Data.h index da10853127..ed3c16f677 100644 --- a/src/comm/Data.h +++ b/src/comm/Data.h @@ -27,7 +27,6 @@ broker::util::optional val_to_data(Val* v); Val* data_to_val(broker::data d, BroType* type); -// TODO: actually need to implement Bro's serialization to support copying vals class DataVal : public OpaqueVal { public: @@ -42,7 +41,14 @@ public: d->Add("}"); } + DECLARE_SERIAL(DataVal); + broker::data data; + +protected: + + DataVal() + {} }; struct type_name_getter { diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 3d6aad4d1e..cfce84a1c9 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -787,6 +787,7 @@ bool comm::Manager::CloseStore(const broker::store::identifier& id, ++it; } + delete it->second->store; it->second->store = nullptr; Unref(it->second); return true; diff --git a/src/comm/Store.cc b/src/comm/Store.cc index 0d94795ce8..8c55c31785 100644 --- a/src/comm/Store.cc +++ b/src/comm/Store.cc @@ -78,17 +78,15 @@ comm::StoreHandleVal::StoreHandleVal(broker::store::identifier id, switch ( store_type ) { case StoreType::FRONTEND: - store.reset(new broker::store::frontend(comm_mgr->Endpoint(), - move(id))); + store = new broker::store::frontend(comm_mgr->Endpoint(), move(id)); break; case StoreType::MASTER: - store.reset(new broker::store::master(comm_mgr->Endpoint(), - move(id), move(backend))); + store = new broker::store::master(comm_mgr->Endpoint(), move(id), + move(backend)); break; case StoreType::CLONE: - store.reset(new broker::store::clone(comm_mgr->Endpoint(), - move(id), resync, - move(backend))); + store = new broker::store::clone(comm_mgr->Endpoint(), move(id), resync, + move(backend)); break; default: reporter->FatalError("unknown data store type: %d", @@ -139,3 +137,73 @@ void comm::StoreHandleVal::ValDescribe(ODesc* d) const d->Add("}"); } + +IMPLEMENT_SERIAL(comm::StoreHandleVal, SER_COMM_STORE_HANDLE_VAL); + +bool comm::StoreHandleVal::DoSerialize(SerialInfo* info) const + { + DO_SERIALIZE(SER_COMM_STORE_HANDLE_VAL, OpaqueVal); + + bool have_store = store != nullptr; + + if ( ! SERIALIZE(have_store) ) + return false; + + if ( ! have_store ) + return true; + + if ( ! SERIALIZE(static_cast(store_type)) ) + return false; + + if ( ! SERIALIZE_STR(store->id().data(), store->id().size()) ) + return false; + + return true; + } + +bool comm::StoreHandleVal::DoUnserialize(UnserialInfo* info) + { + DO_UNSERIALIZE(OpaqueVal); + + bool have_store; + + if ( ! UNSERIALIZE(&have_store) ) + return false; + + if ( ! have_store ) + { + store = nullptr; + return true; + } + + int type; + + if ( ! UNSERIALIZE(&type) ) + return false; + + const char* id_str; + int len; + + if ( ! UNSERIALIZE_STR(&id_str, &len) ) + return false; + + broker::store::identifier id(id_str, len); + delete [] id_str; + + auto handle = comm_mgr->LookupStore(id, static_cast(type)); + + if ( ! handle ) + { + // Passing serialized version of store handles to other Bro processes + // doesn't make sense, only allow local clones of the handle val. + reporter->Error("failed to look up unserialized store handle %s, %d", + id.data(), type); + store = nullptr; + return false; + } + + store = handle->store; + store_type = handle->store_type; + backend_type = handle->backend_type; + return true; + } diff --git a/src/comm/Store.h b/src/comm/Store.h index 3183afbbb3..b02c5b4f5b 100644 --- a/src/comm/Store.h +++ b/src/comm/Store.h @@ -98,9 +98,6 @@ private: StoreType store_type; }; -// TODO: actually need to implement Bro's serialization to support copying vals -// but doesn't make sense to "copy" a master data store, so assert we can -// lookup a store by pair locally (i.e. shouldn't send handles remotely). class StoreHandleVal : public OpaqueVal { public: @@ -112,9 +109,16 @@ public: void ValDescribe(ODesc* d) const override; - std::unique_ptr store; + DECLARE_SERIAL(StoreHandleVal); + + broker::store::frontend* store; comm::StoreType store_type; broker::util::optional backend_type; + +protected: + + StoreHandleVal() + {} }; } // namespace comm From 0cf982f1d1f9d4db458b32fdba5d068bb358c115 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 3 Feb 2015 15:11:16 -0600 Subject: [PATCH 034/256] broker integration: process debug/diagnostic reports from broker --- aux/broker | 2 +- src/DebugLogger.cc | 2 +- src/DebugLogger.h | 1 + src/comm/Manager.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/aux/broker b/aux/broker index c217119d9a..0760c6808c 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit c217119d9a484da941161d182cdc0a1f86a0d40f +Subproject commit 0760c6808c1d035b7e9f484daefe8ba0a3d6ee13 diff --git a/src/DebugLogger.cc b/src/DebugLogger.cc index 6f025e3c2b..3ce5d92888 100644 --- a/src/DebugLogger.cc +++ b/src/DebugLogger.cc @@ -19,7 +19,7 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = { { "logging", 0, false }, {"input", 0, false }, { "threading", 0, false }, { "file_analysis", 0, false }, { "plugins", 0, false }, { "broxygen", 0, false }, - { "pktio", 0, false} + { "pktio", 0, false }, { "broker", 0, false } }; DebugLogger::DebugLogger(const char* filename) diff --git a/src/DebugLogger.h b/src/DebugLogger.h index 9cd09dada1..13124657e7 100644 --- a/src/DebugLogger.h +++ b/src/DebugLogger.h @@ -32,6 +32,7 @@ enum DebugStream { DBG_PLUGINS, // Plugin system DBG_BROXYGEN, // Broxygen DBG_PKTIO, // Packet sources and dumpers. + DBG_BROKER, // Broker communication NUM_DBGS // Has to be last }; diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index cfce84a1c9..443c5f90da 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -2,6 +2,7 @@ #include "Data.h" #include "Store.h" #include +#include #include #include #include "util.h" @@ -11,6 +12,7 @@ #include "comm/messaging.bif.h" #include "comm/store.bif.h" #include "logging/Manager.h" +#include "DebugLogger.h" using namespace std; @@ -67,6 +69,15 @@ bool comm::Manager::InitPostScript() return false; } + res = broker::report::init(true); + + if ( res ) + { + fprintf(stderr, "broker::report::init failed: %s\n", + broker::strerror(res)); + return false; + } + const char* name; auto name_from_script = internal_val("Comm::endpoint_name")->AsString(); @@ -398,6 +409,8 @@ void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, for ( const auto& s : data_stores ) read->Insert(s.second->store->responses().fd()); + + read->Insert(broker::report::default_queue->fd()); } double comm::Manager::NextTimestamp(double* local_network_time) @@ -733,6 +746,52 @@ void comm::Manager::Process() } } + auto reports = broker::report::default_queue->want_pop(); + + if ( ! reports.empty() ) + { + idle = false; + + for ( auto& report : reports ) + { + if ( report.size() < 2 ) + { + reporter->Warning("got broker report msg of size %zu, expect 4", + report.size()); + continue; + } + + uint64_t* level = broker::get(report[1]); + + if ( ! level ) + { + reporter->Warning("got broker report msg w/ bad level type: %d", + static_cast(broker::which(report[1]))); + continue; + } + + auto lvl = static_cast(*level); + + switch ( lvl ) { + case broker::report::level::debug: + DBG_LOG(DBG_BROKER, broker::to_string(report).data()); + break; + case broker::report::level::info: + reporter->Info("broker info: %s", + broker::to_string(report).data()); + break; + case broker::report::level::warn: + reporter->Warning("broker warning: %s", + broker::to_string(report).data()); + break; + case broker::report::level::error: + reporter->Error("broker error: %s", + broker::to_string(report).data()); + break; + } + } + } + SetIdle(idle); } From 4dfec041352298b32d857f715b04a8be722bf89b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 3 Feb 2015 16:38:56 -0600 Subject: [PATCH 035/256] broker integration: add Comm::enable function Works like old enable_communication(), but for new broker communication mechanism. Scripts have to explicitly call this if they want to use the broker communication functionality. Saves a decent chunk of Bros' initialization time when one doesn't need communication features. --- src/Net.cc | 13 ++++- src/comm/CMakeLists.txt | 1 + src/comm/Manager.cc | 72 +++++++++++++++++++++++++--- src/comm/Manager.h | 5 +- src/comm/comm.bif | 13 +++++ src/main.cc | 11 ----- testing/btest/comm/clone_store.bro | 2 + testing/btest/comm/data.bro | 1 + testing/btest/comm/master_store.bro | 1 + testing/btest/comm/remote_event.test | 2 + testing/btest/comm/remote_log.test | 11 +++-- testing/btest/comm/remote_print.test | 2 + 12 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 src/comm/comm.bif diff --git a/src/Net.cc b/src/Net.cc index adac9c02fd..3acd4bce9d 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -34,6 +34,10 @@ #include "iosource/PktDumper.h" #include "plugin/Manager.h" +#ifdef ENABLE_BROKER +#include "comm/Manager.h" +#endif + extern "C" { #include "setsignal.h" }; @@ -315,6 +319,11 @@ void net_run() } #endif current_iosrc = src; + bool communication_enabled = using_communication; + +#ifdef ENABLE_BROKER + communication_enabled |= comm_mgr->Enabled(); +#endif if ( src ) src->Process(); // which will call net_packet_dispatch() @@ -332,7 +341,7 @@ void net_run() } } - else if ( (have_pending_timers || using_communication) && + else if ( (have_pending_timers || communication_enabled) && ! pseudo_realtime ) { // Take advantage of the lull to get up to @@ -347,7 +356,7 @@ void net_run() // us a lot of idle time, but doesn't delay near-term // timers too much. (Delaying them somewhat is okay, // since Bro timers are not high-precision anyway.) - if ( ! using_communication ) + if ( ! communication_enabled ) usleep(100000); else usleep(1000); diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt index 6453e006bf..ef41c605c7 100644 --- a/src/comm/CMakeLists.txt +++ b/src/comm/CMakeLists.txt @@ -19,6 +19,7 @@ set(comm_SRCS Store.cc ) +bif_target(comm.bif) bif_target(data.bif) bif_target(messaging.bif) bif_target(store.bif) diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 443c5f90da..7db80ebb40 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -13,6 +13,7 @@ #include "comm/store.bif.h" #include "logging/Manager.h" #include "DebugLogger.h" +#include "iosource/Manager.h" using namespace std; @@ -28,11 +29,6 @@ comm::Manager::~Manager() CloseStore(s.first.first, s.first.second); } -bool comm::Manager::InitPreScript() - { - return true; - } - static int require_field(RecordType* rt, const char* name) { auto rval = rt->FieldOffset(name); @@ -44,8 +40,11 @@ static int require_field(RecordType* rt, const char* name) return rval; } -bool comm::Manager::InitPostScript() +bool comm::Manager::Enable() { + if ( endpoint != nullptr ) + return true; + auto send_flags_type = internal_type("Comm::SendFlags")->AsRecordType(); send_flags_self_idx = require_field(send_flags_type, "self"); send_flags_peers_idx = require_field(send_flags_type, "peers"); @@ -94,11 +93,15 @@ bool comm::Manager::InitPostScript() } endpoint = unique_ptr(new broker::endpoint(name)); + iosource_mgr->Register(this, true); return true; } bool comm::Manager::Listen(uint16_t port, const char* addr, bool reuse_addr) { + if ( ! Enabled() ) + return false; + auto rval = endpoint->listen(port, addr, reuse_addr); if ( ! rval ) @@ -114,6 +117,9 @@ bool comm::Manager::Listen(uint16_t port, const char* addr, bool reuse_addr) bool comm::Manager::Connect(string addr, uint16_t port, chrono::duration retry_interval) { + if ( ! Enabled() ) + return false; + auto& peer = peers[make_pair(addr, port)]; if ( peer ) @@ -125,6 +131,9 @@ bool comm::Manager::Connect(string addr, uint16_t port, bool comm::Manager::Disconnect(const string& addr, uint16_t port) { + if ( ! Enabled() ) + return false; + auto it = peers.find(make_pair(addr, port)); if ( it == peers.end() ) @@ -137,18 +146,27 @@ bool comm::Manager::Disconnect(const string& addr, uint16_t port) bool comm::Manager::Print(string topic, string msg, Val* flags) { + if ( ! Enabled() ) + return false; + endpoint->send(move(topic), broker::message{move(msg)}, GetFlags(flags)); return true; } bool comm::Manager::Event(std::string topic, broker::message msg, int flags) { + if ( ! Enabled() ) + return false; + endpoint->send(move(topic), move(msg), flags); return true; } bool comm::Manager::Log(EnumVal* stream, RecordVal* columns, int flags) { + if ( ! Enabled() ) + return false; + auto stream_name = stream->Type()->AsEnumType()->Lookup(stream->AsEnum()); if ( ! stream_name ) @@ -176,6 +194,9 @@ bool comm::Manager::Log(EnumVal* stream, RecordVal* columns, int flags) bool comm::Manager::Event(std::string topic, RecordVal* args, Val* flags) { + if ( ! Enabled() ) + return false; + if ( ! args->Lookup(0) ) return false; @@ -198,6 +219,9 @@ bool comm::Manager::Event(std::string topic, RecordVal* args, Val* flags) bool comm::Manager::AutoEvent(string topic, Val* event, Val* flags) { + if ( ! Enabled() ) + return false; + if ( event->Type()->Tag() != TYPE_FUNC ) { reporter->Error("Comm::auto_event must operate on an event"); @@ -227,6 +251,9 @@ bool comm::Manager::AutoEvent(string topic, Val* event, Val* flags) bool comm::Manager::AutoEventStop(const string& topic, Val* event) { + if ( ! Enabled() ) + return false; + if ( event->Type()->Tag() != TYPE_FUNC ) { reporter->Error("Comm::auto_event_stop must operate on an event"); @@ -257,6 +284,9 @@ bool comm::Manager::AutoEventStop(const string& topic, Val* event) RecordVal* comm::Manager::MakeEventArgs(val_list* args) { + if ( ! Enabled() ) + return nullptr; + auto rval = new RecordVal(BifType::Record::Comm::EventArgs); auto arg_vec = new VectorVal(vector_of_data_type); rval->Assign(1, arg_vec); @@ -324,6 +354,9 @@ RecordVal* comm::Manager::MakeEventArgs(val_list* args) bool comm::Manager::SubscribeToPrints(string topic_prefix) { + if ( ! Enabled() ) + return false; + auto& q = print_subscriptions[topic_prefix]; if ( q ) @@ -335,11 +368,17 @@ bool comm::Manager::SubscribeToPrints(string topic_prefix) bool comm::Manager::UnsubscribeToPrints(const string& topic_prefix) { + if ( ! Enabled() ) + return false; + return print_subscriptions.erase(topic_prefix); } bool comm::Manager::SubscribeToEvents(string topic_prefix) { + if ( ! Enabled() ) + return false; + auto& q = event_subscriptions[topic_prefix]; if ( q ) @@ -351,11 +390,17 @@ bool comm::Manager::SubscribeToEvents(string topic_prefix) bool comm::Manager::UnsubscribeToEvents(const string& topic_prefix) { + if ( ! Enabled() ) + return false; + return event_subscriptions.erase(topic_prefix); } bool comm::Manager::SubscribeToLogs(string topic_prefix) { + if ( ! Enabled() ) + return false; + auto& q = log_subscriptions[topic_prefix]; if ( q ) @@ -367,6 +412,9 @@ bool comm::Manager::SubscribeToLogs(string topic_prefix) bool comm::Manager::UnsubscribeToLogs(const string& topic_prefix) { + if ( ! Enabled() ) + return false; + return log_subscriptions.erase(topic_prefix); } @@ -797,6 +845,9 @@ void comm::Manager::Process() bool comm::Manager::AddStore(StoreHandleVal* handle) { + if ( ! Enabled() ) + return false; + if ( ! handle->store ) return false; @@ -814,6 +865,9 @@ comm::StoreHandleVal* comm::Manager::LookupStore(const broker::store::identifier& id, comm::StoreType type) { + if ( ! Enabled() ) + return nullptr; + auto key = make_pair(id, type); auto it = data_stores.find(key); @@ -826,6 +880,9 @@ comm::Manager::LookupStore(const broker::store::identifier& id, bool comm::Manager::CloseStore(const broker::store::identifier& id, StoreType type) { + if ( ! Enabled() ) + return false; + auto key = make_pair(id, type); auto it = data_stores.find(key); @@ -854,5 +911,8 @@ bool comm::Manager::CloseStore(const broker::store::identifier& id, bool comm::Manager::TrackStoreQuery(StoreQueryCallback* cb) { + if ( ! Enabled() ) + return false; + return pending_queries.insert(cb).second; } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 31fdfa56c1..2317ecea2c 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -24,9 +24,10 @@ public: ~Manager(); - bool InitPreScript(); + bool Enable(); - bool InitPostScript(); + bool Enabled() + { return endpoint != nullptr; } bool Listen(uint16_t port, const char* addr = nullptr, bool reuse_addr = true); diff --git a/src/comm/comm.bif b/src/comm/comm.bif new file mode 100644 index 0000000000..7f8d85b720 --- /dev/null +++ b/src/comm/comm.bif @@ -0,0 +1,13 @@ + +##! General functions regarding Bro's broker communication mechanisms. + +%%{ +#include "comm/Manager.h" +%%} + +module Comm; + +function Comm::enable%(%): bool + %{ + return new Val(comm_mgr->Enable(), TYPE_BOOL); + %} diff --git a/src/main.cc b/src/main.cc index 5385ca7993..3d80833009 100644 --- a/src/main.cc +++ b/src/main.cc @@ -860,12 +860,6 @@ int main(int argc, char** argv) #ifdef ENABLE_BROKER comm_mgr = new comm::Manager(); - - if ( ! comm_mgr->InitPreScript() ) - { - fprintf(stderr, "Failed to initialize communication manager."); - exit(1); - } #endif plugin_mgr->InitPreScript(); @@ -942,11 +936,6 @@ int main(int argc, char** argv) exit(rc); } -#ifdef ENABLE_BROKER - comm_mgr->InitPostScript(); - iosource_mgr->Register(comm_mgr, true); -#endif - #ifdef USE_PERFTOOLS_DEBUG } #endif diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro index 03e0fe172f..3ea0347024 100644 --- a/testing/btest/comm/clone_store.bro +++ b/testing/btest/comm/clone_store.bro @@ -53,6 +53,7 @@ event ready() event bro_init() { + Comm::enable(); Comm::listen(9999/tcp, "127.0.0.1"); Comm::subscribe_to_events("bro/event/ready"); Comm::auto_event("bro/event/done", done); @@ -106,6 +107,7 @@ event Comm::remote_connection_established(peer_address: string, event bro_init() { + Comm::enable(); Comm::connect("127.0.0.1", 9999/tcp, 1secs); Comm::auto_event("bro/event/ready", ready); Comm::subscribe_to_events("bro/event/done"); diff --git a/testing/btest/comm/data.bro b/testing/btest/comm/data.bro index 3fb9dcd86e..dfbb8fc1d7 100644 --- a/testing/btest/comm/data.bro +++ b/testing/btest/comm/data.bro @@ -100,6 +100,7 @@ function comm_vector_to_bro_vector(d: Comm::Data): bro_vector event bro_init() { +Comm::enable(); print Comm::data_type(Comm::data(T)); print Comm::data_type(Comm::data(+1)); print Comm::data_type(Comm::data(1)); diff --git a/testing/btest/comm/master_store.bro b/testing/btest/comm/master_store.bro index 84b4ee07a1..a1cc6a8c95 100644 --- a/testing/btest/comm/master_store.bro +++ b/testing/btest/comm/master_store.bro @@ -120,6 +120,7 @@ function dv(d: Comm::Data): Comm::DataVector event bro_init() { + Comm::enable(); local myset: set[string] = {"a", "b", "c"}; local myvec: vector of string = {"alpha", "beta", "gamma"}; h = Store::create_master("master"); diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test index 9ab9a6b224..f44ed0df10 100644 --- a/testing/btest/comm/remote_event.test +++ b/testing/btest/comm/remote_event.test @@ -17,6 +17,7 @@ global auto_event_handler: event(msg: string, c: count); event bro_init() { + Comm::enable(); Comm::listen(9999/tcp, "127.0.0.1"); Comm::subscribe_to_events("bro/event/"); Comm::auto_event("bro/event/my_topic", auto_event_handler); @@ -47,6 +48,7 @@ global auto_event_handler: event(msg: string, c: count); event bro_init() { + Comm::enable(); Comm::subscribe_to_events("bro/event/my_topic"); Comm::connect("127.0.0.1", 9999/tcp, 1secs); } diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test index aea88cdc25..7cdc2ab97d 100644 --- a/testing/btest/comm/remote_log.test +++ b/testing/btest/comm/remote_log.test @@ -23,13 +23,14 @@ export { }; global log_test: event(rec: Test::Info); - - event bro_init() &priority=5 - { - Log::create_stream(Test::LOG, [$columns=Test::Info, $ev=log_test]); - } } +event bro_init() &priority=5 + { + Comm::enable(); + Log::create_stream(Test::LOG, [$columns=Test::Info, $ev=log_test]); + } + @TEST-END-FILE @TEST-START-FILE recv.bro diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test index 48dfd98bed..03e7517f20 100644 --- a/testing/btest/comm/remote_print.test +++ b/testing/btest/comm/remote_print.test @@ -14,6 +14,7 @@ redef exit_only_after_terminate = T; event bro_init() { + Comm::enable(); Comm::listen(9999/tcp, "127.0.0.1"); Comm::subscribe_to_prints("bro/print/"); } @@ -38,6 +39,7 @@ redef exit_only_after_terminate = T; event bro_init() { + Comm::enable(); Comm::subscribe_to_prints("bro/print/my_topic"); Comm::connect("127.0.0.1", 9999/tcp, 1secs); } From 67271ea897e470f6cf2b3484bcc7a6aa4f0622bf Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 3 Feb 2015 17:05:54 -0600 Subject: [PATCH 036/256] Update coverage unit test baselines. --- .../canonified_loaded_scripts.log | 10 +++++-- .../canonified_loaded_scripts.log | 10 +++++-- testing/btest/Baseline/plugins.hooks/output | 28 +++++++++++++------ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index b94df659b4..7b144198ee 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-10-31-20-38-14 +#open 2015-02-03-22-47-13 #fields name #types string scripts/base/init-bare.bro @@ -14,6 +14,8 @@ scripts/base/init-bare.bro build/scripts/base/bif/reporter.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.types.bif.bro build/scripts/base/bif/event.bif.bro + scripts/base/frameworks/comm/__load__.bro + scripts/base/frameworks/comm/main.bro scripts/base/frameworks/logging/__load__.bro scripts/base/frameworks/logging/main.bro build/scripts/base/bif/logging.bif.bro @@ -47,6 +49,10 @@ scripts/base/init-bare.bro build/scripts/base/bif/bloom-filter.bif.bro build/scripts/base/bif/cardinality-counter.bif.bro build/scripts/base/bif/top-k.bif.bro + build/scripts/base/bif/comm.bif.bro + build/scripts/base/bif/data.bif.bro + build/scripts/base/bif/messaging.bif.bro + build/scripts/base/bif/store.bif.bro build/scripts/base/bif/plugins/__load__.bro build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro build/scripts/base/bif/plugins/Bro_AYIYA.events.bif.bro @@ -115,4 +121,4 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2014-10-31-20-38-14 +#close 2015-02-03-22-47-13 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 67de0fc1dc..b102ad26a5 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-10-31-20-38-48 +#open 2015-02-03-22-47-15 #fields name #types string scripts/base/init-bare.bro @@ -14,6 +14,8 @@ scripts/base/init-bare.bro build/scripts/base/bif/reporter.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.types.bif.bro build/scripts/base/bif/event.bif.bro + scripts/base/frameworks/comm/__load__.bro + scripts/base/frameworks/comm/main.bro scripts/base/frameworks/logging/__load__.bro scripts/base/frameworks/logging/main.bro build/scripts/base/bif/logging.bif.bro @@ -47,6 +49,10 @@ scripts/base/init-bare.bro build/scripts/base/bif/bloom-filter.bif.bro build/scripts/base/bif/cardinality-counter.bif.bro build/scripts/base/bif/top-k.bif.bro + build/scripts/base/bif/comm.bif.bro + build/scripts/base/bif/data.bif.bro + build/scripts/base/bif/messaging.bif.bro + build/scripts/base/bif/store.bif.bro build/scripts/base/bif/plugins/__load__.bro build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro build/scripts/base/bif/plugins/Bro_AYIYA.events.bif.bro @@ -247,4 +253,4 @@ scripts/base/init-default.bro scripts/base/misc/find-checksum-offloading.bro scripts/base/misc/find-filtered-trace.bro scripts/policy/misc/loaded-scripts.bro -#close 2014-10-31-20-38-48 +#close 2015-02-03-22-47-15 diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 927a64692f..e198d94048 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -191,7 +191,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, (mysql::LOG, [columns=, ev=MySQL::log_mysql])) -> -0.000000 MetaHookPost CallFunction(Log::__write, (PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, (PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Cluster::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Communication::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, (Conn::LOG)) -> @@ -285,8 +285,8 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, (mysql::LOG, [columns=, ev=MySQL::log_mysql])) -> -0.000000 MetaHookPost CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) -> -0.000000 MetaHookPost CallFunction(Log::write, (PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, (PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::build, ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, (ip or not ip, and, )) -> @@ -401,10 +401,12 @@ 0.000000 MetaHookPost LoadFile(./bro.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./broxygen.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./cardinality-counter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./comm.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./const.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./consts) -> -1 0.000000 MetaHookPost LoadFile(./consts.bro) -> -1 0.000000 MetaHookPost LoadFile(./contents) -> -1 +0.000000 MetaHookPost LoadFile(./data.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./dcc-send) -> -1 0.000000 MetaHookPost LoadFile(./entities) -> -1 0.000000 MetaHookPost LoadFile(./event.bif.bro) -> -1 @@ -425,6 +427,7 @@ 0.000000 MetaHookPost LoadFile(./main) -> -1 0.000000 MetaHookPost LoadFile(./main.bro) -> -1 0.000000 MetaHookPost LoadFile(./max) -> -1 +0.000000 MetaHookPost LoadFile(./messaging.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./min) -> -1 0.000000 MetaHookPost LoadFile(./mozilla-ca-list) -> -1 0.000000 MetaHookPost LoadFile(./netstats) -> -1 @@ -440,6 +443,7 @@ 0.000000 MetaHookPost LoadFile(./sftp) -> -1 0.000000 MetaHookPost LoadFile(./site) -> -1 0.000000 MetaHookPost LoadFile(./std-dev) -> -1 +0.000000 MetaHookPost LoadFile(./store.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./strings.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./sum) -> -1 0.000000 MetaHookPost LoadFile(./top-k.bif.bro) -> -1 @@ -474,6 +478,7 @@ 0.000000 MetaHookPost LoadFile(base<...>/analyzer.bif) -> -1 0.000000 MetaHookPost LoadFile(base<...>/bro.bif) -> -1 0.000000 MetaHookPost LoadFile(base<...>/cluster) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/comm) -> -1 0.000000 MetaHookPost LoadFile(base<...>/communication) -> -1 0.000000 MetaHookPost LoadFile(base<...>/conn) -> -1 0.000000 MetaHookPost LoadFile(base<...>/conn-ids) -> -1 @@ -730,7 +735,7 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, (mysql::LOG, [columns=, ev=MySQL::log_mysql])) -0.000000 MetaHookPre CallFunction(Log::__write, (PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::__write, (PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, (Conn::LOG)) @@ -824,8 +829,8 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, (Weird::LOG, [columns=, ev=Weird::log_weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, (X509::LOG, [columns=, ev=X509::log_x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, (mysql::LOG, [columns=, ev=MySQL::log_mysql])) -0.000000 MetaHookPre CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) -0.000000 MetaHookPre CallFunction(Log::write, (PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::default_path_func, (PacketFilter::LOG, , [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, (PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Notice::want_pp, ()) 0.000000 MetaHookPre CallFunction(PacketFilter::build, ()) 0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, (ip or not ip, and, )) @@ -940,10 +945,12 @@ 0.000000 MetaHookPre LoadFile(./bro.bif.bro) 0.000000 MetaHookPre LoadFile(./broxygen.bif.bro) 0.000000 MetaHookPre LoadFile(./cardinality-counter.bif.bro) +0.000000 MetaHookPre LoadFile(./comm.bif.bro) 0.000000 MetaHookPre LoadFile(./const.bif.bro) 0.000000 MetaHookPre LoadFile(./consts) 0.000000 MetaHookPre LoadFile(./consts.bro) 0.000000 MetaHookPre LoadFile(./contents) +0.000000 MetaHookPre LoadFile(./data.bif.bro) 0.000000 MetaHookPre LoadFile(./dcc-send) 0.000000 MetaHookPre LoadFile(./entities) 0.000000 MetaHookPre LoadFile(./event.bif.bro) @@ -964,6 +971,7 @@ 0.000000 MetaHookPre LoadFile(./main) 0.000000 MetaHookPre LoadFile(./main.bro) 0.000000 MetaHookPre LoadFile(./max) +0.000000 MetaHookPre LoadFile(./messaging.bif.bro) 0.000000 MetaHookPre LoadFile(./min) 0.000000 MetaHookPre LoadFile(./mozilla-ca-list) 0.000000 MetaHookPre LoadFile(./netstats) @@ -979,6 +987,7 @@ 0.000000 MetaHookPre LoadFile(./sftp) 0.000000 MetaHookPre LoadFile(./site) 0.000000 MetaHookPre LoadFile(./std-dev) +0.000000 MetaHookPre LoadFile(./store.bif.bro) 0.000000 MetaHookPre LoadFile(./strings.bif.bro) 0.000000 MetaHookPre LoadFile(./sum) 0.000000 MetaHookPre LoadFile(./top-k.bif.bro) @@ -1013,6 +1022,7 @@ 0.000000 MetaHookPre LoadFile(base<...>/analyzer.bif) 0.000000 MetaHookPre LoadFile(base<...>/bro.bif) 0.000000 MetaHookPre LoadFile(base<...>/cluster) +0.000000 MetaHookPre LoadFile(base<...>/comm) 0.000000 MetaHookPre LoadFile(base<...>/communication) 0.000000 MetaHookPre LoadFile(base<...>/conn) 0.000000 MetaHookPre LoadFile(base<...>/conn-ids) @@ -1269,7 +1279,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) @@ -1363,8 +1373,8 @@ 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql]) -0.000000 | HookCallFunction Log::default_path_func(PacketFilter::LOG, , [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1421870896.278622, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::default_path_func(PacketFilter::LOG, , [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1423003752.294979, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) From 9592f6422530aff4873d31453954acacd6034e43 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Thu, 5 Feb 2015 12:44:10 -0500 Subject: [PATCH 037/256] Update the SOCKS analyzer to support user/pass login. - This addresses BIT-1011 - Add a new field to socks.log; "password". - Two new events; socks_login_userpass and socks_login_reply. - One new weird for unsupported authentication method. - A new test for authenticated socks traffic. - Credit to Nicolas Retrain for the initial patch. Thanks! --- scripts/base/protocols/socks/main.bro | 22 ++++++- src/analyzer/protocol/socks/SOCKS.cc | 3 +- src/analyzer/protocol/socks/events.bif | 16 +++++ .../protocol/socks/socks-analyzer.pac | 40 ++++++++++++ .../protocol/socks/socks-protocol.pac | 57 +++++++++++++++--- .../socks.log | 10 +++ .../tunnel.log | 10 +++ .../socks.log | 10 +-- .../socks.log | 10 +-- testing/btest/Traces/socks-auth.pcap | Bin 0 -> 1326 bytes .../base/protocols/socks/socks-auth.bro | 5 ++ 11 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/socks.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/tunnel.log create mode 100644 testing/btest/Traces/socks-auth.pcap create mode 100644 testing/btest/scripts/base/protocols/socks/socks-auth.bro diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index 713161d442..f60c3ce41c 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -16,8 +16,10 @@ export { id: conn_id &log; ## Protocol version of SOCKS. version: count &log; - ## Username for the proxy if extracted from the network. + ## Username used to request a login to the proxy. user: string &log &optional; + ## Password used to request a login to the proxy. + password: string &log &optional; ## Server status for the attempt at using the proxy. status: string &log &optional; ## Client requested SOCKS address. Could be an address, a name @@ -91,3 +93,21 @@ event socks_reply(c: connection, version: count, reply: count, sa: SOCKS::Addres if ( "SOCKS" in c$service ) Log::write(SOCKS::LOG, c$socks); } + +event socks_login_userpass(c: connection, user: string, password: string) &priority=5 + { + # Authentication only possible with the version 5. + set_session(c, 5); + + c$socks$user = user; + c$socks$password = password; + } + +event socks_login_reply(c: connection, code: count) &priority=5 + { + # Authentication only possible with the version 5. + set_session(c, 5); + + c$socks$status = v5_status[code]; + } + diff --git a/src/analyzer/protocol/socks/SOCKS.cc b/src/analyzer/protocol/socks/SOCKS.cc index e678528f35..ec1e85653b 100644 --- a/src/analyzer/protocol/socks/SOCKS.cc +++ b/src/analyzer/protocol/socks/SOCKS.cc @@ -57,8 +57,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) // with the rest of the conneciton. // // Note that we assume that no payload data arrives before both endpoints - // are done with there part of the SOCKS protocol. - + // are done with their part of the SOCKS protocol. if ( ! pia ) { pia = new pia::PIA_TCP(Conn()); diff --git a/src/analyzer/protocol/socks/events.bif b/src/analyzer/protocol/socks/events.bif index 4f1f8ad1cd..ece69140a1 100644 --- a/src/analyzer/protocol/socks/events.bif +++ b/src/analyzer/protocol/socks/events.bif @@ -27,3 +27,19 @@ event socks_request%(c: connection, version: count, request_type: count, sa: SOC ## p: The destination port for the proxied traffic. event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Address, p: port%); +## Generated when a SOCKS client performs username and password based login. +## +## c: The parent connection of the proxy. +## +## user: The given username. +## +## password: The given password. +event socks_login_userpass%(c: connection, user: string, password: string%); + +## Generated when a SOCKS server replies to a login attempt. +## +## c: The parent connection of the proxy. +## +## code: The response code for the attempted login. +event socks_login_reply%(c: connection, code: count%); + diff --git a/src/analyzer/protocol/socks/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac index db98b3f4b3..7d634e2f46 100644 --- a/src/analyzer/protocol/socks/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -148,6 +148,31 @@ refine connection SOCKS_Conn += { return true; %} + function socks5_auth_request_userpass(request: SOCKS5_Auth_Request_UserPass): bool + %{ + StringVal* user = new StringVal(${request.username}.length(), (const char*) ${request.username}.begin()); + StringVal* pass = new StringVal(${request.password}.length(), (const char*) ${request.password}.begin()); + + BifEvent::generate_socks_login_userpass(bro_analyzer(), + bro_analyzer()->Conn(), + user, pass); + return true; + %} + + function socks5_unsupported_authentication(auth_method: uint8): bool + %{ + reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_%d", auth_method)); + return true; + %} + + function socks5_auth_reply(reply: SOCKS5_Auth_Reply): bool + %{ + BifEvent::generate_socks_login_reply(bro_analyzer(), + bro_analyzer()->Conn(), + ${reply.code}); + return true; + %} + function version_error(version: uint8): bool %{ bro_analyzer()->ProtocolViolation(fmt("unsupported/unknown SOCKS version %d", version)); @@ -176,3 +201,18 @@ refine typeattr SOCKS5_Request += &let { refine typeattr SOCKS5_Reply += &let { proc: bool = $context.connection.socks5_reply(this); }; + +refine typeattr SOCKS5_Auth_Negotiation_Reply += &let { +}; + +refine typeattr SOCKS5_Auth_Request_UserPass += &let { + proc: bool = $context.connection.socks5_auth_request_userpass(this); +}; + +refine typeattr SOCKS5_Auth_Reply += &let { + proc: bool = $context.connection.socks5_auth_reply(this); +}; + +refine typeattr SOCKS5_Unsupported_Authentication += &let { + proc: bool = $context.connection.socks5_unsupported_authentication($context.connection.v5_auth_method()); +}; diff --git a/src/analyzer/protocol/socks/socks-protocol.pac b/src/analyzer/protocol/socks/socks-protocol.pac index 05ca4bc861..4e48ea0672 100644 --- a/src/analyzer/protocol/socks/socks-protocol.pac +++ b/src/analyzer/protocol/socks/socks-protocol.pac @@ -2,9 +2,10 @@ type SOCKS_Version(is_orig: bool) = record { version: uint8; msg: case version of { - 4 -> socks4_msg: SOCKS4_Message(is_orig); - 5 -> socks5_msg: SOCKS5_Message(is_orig); - default -> socks_msg_fail: SOCKS_Version_Error(version); + 1 -> socks5_auth_msg: SOCKS5_Auth_Message(is_orig); + 4 -> socks4_msg: SOCKS4_Message(is_orig); + 5 -> socks5_msg: SOCKS5_Message(is_orig); + default -> socks_msg_fail: SOCKS_Version_Error(version); }; }; @@ -14,10 +15,11 @@ type SOCKS_Version_Error(version: uint8) = record { # SOCKS5 Implementation type SOCKS5_Message(is_orig: bool) = case $context.connection.v5_past_authentication() of { - true -> msg: SOCKS5_Real_Message(is_orig); false -> auth: SOCKS5_Auth_Negotiation(is_orig); + true -> msg: SOCKS5_Real_Message(is_orig); }; + type SOCKS5_Auth_Negotiation(is_orig: bool) = case is_orig of { true -> req: SOCKS5_Auth_Negotiation_Request; false -> rep: SOCKS5_Auth_Negotiation_Reply; @@ -32,6 +34,32 @@ type SOCKS5_Auth_Negotiation_Reply = record { selected_auth_method: uint8; } &let { past_auth = $context.connection.set_v5_past_authentication(); + set_auth = $context.connection.set_v5_auth_method(selected_auth_method); +}; + +type SOCKS5_Auth_Message(is_orig: bool) = case is_orig of { + true -> req: SOCKS5_Auth_Request; + false -> rep: SOCKS5_Auth_Reply; +}; + +type SOCKS5_Auth_Request = case $context.connection.v5_auth_method() of { + 0x02 -> userpass : SOCKS5_Auth_Request_UserPass; + default -> unsupported : SOCKS5_Unsupported_Authentication; +}; + +type SOCKS5_Unsupported_Authentication = record { + crap: bytestring &restofdata; +}; + +type SOCKS5_Auth_Request_UserPass = record { + ulen : uint8; + username : bytestring &length=ulen; + plen : uint8; + password : bytestring &length=plen; +}; + +type SOCKS5_Auth_Reply = record { + code : uint8; }; type SOCKS5_Real_Message(is_orig: bool) = case is_orig of { @@ -55,10 +83,10 @@ type SOCKS5_Address = record { } &byteorder = bigendian; type SOCKS5_Request = record { - command: uint8; - reserved: uint8; - remote_name: SOCKS5_Address; - port: uint16; + command : uint8; + reserved : uint8; + remote_name : SOCKS5_Address; + port : uint16; } &byteorder = bigendian; type SOCKS5_Reply = record { @@ -99,10 +127,12 @@ type SOCKS4_Reply = record { refine connection SOCKS_Conn += { %member{ bool v5_authenticated_; + uint8 selected_auth_method_; %} %init{ v5_authenticated_ = false; + selected_auth_method_ = 255; %} function v5_past_authentication(): bool @@ -115,5 +145,16 @@ refine connection SOCKS_Conn += { v5_authenticated_ = true; return true; %} + + function set_v5_auth_method(method: uint8): bool + %{ + selected_auth_method_ = method; + return true; + %} + + function v5_auth_method(): uint8 + %{ + return selected_auth_method_; + %} }; diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/socks.log b/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/socks.log new file mode 100644 index 0000000000..cc5fa80191 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/socks.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path socks +#open 2015-02-05-16-13-12 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user password status request.host request.name request_p bound.host bound.name bound_p +#types time string addr port addr port count string string string addr string port addr string port +1368517392.724989 CXWv6p3arKYeMETxOg 192.168.0.2 55951 192.168.0.1 1080 5 bob alice succeeded 192.168.0.2 - 22 192.168.0.1 - 55951 +#close 2015-02-05-16-13-12 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/tunnel.log b/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/tunnel.log new file mode 100644 index 0000000000..d53238df93 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.socks-auth/tunnel.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2015-02-05-16-13-12 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1368517392.728523 - 192.168.0.2 0 192.168.0.1 1080 Tunnel::SOCKS Tunnel::DISCOVER +#close 2015-02-05-16-13-12 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log index 148e4adf02..f69df31b66 100644 --- a/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path socks -#open 2013-08-26-19-04-20 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user status request.host request.name request_p bound.host bound.name bound_p -#types time string addr port addr port count string string addr string port addr string port -1340213015.276495 CjhGID4nQcgTWjvg4c 10.0.0.55 53994 60.190.189.214 8124 5 - succeeded - www.osnews.com 80 192.168.0.31 - 2688 -#close 2013-08-26-19-04-20 +#open 2015-02-05-17-39-14 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user password status request.host request.name request_p bound.host bound.name bound_p +#types time string addr port addr port count string string string addr string port addr string port +1340213015.276495 CjhGID4nQcgTWjvg4c 10.0.0.55 53994 60.190.189.214 8124 5 - - succeeded - www.osnews.com 80 192.168.0.31 - 2688 +#close 2015-02-05-17-39-14 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log index d706a11da3..de7b26f875 100644 --- a/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path socks -#open 2013-08-26-19-04-20 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user status request.host request.name request_p bound.host bound.name bound_p -#types time string addr port addr port count string string addr string port addr string port -1340113261.914619 CXWv6p3arKYeMETxOg 10.0.0.50 59580 85.194.84.197 1080 5 - succeeded - www.google.com 443 0.0.0.0 - 443 -#close 2013-08-26-19-04-20 +#open 2015-02-05-17-39-29 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user password status request.host request.name request_p bound.host bound.name bound_p +#types time string addr port addr port count string string string addr string port addr string port +1340113261.914619 CXWv6p3arKYeMETxOg 10.0.0.50 59580 85.194.84.197 1080 5 - - succeeded - www.google.com 443 0.0.0.0 - 443 +#close 2015-02-05-17-39-29 diff --git a/testing/btest/Traces/socks-auth.pcap b/testing/btest/Traces/socks-auth.pcap new file mode 100644 index 0000000000000000000000000000000000000000..1570e229473da081b50bd3906a3263503896de6a GIT binary patch literal 1326 zcmaKsPiWIn9LIkzFX_UfGfpY9D5wV$MAW)E5-sZxrA#(N@HTb2xuGEQ<~hefgf^Ff z?y`ypWlTXt@T54QNb%3Wfs`J-dGe;Xrv84frsSp7!mlJDeDZyt_xrss>(46+s1W^H zEdYi$=J(*@yAOSE9;2`oPSwl-kr!CAid?8JV@=wjO=e-!>&?Rx1mE3X;fWA*S{i& z13igDJP3bxhz&rZ#(^t@okwgesH`BDbqKrYBowqz!IEb><FdsoPSj;elW54rQ$+{kxuPd#Iyhx zzeOpVI}Dh_gj8KR3;whqrg{=lr+G;xGCp%>M!SCd*6bX?cbQV$q|{SF!HBFN!%%8P zNPQH+ZB$^1etNR^zfw;N;&4wQO8s=dLu?X}31)4d0TZ}q12|v+EW5)GH~I95uaJvKz{QEvA^*sZ@mQR#e>ZU7(~phT976yr03CO%@0dt zxfS9wD^3GQ*GmUBeoi2LnPztVZk%i>m^_S5gV#v@_b6=6iOl_p%*#lh^h{U(QH^}q qAvzXq>*gfGvW3xXUhLZ8h}b?~G93G0)x%voJ}wcNhPU)?z4Ql$s7wg} literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/socks/socks-auth.bro b/testing/btest/scripts/base/protocols/socks/socks-auth.bro new file mode 100644 index 0000000000..2123dc1d45 --- /dev/null +++ b/testing/btest/scripts/base/protocols/socks/socks-auth.bro @@ -0,0 +1,5 @@ +# @TEST-EXEC: bro -r $TRACES/socks-auth.pcap %INPUT +# @TEST-EXEC: btest-diff socks.log +# @TEST-EXEC: btest-diff tunnel.log + +@load base/protocols/socks From 0253f49a9433766bcbe3530a9a63f80592d0504c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 6 Feb 2015 16:54:01 -0600 Subject: [PATCH 038/256] broker integration: adapt to change in expiration_time --- aux/broker | 2 +- src/comm/store.bif | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/aux/broker b/aux/broker index 0760c6808c..b0d97b1fcb 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 0760c6808c1d035b7e9f484daefe8ba0a3d6ee13 +Subproject commit b0d97b1fcbdcb9027bd34031c8706be0c0ab315b diff --git a/src/comm/store.bif b/src/comm/store.bif index 7d09704d31..18e63282e8 100644 --- a/src/comm/store.bif +++ b/src/comm/store.bif @@ -108,20 +108,26 @@ function Store::insert%(h: opaque of Store::Handle, auto& key = comm::opaque_field_to_data(k->AsRecordVal(), frame); auto& val = comm::opaque_field_to_data(v->AsRecordVal(), frame); - broker::util::optional expiry; + using broker::store::expiration_time; + broker::util::optional expiry; auto abs_expiry_val = e->AsRecordVal()->Lookup(0); - auto rel_expiry_val = e->AsRecordVal()->Lookup(1); if ( abs_expiry_val ) { - auto tag = broker::store::expiration_time::tag::absolute; - expiry = broker::store::expiration_time(abs_expiry_val->AsTime(), tag); + expiry = expiration_time(abs_expiry_val->AsTime()); + handle->store->insert(key, val, expiry); + return new Val(true, TYPE_BOOL); } - else if ( rel_expiry_val ) + + auto rel_expiry_val = e->AsRecordVal()->Lookup(1); + + if ( rel_expiry_val ) { - auto tag = broker::store::expiration_time::tag::since_last_modification; - expiry = broker::store::expiration_time(rel_expiry_val->AsInterval(), tag); + auto ct = broker::time_point::now().value; + expiry = expiration_time(rel_expiry_val->AsInterval(), ct); + handle->store->insert(key, val, expiry); + return new Val(true, TYPE_BOOL); } handle->store->insert(key, val, expiry); From 3190ca275e4c64ea0eb6c8ddbd81bc6afe95bc04 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 6 Feb 2015 19:32:08 -0500 Subject: [PATCH 039/256] SSH: Fix some memleaks. --- src/analyzer/protocol/ssh/ssh-protocol.pac | 167 +++++++++++---------- 1 file changed, 89 insertions(+), 78 deletions(-) diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index 36bfcaedf3..e642e87cea 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -6,44 +6,44 @@ enum version { enum state { VERSION_EXCHANGE = 0, - KEX_INIT = 1, - KEX_DH_GEX = 2, - KEX_DH = 3, - KEX_ECC = 4, - KEX_GSS = 5, - KEX_RSA = 6, - ENCRYPTED = 7, + KEX_INIT = 1, + KEX_DH_GEX = 2, + KEX_DH = 3, + KEX_ECC = 4, + KEX_GSS = 5, + KEX_RSA = 6, + ENCRYPTED = 7, }; -# diffie-hellman-group1-sha1 [RFC4253] Section 8.1 -# diffie-hellman-group14-sha1 [RFC4253] Section 8.2 +# diffie-hellman-group1-sha1 [RFC4253] Section 8.1 +# diffie-hellman-group14-sha1 [RFC4253] Section 8.2 enum KEX_DH_message_id { SSH_MSG_KEXDH_INIT = 30, SSH_MSG_KEXDH_REPLY = 31, }; -# diffie-hellman-group-exchange-sha1 [RFC4419] Section 4.1 -# diffie-hellman-group-exchange-sha256 [RFC4419] Section 4.2 +# diffie-hellman-group-exchange-sha1 [RFC4419] Section 4.1 +# diffie-hellman-group-exchange-sha256 [RFC4419] Section 4.2 enum KEX_DH_GEX_message_id { - SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, - SSH_MSG_KEX_DH_GEX_GROUP = 31, - SSH_MSG_KEX_DH_GEX_INIT = 32, - SSH_MSG_KEX_DH_GEX_REPLY = 33, - SSH_MSG_KEX_DH_GEX_REQUEST = 34, + SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30, + SSH_MSG_KEX_DH_GEX_GROUP = 31, + SSH_MSG_KEX_DH_GEX_INIT = 32, + SSH_MSG_KEX_DH_GEX_REPLY = 33, + SSH_MSG_KEX_DH_GEX_REQUEST = 34, }; -# rsa1024-sha1 [RFC4432] -# rsa2048-sha256 [RFC4432] +# rsa1024-sha1 [RFC4432] +# rsa2048-sha256 [RFC4432] enum KEX_RSA_message_id { - SSH_MSG_KEXRSA_PUBKEY = 30, - SSH_MSG_KEXRSA_SECRET = 31, - SSH_MSG_KEXRSA_DONE = 32, + SSH_MSG_KEXRSA_PUBKEY = 30, + SSH_MSG_KEXRSA_SECRET = 31, + SSH_MSG_KEXRSA_DONE = 32, }; -# gss-group1-sha1-* [RFC4462] Section 2.3 -# gss-group14-sha1-* [RFC4462] Section 2.4 -# gss-gex-sha1-* [RFC4462] Section 2.5 -# gss-* [RFC4462] Section 2.6 +# gss-group1-sha1-* [RFC4462] Section 2.3 +# gss-group14-sha1-* [RFC4462] Section 2.4 +# gss-gex-sha1-* [RFC4462] Section 2.5 +# gss-* [RFC4462] Section 2.6 enum KEX_GSS_message_id { SSH_MSG_KEXGSS_INIT = 30, SSH_MSG_KEXGSS_CONTINUE = 31, @@ -56,8 +56,8 @@ enum KEX_GSS_message_id { # ecdh-sha2-* [RFC5656] enum KEX_ECDH_message_id { - SSH_MSG_KEX_ECDH_INIT = 30, - SSH_MSG_KEX_ECDH_REPLY = 31, + SSH_MSG_KEX_ECDH_INIT = 30, + SSH_MSG_KEX_ECDH_REPLY = 31, }; # ecmqv-sha2 [RFC5656] @@ -67,74 +67,74 @@ enum KEX_ECMQV_message_id { }; enum ssh1_message_id { - SSH_MSG_NONE = 0, - SSH_MSG_DISCONNECT = 1, - SSH_SMSG_PUBLIC_KEY = 2, - SSH_CMSG_SESSION_KEY = 3, - SSH_CMSG_USER = 4, - SSH_CMSG_AUTH_RHOSTS = 5, - SSH_CMSG_AUTH_RSA = 6, - SSH_SMSG_AUTH_RSA_CHALLENGE = 7, - SSH_CMSG_AUTH_RSA_RESPONSE = 8, - SSH_CMSG_AUTH_PASSWORD = 9, - SSH_CMSG_REQUEST_PTY = 10, - SSH_CMSG_WINDOW_SIZE = 11, - SSH_CMSG_EXEC_SHELL = 12, - SSH_CMSG_EXEC_CMD = 13, - SSH_SMSG_SUCCESS = 14, - SSH_SMSG_FAILURE = 15, - SSH_CMSG_STDIN_DATA = 16, - SSH_SMSG_STDOUT_DATA = 17, - SSH_SMSG_STDERR_DATA = 18, - SSH_CMSG_EOF = 19, - SSH_SMSG_EXITSTATUS = 20, + SSH_MSG_NONE = 0, + SSH_MSG_DISCONNECT = 1, + SSH_SMSG_PUBLIC_KEY = 2, + SSH_CMSG_SESSION_KEY = 3, + SSH_CMSG_USER = 4, + SSH_CMSG_AUTH_RHOSTS = 5, + SSH_CMSG_AUTH_RSA = 6, + SSH_SMSG_AUTH_RSA_CHALLENGE = 7, + SSH_CMSG_AUTH_RSA_RESPONSE = 8, + SSH_CMSG_AUTH_PASSWORD = 9, + SSH_CMSG_REQUEST_PTY = 10, + SSH_CMSG_WINDOW_SIZE = 11, + SSH_CMSG_EXEC_SHELL = 12, + SSH_CMSG_EXEC_CMD = 13, + SSH_SMSG_SUCCESS = 14, + SSH_SMSG_FAILURE = 15, + SSH_CMSG_STDIN_DATA = 16, + SSH_SMSG_STDOUT_DATA = 17, + SSH_SMSG_STDERR_DATA = 18, + SSH_CMSG_EOF = 19, + SSH_SMSG_EXITSTATUS = 20, SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 21, SSH_MSG_CHANNEL_OPEN_FAILURE = 22, - SSH_MSG_CHANNEL_DATA = 23, - SSH_MSG_CHANNEL_CLOSE = 24, + SSH_MSG_CHANNEL_DATA = 23, + SSH_MSG_CHANNEL_CLOSE = 24, SSH_MSG_CHANNEL_CLOSE_CONFIRMATION = 25, SSH_CMSG_X11_REQUEST_FORWARDING_OLD = 26, - SSH_SMSG_X11_OPEN = 27, + SSH_SMSG_X11_OPEN = 27, SSH_CMSG_PORT_FORWARD_REQUEST = 28, - SSH_MSG_PORT_OPEN = 29, + SSH_MSG_PORT_OPEN = 29, SSH_CMSG_AGENT_REQUEST_FORWARDING = 30, - SSH_SMSG_AGENT_OPEN = 31, - SSH_MSG_IGNORE = 32, - SSH_CMSG_EXIT_CONFIRMATION = 33, + SSH_SMSG_AGENT_OPEN = 31, + SSH_MSG_IGNORE = 32, + SSH_CMSG_EXIT_CONFIRMATION = 33, SSH_CMSG_X11_REQUEST_FORWARDING = 34, - SSH_CMSG_AUTH_RHOSTS_RSA = 35, - SSH_MSG_DEBUG = 36, + SSH_CMSG_AUTH_RHOSTS_RSA = 35, + SSH_MSG_DEBUG = 36, SSH_CMSG_REQUEST_COMPRESSION = 37, - SSH_CMSG_MAX_PACKET_SIZE = 38, - SSH_CMSG_AUTH_TIS = 39, - SSH_SMSG_AUTH_TIS_CHALLENGE = 40, - SSH_CMSG_AUTH_TIS_RESPONSE = 41, - SSH_CMSG_AUTH_KERBEROS = 42, + SSH_CMSG_MAX_PACKET_SIZE = 38, + SSH_CMSG_AUTH_TIS = 39, + SSH_SMSG_AUTH_TIS_CHALLENGE = 40, + SSH_CMSG_AUTH_TIS_RESPONSE = 41, + SSH_CMSG_AUTH_KERBEROS = 42, SSH_SMSG_AUTH_KERBEROS_RESPONSE = 43, - SSH_CMSG_HAVE_KERBEROS_TGT = 44, + SSH_CMSG_HAVE_KERBEROS_TGT = 44, }; enum ssh2_message_id { - MSG_DISCONNECT = 1, - MSG_IGNORE = 2, - MSG_UNIMPLEMENTED = 3, - MSG_DEBUG = 4, - MSG_SERVICE_REQUEST = 5, - MSG_SERVICE_ACCEPT = 6, - MSG_KEXINIT = 20, - MSG_NEWKEYS = 21, + MSG_DISCONNECT = 1, + MSG_IGNORE = 2, + MSG_UNIMPLEMENTED = 3, + MSG_DEBUG = 4, + MSG_SERVICE_REQUEST = 5, + MSG_SERVICE_ACCEPT = 6, + MSG_KEXINIT = 20, + MSG_NEWKEYS = 21, }; ## SSH Generic type SSH_PDU(is_orig: bool) = case $context.connection.get_state(is_orig) of { - VERSION_EXCHANGE -> version: SSH_Version(is_orig); - KEX_INIT -> kex: SSH_Key_Exchange(is_orig); - KEX_DH_GEX -> kex_dh_gex: SSH_Key_Exchange_DH_GEX(is_orig); - KEX_DH -> kex_dh: SSH_Key_Exchange_DH(is_orig); - KEX_ECC -> kex_ecc: SSH_Key_Exchange_ECC(is_orig); - KEX_GSS -> kex_gss: SSH_Key_Exchange_GSS(is_orig); - KEX_RSA -> kex_rsa: SSH_Key_Exchange_RSA(is_orig); + VERSION_EXCHANGE -> version: SSH_Version(is_orig); + KEX_INIT -> kex: SSH_Key_Exchange(is_orig); + KEX_DH_GEX -> kex_dh_gex: SSH_Key_Exchange_DH_GEX(is_orig); + KEX_DH -> kex_dh: SSH_Key_Exchange_DH(is_orig); + KEX_ECC -> kex_ecc: SSH_Key_Exchange_ECC(is_orig); + KEX_GSS -> kex_gss: SSH_Key_Exchange_GSS(is_orig); + KEX_RSA -> kex_rsa: SSH_Key_Exchange_RSA(is_orig); } &byteorder=bigendian; type SSH_Version(is_orig: bool) = record { @@ -425,6 +425,11 @@ refine connection SSH_Conn += { kex_algorithm_ = bytestring(); %} + %cleanup{ + kex_algorithm_.free(); + kex_algs_cache_.free(); + %} + function get_state(is_orig: bool): int %{ if ( is_orig ) @@ -514,6 +519,9 @@ refine connection SSH_Conn += { kex_algorithm_.init((const uint8 *) client_list->Lookup(i)->AsStringVal()->Bytes(), client_list->Lookup(i)->AsStringVal()->Len()); + Unref(client_list); + Unref(server_list); + // UNTESTED if ( update_kex_state_if_equal("rsa1024-sha1", KEX_RSA) ) return true; @@ -556,6 +564,9 @@ refine connection SSH_Conn += { } } } + + Unref(client_list); + Unref(server_list); return true; From 530c3c0c6b19fe0e708a076a79567f9fa8334216 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sun, 8 Feb 2015 18:20:38 -0800 Subject: [PATCH 040/256] Changing load order for plugin scripts. This can be need if they depends on each other. --- src/plugin/Manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index 2ca34d94f3..ab0b85676b 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -172,7 +172,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_ // Load {bif,scripts}/__load__.bro automatically. - string init = dir + "scripts/__load__.bro"; + string init = dir + "lib/bif/__load__.bro"; if ( is_file(init) ) { @@ -180,7 +180,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_ scripts_to_load.push_back(init); } - init = dir + "lib/bif/__load__.bro"; + init = dir + "scripts/__load__.bro"; if ( is_file(init) ) { From 23b9705a7bbd6333b767b8908be2ddcf7017b5a5 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sun, 8 Feb 2015 18:21:23 -0800 Subject: [PATCH 041/256] Fixing analyzer tag types for some Files::* functions. --- CHANGES | 6 ++++++ VERSION | 2 +- scripts/base/frameworks/files/main.bro | 22 +++++++++++----------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index d1031765cc..3367c878cd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ +2.3-413 | 2015-02-08 18:23:05 -0800 + + * Fixing analyzer tag types for some Files::* functions. (Robin Sommer) + + * Changing load order for plugin scripts. (Robin Sommer) + 2.3-411 | 2015-02-05 10:05:48 -0600 * Fix file analysis of files with total size below the bof_buffer size diff --git a/VERSION b/VERSION index defa33cc31..fca56f2eeb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3-411 +2.3-413 diff --git a/scripts/base/frameworks/files/main.bro b/scripts/base/frameworks/files/main.bro index e335d4be9d..94a46578c0 100644 --- a/scripts/base/frameworks/files/main.bro +++ b/scripts/base/frameworks/files/main.bro @@ -267,7 +267,7 @@ export { ## mts: The set of MIME types, each in the form "foo/bar" (case-insensitive). ## ## Returns: True if the MIME types were successfully registered. - global register_for_mime_types: function(tag: Analyzer::Tag, mts: set[string]) : bool; + global register_for_mime_types: function(tag: Files::Tag, mts: set[string]) : bool; ## Registers a MIME type for an analyzer. If a future file with this type is seen, ## the analyzer will be automatically assigned to parsing it. The function *adds* @@ -278,20 +278,20 @@ export { ## mt: The MIME type in the form "foo/bar" (case-insensitive). ## ## Returns: True if the MIME type was successfully registered. - global register_for_mime_type: function(tag: Analyzer::Tag, mt: string) : bool; + global register_for_mime_type: function(tag: Files::Tag, mt: string) : bool; ## Returns a set of all MIME types currently registered for a specific analyzer. ## ## tag: The tag of the analyzer. ## ## Returns: The set of MIME types. - global registered_mime_types: function(tag: Analyzer::Tag) : set[string]; + global registered_mime_types: function(tag: Files::Tag) : set[string]; ## Returns a table of all MIME-type-to-analyzer mappings currently registered. ## ## Returns: A table mapping each analyzer to the set of MIME types ## registered for it. - global all_registered_mime_types: function() : table[Analyzer::Tag] of set[string]; + global all_registered_mime_types: function() : table[Files::Tag] of set[string]; ## Event that can be handled to access the Info record as it is sent on ## to the logging framework. @@ -306,8 +306,8 @@ redef record fa_file += { global registered_protocols: table[Analyzer::Tag] of ProtoRegistration = table(); # Store the MIME type to analyzer mappings. -global mime_types: table[Analyzer::Tag] of set[string]; -global mime_type_to_analyzers: table[string] of set[Analyzer::Tag]; +global mime_types: table[Files::Tag] of set[string]; +global mime_type_to_analyzers: table[string] of set[Files::Tag]; global analyzer_add_callbacks: table[Files::Tag] of function(f: fa_file, args: AnalyzerArgs) = table(); @@ -401,7 +401,7 @@ function register_protocol(tag: Analyzer::Tag, reg: ProtoRegistration): bool return result; } -function register_for_mime_types(tag: Analyzer::Tag, mime_types: set[string]) : bool +function register_for_mime_types(tag: Files::Tag, mime_types: set[string]) : bool { local rc = T; @@ -414,7 +414,7 @@ function register_for_mime_types(tag: Analyzer::Tag, mime_types: set[string]) : return rc; } -function register_for_mime_type(tag: Analyzer::Tag, mt: string) : bool +function register_for_mime_type(tag: Files::Tag, mt: string) : bool { if ( tag !in mime_types ) { @@ -431,12 +431,12 @@ function register_for_mime_type(tag: Analyzer::Tag, mt: string) : bool return T; } -function registered_mime_types(tag: Analyzer::Tag) : set[string] +function registered_mime_types(tag: Files::Tag) : set[string] { return tag in mime_types ? mime_types[tag] : set(); } -function all_registered_mime_types(): table[Analyzer::Tag] of set[string] +function all_registered_mime_types(): table[Files::Tag] of set[string] { return mime_types; } @@ -451,7 +451,7 @@ function describe(f: fa_file): string return handler$describe(f); } -event get_file_handle(tag: Analyzer::Tag, c: connection, is_orig: bool) &priority=5 +event get_file_handle(tag: Files::Tag, c: connection, is_orig: bool) &priority=5 { if ( tag !in registered_protocols ) return; From 5f0a27ca31443ee3c308e49ff5b6e6b1c2fec963 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 9 Feb 2015 12:10:49 -0800 Subject: [PATCH 042/256] Submodule update - newest sqlite version --- src/3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty b/src/3rdparty index 7e15efe9d2..f2e34d731e 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 7e15efe9d28d46bfa662fcdd1cbb15ce1db285c9 +Subproject commit f2e34d731ed29bb993fbb065846faa342a8c824f From afc5767165eb6357c9564937e7975759ce76258c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 9 Feb 2015 15:48:42 -0600 Subject: [PATCH 043/256] broker integration: add events for incoming connection status updates e.g. for the listen() side of connections to tell when peers have connected or disconnected. --- aux/broker | 2 +- src/comm/Manager.cc | 74 +++++++++++++------ src/comm/comm.bif | 53 +++++++++++++ src/comm/messaging.bif | 49 ------------ .../comm.connection_updates/recv.recv.out | 2 + .../comm.connection_updates/send.send.out | 1 + .../Baseline/comm.remote_event/send.send.out | 2 +- .../Baseline/comm.remote_log/send.send.out | 2 +- .../Baseline/comm.remote_print/send.send.out | 2 +- testing/btest/comm/clone_store.bro | 6 +- testing/btest/comm/connection_updates.bro | 55 ++++++++++++++ testing/btest/comm/remote_event.test | 8 +- testing/btest/comm/remote_log.test | 8 +- testing/btest/comm/remote_print.test | 8 +- 14 files changed, 182 insertions(+), 90 deletions(-) create mode 100644 testing/btest/Baseline/comm.connection_updates/recv.recv.out create mode 100644 testing/btest/Baseline/comm.connection_updates/send.send.out create mode 100644 testing/btest/comm/connection_updates.bro diff --git a/aux/broker b/aux/broker index b0d97b1fcb..4fae86cd67 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit b0d97b1fcbdcb9027bd34031c8706be0c0ab315b +Subproject commit 4fae86cd67b999f48a2f2f354c91e4b1b343b2a1 diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 7db80ebb40..1dc7cc5415 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -8,6 +8,7 @@ #include "util.h" #include "Var.h" #include "Reporter.h" +#include "comm/comm.bif.h" #include "comm/data.bif.h" #include "comm/messaging.bif.h" #include "comm/store.bif.h" @@ -444,7 +445,8 @@ int comm::Manager::GetFlags(Val* flags) void comm::Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, iosource::FD_Set* except) { - read->Insert(endpoint->peer_status().fd()); + read->Insert(endpoint->outgoing_connection_status().fd()); + read->Insert(endpoint->incoming_connection_status().fd()); for ( const auto& ps : print_subscriptions ) read->Insert(ps.second.fd()); @@ -523,57 +525,85 @@ static RecordVal* response_to_val(broker::store::response r) void comm::Manager::Process() { bool idle = true; - auto peer_status_updates = endpoint->peer_status().want_pop(); + auto outgoing_connection_updates = + endpoint->outgoing_connection_status().want_pop(); + auto incoming_connection_updates = + endpoint->incoming_connection_status().want_pop(); - if ( ! peer_status_updates.empty() ) + for ( auto& u : outgoing_connection_updates ) + { idle = false; - for ( auto& u : peer_status_updates ) - { - if ( ! u.relation.remote() ) - continue; - switch ( u.status ) { - case broker::peer_status::tag::established: - if ( Comm::remote_connection_established ) + case broker::outgoing_connection_status::tag::established: + if ( Comm::outgoing_connection_established ) { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new PortVal(u.relation.remote_tuple().second, TRANSPORT_TCP)); vl->append(new StringVal(u.peer_name)); - mgr.QueueEvent(Comm::remote_connection_established, vl); + mgr.QueueEvent(Comm::outgoing_connection_established, vl); } - break; - case broker::peer_status::tag::disconnected: - if ( Comm::remote_connection_broken ) + case broker::outgoing_connection_status::tag::disconnected: + if ( Comm::outgoing_connection_broken ) { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new PortVal(u.relation.remote_tuple().second, TRANSPORT_TCP)); - mgr.QueueEvent(Comm::remote_connection_broken, vl); + mgr.QueueEvent(Comm::outgoing_connection_broken, vl); } - break; - case broker::peer_status::tag::incompatible: - if ( Comm::remote_connection_incompatible ) + case broker::outgoing_connection_status::tag::incompatible: + if ( Comm::outgoing_connection_incompatible ) { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new PortVal(u.relation.remote_tuple().second, TRANSPORT_TCP)); - mgr.QueueEvent(Comm::remote_connection_incompatible, vl); + mgr.QueueEvent(Comm::outgoing_connection_incompatible, vl); } - break; default: - reporter->InternalWarning("unknown broker::peer_status::tag : %d", - static_cast(u.status)); + reporter->InternalWarning( + "unknown broker::outgoing_connection_status::tag : %d", + static_cast(u.status)); + break; + } + } + + for ( auto& u : incoming_connection_updates ) + { + idle = false; + + switch ( u.status ) { + case broker::incoming_connection_status::tag::established: + if ( Comm::incoming_connection_established ) + { + val_list* vl = new val_list; + vl->append(new StringVal(u.peer_name)); + mgr.QueueEvent(Comm::incoming_connection_established, vl); + } + break; + + case broker::incoming_connection_status::tag::disconnected: + if ( Comm::incoming_connection_broken ) + { + val_list* vl = new val_list; + vl->append(new StringVal(u.peer_name)); + mgr.QueueEvent(Comm::incoming_connection_broken, vl); + } + break; + + default: + reporter->InternalWarning( + "unknown broker::incoming_connection_status::tag : %d", + static_cast(u.status)); break; } } diff --git a/src/comm/comm.bif b/src/comm/comm.bif index 7f8d85b720..e87c6c1144 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -11,3 +11,56 @@ function Comm::enable%(%): bool %{ return new Val(comm_mgr->Enable(), TYPE_BOOL); %} + +event Comm::outgoing_connection_established%(peer_address: string, + peer_port: port, + peer_name: string%); + +event Comm::outgoing_connection_broken%(peer_address: string, + peer_port: port%); + +event Comm::outgoing_connection_incompatible%(peer_address: string, + peer_port: port%); + +event Comm::incoming_connection_established%(peer_name: string%); + +event Comm::incoming_connection_broken%(peer_name: string%); + +function Comm::listen%(p: port, a: string &default = "", + reuse: bool &default = T%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("listen port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0, + reuse); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::connect%(a: string, p: port, retry: interval%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Connect(a->CheckString(), p->Port(), + std::chrono::duration(retry)); + return new Val(rval, TYPE_BOOL); + %} + +function Comm::disconnect%(a: string, p: port%): bool + %{ + if ( ! p->IsTCP() ) + { + reporter->Error("remote connection port must use tcp"); + return new Val(false, TYPE_BOOL); + } + + auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); + return new Val(rval, TYPE_BOOL); + %} diff --git a/src/comm/messaging.bif b/src/comm/messaging.bif index f5034f842f..26f9497449 100644 --- a/src/comm/messaging.bif +++ b/src/comm/messaging.bif @@ -12,55 +12,6 @@ type Comm::SendFlags: record; type Comm::EventArgs: record; -event Comm::remote_connection_established%(peer_address: string, - peer_port: port, - peer_name: string%); - -event Comm::remote_connection_broken%(peer_address: string, - peer_port: port%); - -event Comm::remote_connection_incompatible%(peer_address: string, - peer_port: port%); - -function Comm::listen%(p: port, a: string &default = "", - reuse: bool &default = T%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("listen port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Listen(p->Port(), a->Len() ? a->CheckString() : 0, - reuse); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::connect%(a: string, p: port, retry: interval%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("remote connection port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Connect(a->CheckString(), p->Port(), - std::chrono::duration(retry)); - return new Val(rval, TYPE_BOOL); - %} - -function Comm::disconnect%(a: string, p: port%): bool - %{ - if ( ! p->IsTCP() ) - { - reporter->Error("remote connection port must use tcp"); - return new Val(false, TYPE_BOOL); - } - - auto rval = comm_mgr->Disconnect(a->CheckString(), p->Port()); - return new Val(rval, TYPE_BOOL); - %} - event Comm::print_handler%(msg: string%); function Comm::print%(topic: string, msg: string, diff --git a/testing/btest/Baseline/comm.connection_updates/recv.recv.out b/testing/btest/Baseline/comm.connection_updates/recv.recv.out new file mode 100644 index 0000000000..3f2a1a9670 --- /dev/null +++ b/testing/btest/Baseline/comm.connection_updates/recv.recv.out @@ -0,0 +1,2 @@ +Comm::incoming_connection_established, connector +Comm::incoming_connection_broken, connector diff --git a/testing/btest/Baseline/comm.connection_updates/send.send.out b/testing/btest/Baseline/comm.connection_updates/send.send.out new file mode 100644 index 0000000000..e23422e320 --- /dev/null +++ b/testing/btest/Baseline/comm.connection_updates/send.send.out @@ -0,0 +1 @@ +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp, listener diff --git a/testing/btest/Baseline/comm.remote_event/send.send.out b/testing/btest/Baseline/comm.remote_event/send.send.out index ef1f7bc7e1..9fbb21f245 100644 --- a/testing/btest/Baseline/comm.remote_event/send.send.out +++ b/testing/btest/Baseline/comm.remote_event/send.send.out @@ -1,4 +1,4 @@ -Comm::remote_connection_established, 127.0.0.1, 9999/tcp +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp got event msg, pong, 0 got auto event msg, ping, 0 got event msg, pong, 1 diff --git a/testing/btest/Baseline/comm.remote_log/send.send.out b/testing/btest/Baseline/comm.remote_log/send.send.out index 0968e6beb9..e2415290d6 100644 --- a/testing/btest/Baseline/comm.remote_log/send.send.out +++ b/testing/btest/Baseline/comm.remote_log/send.send.out @@ -1 +1 @@ -Comm::remote_connection_established, 127.0.0.1, 9999/tcp +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp diff --git a/testing/btest/Baseline/comm.remote_print/send.send.out b/testing/btest/Baseline/comm.remote_print/send.send.out index 982ee993f6..fc5996194d 100644 --- a/testing/btest/Baseline/comm.remote_print/send.send.out +++ b/testing/btest/Baseline/comm.remote_print/send.send.out @@ -1,4 +1,4 @@ -Comm::remote_connection_established, 127.0.0.1, 9999/tcp +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp got print msg, pong 0 got print msg, pong 1 got print msg, pong 2 diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro index 3ea0347024..7a8ccb3a56 100644 --- a/testing/btest/comm/clone_store.bro +++ b/testing/btest/comm/clone_store.bro @@ -81,9 +81,9 @@ event done() terminate(); } -event Comm::remote_connection_established(peer_address: string, - peer_port: port, - peer_name: string) +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) { local myset: set[string] = {"a", "b", "c"}; local myvec: vector of string = {"alpha", "beta", "gamma"}; diff --git a/testing/btest/comm/connection_updates.bro b/testing/btest/comm/connection_updates.bro new file mode 100644 index 0000000000..a1e8c517d2 --- /dev/null +++ b/testing/btest/comm/connection_updates.bro @@ -0,0 +1,55 @@ +# @TEST_SERIALIZE: brokercomm +# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE recv.bro + +redef exit_only_after_terminate = T; +redef Comm::endpoint_name = "listener"; + +event bro_init() + { + Comm::enable(); + Comm::listen(9999/tcp, "127.0.0.1"); + } + +event Comm::incoming_connection_established(peer_name: string) + { + print "Comm::incoming_connection_established", peer_name;; + } + +event Comm::incoming_connection_broken(peer_name: string) + { + print "Comm::incoming_connection_broken", peer_name;; + terminate(); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +redef exit_only_after_terminate = T; +redef Comm::endpoint_name = "connector"; + +event bro_init() + { + Comm::enable(); + Comm::connect("127.0.0.1", 9999/tcp, 1sec); + } + +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::outgoing_connection_established", + peer_address, peer_port, peer_name;; + terminate(); + } + +@TEST-END-FILE diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test index f44ed0df10..fc34ad79ec 100644 --- a/testing/btest/comm/remote_event.test +++ b/testing/btest/comm/remote_event.test @@ -55,11 +55,11 @@ event bro_init() global event_count = 0; -event Comm::remote_connection_established(peer_address: string, - peer_port: port, - peer_name: string) +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) { - print "Comm::remote_connection_established", peer_address, peer_port; + print "Comm::outgoing_connection_established", peer_address, peer_port; local args = Comm::event_args(event_handler, "ping", event_count); Comm::event("bro/event/hi", args); ++event_count; diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test index 7cdc2ab97d..47227e2fba 100644 --- a/testing/btest/comm/remote_log.test +++ b/testing/btest/comm/remote_log.test @@ -77,11 +77,11 @@ event do_write() } } -event Comm::remote_connection_established(peer_address: string, - peer_port: port, - peer_name: string) +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) { - print "Comm::remote_connection_established", peer_address, peer_port; + print "Comm::outgoing_connection_established", peer_address, peer_port; event do_write(); } diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test index 03e7517f20..28e5bccc95 100644 --- a/testing/btest/comm/remote_print.test +++ b/testing/btest/comm/remote_print.test @@ -46,11 +46,11 @@ event bro_init() global n = 0; -event Comm::remote_connection_established(peer_address: string, - peer_port: port, - peer_name: string) +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) { - print "Comm::remote_connection_established", peer_address, peer_port; + print "Comm::outgoing_connection_established", peer_address, peer_port; Comm::print("bro/print/hi", fmt("ping %d", n)); ++n; } From cfb666af2be257994584edd0ea68a8277c22ff27 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 9 Feb 2015 16:01:31 -0600 Subject: [PATCH 044/256] broker integration: move listen port for unit tests to a btest variable Later, this might be something btest itself could provide to help parallelize communication tests. E.g. unit tests requests a unique number from some range and btest coordinates the distribution of those among all tests. --- testing/btest/btest.cfg | 1 + testing/btest/comm/clone_store.bro | 10 ++++++---- testing/btest/comm/connection_updates.bro | 10 ++++++---- testing/btest/comm/remote_event.test | 10 ++++++---- testing/btest/comm/remote_log.test | 10 ++++++---- testing/btest/comm/remote_print.test | 10 ++++++---- 6 files changed, 31 insertions(+), 20 deletions(-) diff --git a/testing/btest/btest.cfg b/testing/btest/btest.cfg index 2eea514357..3c91872f5a 100644 --- a/testing/btest/btest.cfg +++ b/testing/btest/btest.cfg @@ -25,3 +25,4 @@ TMPDIR=%(testbase)s/.tmp BRO_PROFILER_FILE=%(testbase)s/.tmp/script-coverage.XXXXXX BTEST_RST_FILTER=$SCRIPTS/rst-filter BRO_DNS_FAKE=1 +BROKER_PORT=9999/tcp diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro index 7a8ccb3a56..44ef0683cf 100644 --- a/testing/btest/comm/clone_store.bro +++ b/testing/btest/comm/clone_store.bro @@ -1,8 +1,8 @@ # @TEST_SERIALIZE: brokercomm # @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt -# @TEST-EXEC: btest-bg-run clone "bro -b ../clone.bro >clone.out" -# @TEST-EXEC: btest-bg-run master "bro -b ../master.bro >master.out" +# @TEST-EXEC: btest-bg-run clone "bro -b ../clone.bro broker_port=$BROKER_PORT >clone.out" +# @TEST-EXEC: btest-bg-run master "bro -b ../master.bro broker_port=$BROKER_PORT >master.out" # @TEST-EXEC: btest-bg-wait 20 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff clone/clone.out @@ -10,6 +10,7 @@ @TEST-START-FILE clone.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; global h: opaque of Store::Handle; @@ -54,7 +55,7 @@ event ready() event bro_init() { Comm::enable(); - Comm::listen(9999/tcp, "127.0.0.1"); + Comm::listen(broker_port, "127.0.0.1"); Comm::subscribe_to_events("bro/event/ready"); Comm::auto_event("bro/event/done", done); } @@ -63,6 +64,7 @@ event bro_init() @TEST-START-FILE master.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; global h: opaque of Store::Handle; @@ -108,7 +110,7 @@ event Comm::outgoing_connection_established(peer_address: string, event bro_init() { Comm::enable(); - Comm::connect("127.0.0.1", 9999/tcp, 1secs); + Comm::connect("127.0.0.1", broker_port, 1secs); Comm::auto_event("bro/event/ready", ready); Comm::subscribe_to_events("bro/event/done"); } diff --git a/testing/btest/comm/connection_updates.bro b/testing/btest/comm/connection_updates.bro index a1e8c517d2..d6f4c99fa3 100644 --- a/testing/btest/comm/connection_updates.bro +++ b/testing/btest/comm/connection_updates.bro @@ -1,8 +1,8 @@ # @TEST_SERIALIZE: brokercomm # @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt -# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" -# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" # @TEST-EXEC: btest-bg-wait 20 # @TEST-EXEC: btest-diff recv/recv.out @@ -10,13 +10,14 @@ @TEST-START-FILE recv.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; redef Comm::endpoint_name = "listener"; event bro_init() { Comm::enable(); - Comm::listen(9999/tcp, "127.0.0.1"); + Comm::listen(broker_port, "127.0.0.1"); } event Comm::incoming_connection_established(peer_name: string) @@ -34,13 +35,14 @@ event Comm::incoming_connection_broken(peer_name: string) @TEST-START-FILE send.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; redef Comm::endpoint_name = "connector"; event bro_init() { Comm::enable(); - Comm::connect("127.0.0.1", 9999/tcp, 1sec); + Comm::connect("127.0.0.1", broker_port, 1sec); } event Comm::outgoing_connection_established(peer_address: string, diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test index fc34ad79ec..aeced18eea 100644 --- a/testing/btest/comm/remote_event.test +++ b/testing/btest/comm/remote_event.test @@ -1,8 +1,8 @@ # @TEST_SERIALIZE: brokercomm # @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt -# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" -# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" # @TEST-EXEC: btest-bg-wait 20 # @TEST-EXEC: btest-diff recv/recv.out @@ -10,6 +10,7 @@ @TEST-START-FILE recv.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; global event_handler: event(msg: string, c: count); @@ -18,7 +19,7 @@ global auto_event_handler: event(msg: string, c: count); event bro_init() { Comm::enable(); - Comm::listen(9999/tcp, "127.0.0.1"); + Comm::listen(broker_port, "127.0.0.1"); Comm::subscribe_to_events("bro/event/"); Comm::auto_event("bro/event/my_topic", auto_event_handler); } @@ -41,6 +42,7 @@ event event_handler(msg: string, n: count) @TEST-START-FILE send.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; global event_handler: event(msg: string, c: count); @@ -50,7 +52,7 @@ event bro_init() { Comm::enable(); Comm::subscribe_to_events("bro/event/my_topic"); - Comm::connect("127.0.0.1", 9999/tcp, 1secs); + Comm::connect("127.0.0.1", broker_port, 1secs); } global event_count = 0; diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test index 47227e2fba..2a6174810e 100644 --- a/testing/btest/comm/remote_log.test +++ b/testing/btest/comm/remote_log.test @@ -1,8 +1,8 @@ # @TEST_SERIALIZE: brokercomm # @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt -# @TEST-EXEC: btest-bg-run recv "bro -b ../common.bro ../recv.bro >recv.out" -# @TEST-EXEC: btest-bg-run send "bro -b ../common.bro ../send.bro >send.out" +# @TEST-EXEC: btest-bg-run recv "bro -b ../common.bro ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../common.bro ../send.bro broker_port=$BROKER_PORT >send.out" # @TEST-EXEC: btest-bg-wait 20 # @TEST-EXEC: btest-diff recv/recv.out @@ -35,11 +35,12 @@ event bro_init() &priority=5 @TEST-START-FILE recv.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; event bro_init() { - Comm::listen(9999/tcp, "127.0.0.1"); + Comm::listen(broker_port, "127.0.0.1"); Comm::subscribe_to_logs("bro/log/"); } @@ -55,12 +56,13 @@ event Test::log_test(rec: Test::Info) @TEST-START-FILE send.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; event bro_init() { Comm::enable_remote_logs(Test::LOG); - Comm::connect("127.0.0.1", 9999/tcp, 1secs); + Comm::connect("127.0.0.1", broker_port, 1secs); } global n = 0; diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test index 28e5bccc95..0c32e2c1fe 100644 --- a/testing/btest/comm/remote_print.test +++ b/testing/btest/comm/remote_print.test @@ -1,8 +1,8 @@ # @TEST_SERIALIZE: brokercomm # @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt -# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro >recv.out" -# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro >send.out" +# @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" # @TEST-EXEC: btest-bg-wait 20 # @TEST-EXEC: btest-diff recv/recv.out @@ -10,12 +10,13 @@ @TEST-START-FILE recv.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; event bro_init() { Comm::enable(); - Comm::listen(9999/tcp, "127.0.0.1"); + Comm::listen(broker_port, "127.0.0.1"); Comm::subscribe_to_prints("bro/print/"); } @@ -35,13 +36,14 @@ event Comm::print_handler(msg: string) @TEST-START-FILE send.bro +const broker_port: port &redef; redef exit_only_after_terminate = T; event bro_init() { Comm::enable(); Comm::subscribe_to_prints("bro/print/my_topic"); - Comm::connect("127.0.0.1", 9999/tcp, 1secs); + Comm::connect("127.0.0.1", broker_port, 1secs); } global n = 0; From ebc9407a2b28c81522a00063290e77c99a31c6e6 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 9 Feb 2015 16:18:46 -0600 Subject: [PATCH 045/256] broker integration: add knobs to set auto publish/advertise behavior --- scripts/base/frameworks/comm/main.bro | 5 ++++ src/comm/Manager.cc | 33 +++++++++++++++++++++++++-- src/comm/Manager.h | 4 +++- src/comm/comm.bif | 11 +++++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index a2cd1f6ac0..66dc1715f4 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -5,6 +5,11 @@ export { const endpoint_name = "" &redef; + type EndpointFlags: record { + auto_publish: bool &default = T; + auto_advertise: bool &default = T; + }; + type SendFlags: record { self: bool &default = F; peers: bool &default = T; diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 1dc7cc5415..832718b595 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -41,7 +41,25 @@ static int require_field(RecordType* rt, const char* name) return rval; } -bool comm::Manager::Enable() +static int GetEndpointFlags(Val* broker_endpoint_flags) + { + int rval = 0; + auto r = broker_endpoint_flags->AsRecordVal(); + Val* auto_publish_flag = r->Lookup("auto_publish", true); + Val* auto_advertise_flag = r->Lookup("auto_advertise", true); + + if ( auto_publish_flag->AsBool() ) + rval |= broker::AUTO_PUBLISH; + + if ( auto_advertise_flag->AsBool() ) + rval |= broker::AUTO_ADVERTISE; + + Unref(auto_publish_flag); + Unref(auto_advertise_flag); + return rval; + } + +bool comm::Manager::Enable(Val* broker_endpoint_flags) { if ( endpoint != nullptr ) return true; @@ -93,11 +111,22 @@ bool comm::Manager::Enable() name = fmt("bro@.%ld", static_cast(getpid())); } - endpoint = unique_ptr(new broker::endpoint(name)); + int flags = GetEndpointFlags(broker_endpoint_flags); + endpoint = unique_ptr(new broker::endpoint(name, flags)); iosource_mgr->Register(this, true); return true; } +bool comm::Manager::SetEndpointFlags(Val* broker_endpoint_flags) + { + if ( ! Enabled() ) + return false; + + int flags = GetEndpointFlags(broker_endpoint_flags); + endpoint->set_flags(flags); + return true; + } + bool comm::Manager::Listen(uint16_t port, const char* addr, bool reuse_addr) { if ( ! Enabled() ) diff --git a/src/comm/Manager.h b/src/comm/Manager.h index 2317ecea2c..ef1532fbc8 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -24,7 +24,9 @@ public: ~Manager(); - bool Enable(); + bool Enable(Val* flags); + + bool SetEndpointFlags(Val* flags); bool Enabled() { return endpoint != nullptr; } diff --git a/src/comm/comm.bif b/src/comm/comm.bif index e87c6c1144..aa7efac472 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -7,9 +7,16 @@ module Comm; -function Comm::enable%(%): bool +type Comm::EndpointFlags: record; + +function Comm::enable%(flags: EndpointFlags &default = EndpointFlags()%): bool %{ - return new Val(comm_mgr->Enable(), TYPE_BOOL); + return new Val(comm_mgr->Enable(flags), TYPE_BOOL); + %} + +function Comm::set_endpoint_flags%(flags: EndpointFlags &default = EndpointFlags()%): bool + %{ + return new Val(comm_mgr->SetEndpointFlags(flags), TYPE_BOOL); %} event Comm::outgoing_connection_established%(peer_address: string, From bdf21c054a5a74408d456446afd009aa2c5f04b7 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 10 Feb 2015 09:51:57 -0600 Subject: [PATCH 046/256] broker integration: add (un)publish/(un)advertise functions For when one wants to manually tune pub/sub behavior instead of use the default automatic settings of allowing publication to all peers and advertising all subscriptions to all peers. --- src/comm/Manager.cc | 36 ++++++++++++++++++++++++++++++++++++ src/comm/Manager.h | 8 ++++++++ src/comm/comm.bif | 20 ++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 832718b595..6c09c08f2b 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -448,6 +448,42 @@ bool comm::Manager::UnsubscribeToLogs(const string& topic_prefix) return log_subscriptions.erase(topic_prefix); } +bool comm::Manager::PublishTopic(broker::topic t) + { + if ( ! Enabled() ) + return false; + + endpoint->publish(move(t)); + return true; + } + +bool comm::Manager::UnpublishTopic(broker::topic t) + { + if ( ! Enabled() ) + return false; + + endpoint->unpublish(move(t)); + return true; + } + +bool comm::Manager::AdvertiseTopic(broker::topic t) + { + if ( ! Enabled() ) + return false; + + endpoint->advertise(move(t)); + return true; + } + +bool comm::Manager::UnadvertiseTopic(broker::topic t) + { + if ( ! Enabled() ) + return false; + + endpoint->unadvertise(move(t)); + return true; + } + int comm::Manager::GetFlags(Val* flags) { auto r = flags->AsRecordVal(); diff --git a/src/comm/Manager.h b/src/comm/Manager.h index ef1532fbc8..e8a8d5e5b1 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -64,6 +64,14 @@ public: bool UnsubscribeToLogs(const std::string& topic_prefix); + bool PublishTopic(broker::topic t); + + bool UnpublishTopic(broker::topic t); + + bool AdvertiseTopic(broker::topic t); + + bool UnadvertiseTopic(broker::topic t); + bool AddStore(StoreHandleVal* handle); StoreHandleVal* LookupStore(const broker::store::identifier& id, StoreType type); diff --git a/src/comm/comm.bif b/src/comm/comm.bif index aa7efac472..1d41b572f6 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -19,6 +19,26 @@ function Comm::set_endpoint_flags%(flags: EndpointFlags &default = EndpointFlags return new Val(comm_mgr->SetEndpointFlags(flags), TYPE_BOOL); %} +function Comm::publish_topic%(topic: string%): bool + %{ + return new Val(comm_mgr->PublishTopic(topic->CheckString()), TYPE_BOOL); + %} + +function Comm::unpublish_topic%(topic: string%): bool + %{ + return new Val(comm_mgr->UnpublishTopic(topic->CheckString()), TYPE_BOOL); + %} + +function Comm::advertise_topic%(topic: string%): bool + %{ + return new Val(comm_mgr->AdvertiseTopic(topic->CheckString()), TYPE_BOOL); + %} + +function Comm::unadvertise_topic%(topic: string%): bool + %{ + return new Val(comm_mgr->UnadvertiseTopic(topic->CheckString()), TYPE_BOOL); + %} + event Comm::outgoing_connection_established%(peer_address: string, peer_port: port, peer_name: string%); From fc36777e66c71fb975b344a8930bd7980b4f5e9f Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 10 Feb 2015 12:34:47 -0600 Subject: [PATCH 047/256] Add --enable-c++11 configure flag. And try to detect that compiler version is sufficient for C++11 support. --enable-broker implies --enable-c++11 --- CMakeLists.txt | 5 ++++- aux/broker | 2 +- cmake | 2 +- configure | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b31e60ac01..28ebc8b568 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,8 +177,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) ######################################################################## ## Recurse on sub-directories +if ( ENABLE_CXX11 ) + include(RequireCXX11) +endif () + if ( ENABLE_BROKER ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") add_subdirectory(aux/broker) set(brodeps ${brodeps} broker) add_definitions(-DENABLE_BROKER) diff --git a/aux/broker b/aux/broker index 4fae86cd67..0af74017e2 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 4fae86cd67b999f48a2f2f354c91e4b1b343b2a1 +Subproject commit 0af74017e28d78179a25d60ca80385af444d39f1 diff --git a/cmake b/cmake index c2057b7f15..532dd04e8c 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit c2057b7f15dedc27641a50312384505ce4f2112c +Subproject commit 532dd04e8c5027c613a65ea10bcdbaf5e876fcfa diff --git a/configure b/configure index 6235aba7dd..3f7295711c 100755 --- a/configure +++ b/configure @@ -41,6 +41,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --enable-perftools-debug use Google's perftools for debugging --enable-jemalloc link against jemalloc --enable-ruby build ruby bindings for broccoli (deprecated) + --enable-c++11 build using the C++11 standard --enable-broker enable use of the Broker communication library (requires C++ Actor Framework and C++11) --disable-broccoli don't build or install the Broccoli library @@ -182,7 +183,11 @@ while [ $# -ne 0 ]; do --enable-jemalloc) append_cache_entry ENABLE_JEMALLOC BOOL true ;; + --enable-c++11) + append_cache_entry ENABLE_CXX11 BOOL true + ;; --enable-broker) + append_cache_entry ENABLE_CXX11 BOOL true append_cache_entry ENABLE_BROKER BOOL true ;; --disable-broccoli) From 6d868d83bea1df0c149704f05361768456231315 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 10 Feb 2015 13:44:04 -0600 Subject: [PATCH 048/256] broker integration: fix unit tests to work when broker is not enabled. --- src/CMakeLists.txt | 4 ++++ src/comm-dummy/CMakeLists.txt | 13 +++++++++++++ src/comm-dummy/comm.bif | 3 +++ src/comm-dummy/data.bif | 3 +++ src/comm-dummy/messaging.bif | 3 +++ src/comm-dummy/store.bif | 3 +++ testing/btest/comm/clone_store.bro | 4 ++-- testing/btest/comm/connection_updates.bro | 4 ++-- testing/btest/comm/data.bro | 2 ++ testing/btest/comm/master_store.bro | 2 ++ testing/btest/comm/remote_event.test | 4 ++-- testing/btest/comm/remote_log.test | 4 ++-- testing/btest/comm/remote_print.test | 4 ++-- 13 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 src/comm-dummy/CMakeLists.txt create mode 100644 src/comm-dummy/comm.bif create mode 100644 src/comm-dummy/data.bif create mode 100644 src/comm-dummy/messaging.bif create mode 100644 src/comm-dummy/store.bif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 55ca12c873..323fb6f023 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -163,6 +163,10 @@ add_subdirectory(probabilistic) if ( ENABLE_BROKER ) add_subdirectory(comm) +else () + # Just to satisfy coverage unit tests until new Broker-based + # communication is enabled by default. + add_subdirectory(comm-dummy) endif () set(bro_SUBDIRS diff --git a/src/comm-dummy/CMakeLists.txt b/src/comm-dummy/CMakeLists.txt new file mode 100644 index 0000000000..cddea1342d --- /dev/null +++ b/src/comm-dummy/CMakeLists.txt @@ -0,0 +1,13 @@ +# Placeholder for Broker-based communication functionality, not enabled +# by default. This helps satisfy coverage unit tests pass regardless of +# whether Broker is enabled or not. + +include(BroSubdir) + +bif_target(comm.bif) +bif_target(data.bif) +bif_target(messaging.bif) +bif_target(store.bif) + +bro_add_subdir_library(comm_dummy ${BIF_OUTPUT_CC}) +add_dependencies(bro_comm_dummy generate_outputs) diff --git a/src/comm-dummy/comm.bif b/src/comm-dummy/comm.bif new file mode 100644 index 0000000000..b030a4cc73 --- /dev/null +++ b/src/comm-dummy/comm.bif @@ -0,0 +1,3 @@ + +##! Placeholder for Broker-based communication functionality, not enabled +##! by default. diff --git a/src/comm-dummy/data.bif b/src/comm-dummy/data.bif new file mode 100644 index 0000000000..e9b9950474 --- /dev/null +++ b/src/comm-dummy/data.bif @@ -0,0 +1,3 @@ + +##! Placeholder for Broker-based communication functionality, not enabled +##! by default diff --git a/src/comm-dummy/messaging.bif b/src/comm-dummy/messaging.bif new file mode 100644 index 0000000000..e9b9950474 --- /dev/null +++ b/src/comm-dummy/messaging.bif @@ -0,0 +1,3 @@ + +##! Placeholder for Broker-based communication functionality, not enabled +##! by default diff --git a/src/comm-dummy/store.bif b/src/comm-dummy/store.bif new file mode 100644 index 0000000000..e9b9950474 --- /dev/null +++ b/src/comm-dummy/store.bif @@ -0,0 +1,3 @@ + +##! Placeholder for Broker-based communication functionality, not enabled +##! by default diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro index 44ef0683cf..da05f45210 100644 --- a/testing/btest/comm/clone_store.bro +++ b/testing/btest/comm/clone_store.bro @@ -1,5 +1,5 @@ -# @TEST_SERIALIZE: brokercomm -# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt # @TEST-EXEC: btest-bg-run clone "bro -b ../clone.bro broker_port=$BROKER_PORT >clone.out" # @TEST-EXEC: btest-bg-run master "bro -b ../master.bro broker_port=$BROKER_PORT >master.out" diff --git a/testing/btest/comm/connection_updates.bro b/testing/btest/comm/connection_updates.bro index d6f4c99fa3..67f66646c9 100644 --- a/testing/btest/comm/connection_updates.bro +++ b/testing/btest/comm/connection_updates.bro @@ -1,5 +1,5 @@ -# @TEST_SERIALIZE: brokercomm -# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt # @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" # @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" diff --git a/testing/btest/comm/data.bro b/testing/btest/comm/data.bro index dfbb8fc1d7..a7de41be7a 100644 --- a/testing/btest/comm/data.bro +++ b/testing/btest/comm/data.bro @@ -1,3 +1,5 @@ +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + # @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: btest-diff out diff --git a/testing/btest/comm/master_store.bro b/testing/btest/comm/master_store.bro index a1cc6a8c95..61331bd170 100644 --- a/testing/btest/comm/master_store.bro +++ b/testing/btest/comm/master_store.bro @@ -1,3 +1,5 @@ +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt + # @TEST-EXEC: bro -b %INPUT >out # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test index aeced18eea..2e7aa02d6a 100644 --- a/testing/btest/comm/remote_event.test +++ b/testing/btest/comm/remote_event.test @@ -1,5 +1,5 @@ -# @TEST_SERIALIZE: brokercomm -# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt # @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" # @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test index 2a6174810e..b7dd54abf3 100644 --- a/testing/btest/comm/remote_log.test +++ b/testing/btest/comm/remote_log.test @@ -1,5 +1,5 @@ -# @TEST_SERIALIZE: brokercomm -# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt # @TEST-EXEC: btest-bg-run recv "bro -b ../common.bro ../recv.bro broker_port=$BROKER_PORT >recv.out" # @TEST-EXEC: btest-bg-run send "bro -b ../common.bro ../send.bro broker_port=$BROKER_PORT >send.out" diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test index 0c32e2c1fe..4cf9d9b489 100644 --- a/testing/btest/comm/remote_print.test +++ b/testing/btest/comm/remote_print.test @@ -1,5 +1,5 @@ -# @TEST_SERIALIZE: brokercomm -# @TEST_REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt # @TEST-EXEC: btest-bg-run recv "bro -b ../recv.bro broker_port=$BROKER_PORT >recv.out" # @TEST-EXEC: btest-bg-run send "bro -b ../send.bro broker_port=$BROKER_PORT >send.out" From 07cba950b89253a1a9d2857dfcec7744e87fc5ba Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 10 Feb 2015 16:14:49 -0600 Subject: [PATCH 049/256] Fix gcc compile warnings. --- aux/broker | 2 +- src/EventHandler.cc | 2 +- src/comm/Data.cc | 10 ++++++---- src/comm/Manager.cc | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/aux/broker b/aux/broker index 0af74017e2..9def853ec4 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 0af74017e28d78179a25d60ca80385af444d39f1 +Subproject commit 9def853ec4498e0133735938355832e0a7628ec8 diff --git a/src/EventHandler.cc b/src/EventHandler.cc index d623f43b66..c252951781 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -94,7 +94,7 @@ void EventHandler::Call(val_list* vl, bool no_remote) msg.emplace_back(Name()); bool valid_args = true; - for ( auto i = 0u; i < vl->length(); ++i ) + for ( auto i = 0; i < vl->length(); ++i ) { auto opt_data = comm::val_to_data((*vl)[i]); diff --git a/src/comm/Data.cc b/src/comm/Data.cc index 0ea7666f9e..77b2a496bf 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -192,7 +192,8 @@ struct val_converter { auto expected_index_types = tt->Indices()->Types(); - if ( expected_index_types->length() != indices->size() ) + if ( static_cast(expected_index_types->length()) != + indices->size() ) { Unref(rval); return nullptr; @@ -244,7 +245,8 @@ struct val_converter { auto expected_index_types = tt->Indices()->Types(); - if ( expected_index_types->length() != indices->size() ) + if ( static_cast(expected_index_types->length()) != + indices->size() ) { Unref(rval); return nullptr; @@ -315,7 +317,7 @@ struct val_converter { auto rt = type->AsRecordType(); - if ( a.fields.size() != rt->NumFields() ) + if ( a.fields.size() != static_cast(rt->NumFields()) ) return nullptr; auto rval = new RecordVal(rt); @@ -505,7 +507,7 @@ broker::util::optional comm::val_to_data(Val* v) { auto rec = v->AsRecordVal(); broker::record rval; - auto num_fields = v->Type()->AsRecordType()->NumFields(); + size_t num_fields = v->Type()->AsRecordType()->NumFields(); rval.fields.reserve(num_fields); for ( auto i = 0u; i < num_fields; ++i ) diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 6c09c08f2b..92b2c167dd 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -322,7 +322,7 @@ RecordVal* comm::Manager::MakeEventArgs(val_list* args) rval->Assign(1, arg_vec); Func* func; - for ( auto i = 0u; i < args->length(); ++i ) + for ( auto i = 0; i < args->length(); ++i ) { auto arg_val = (*args)[i]; @@ -742,7 +742,7 @@ void comm::Manager::Process() auto arg_types = ehp->FType()->ArgTypes()->Types(); - if ( arg_types->length() != em.size() - 1 ) + if ( static_cast(arg_types->length()) != em.size() - 1 ) { reporter->Warning("got event message with invalid # of args," " got %zd, expected %d", em.size() - 1, @@ -766,7 +766,7 @@ void comm::Manager::Process() } } - if ( vl->length() == em.size() - 1 ) + if ( static_cast(vl->length()) == em.size() - 1 ) mgr.QueueEvent(ehp, vl); else delete_vals(vl); From 8e4d37d5c1a24ab385286cb6ee8ba976bccbca00 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 11 Feb 2015 11:21:01 -0600 Subject: [PATCH 050/256] Improve comm tests. Same old problems: hard to get termination conditions right. --- .../Baseline/comm.remote_event/send.send.out | 2 - .../Baseline/comm.remote_print/send.send.out | 1 - testing/btest/comm/clone_store.bro | 12 ++---- testing/btest/comm/remote_event.test | 36 +++++++----------- testing/btest/comm/remote_log.test | 8 +++- testing/btest/comm/remote_print.test | 37 +++++++++++++------ 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/testing/btest/Baseline/comm.remote_event/send.send.out b/testing/btest/Baseline/comm.remote_event/send.send.out index 9fbb21f245..0e529e08fc 100644 --- a/testing/btest/Baseline/comm.remote_event/send.send.out +++ b/testing/btest/Baseline/comm.remote_event/send.send.out @@ -9,5 +9,3 @@ got event msg, pong, 3 got auto event msg, ping, 3 got event msg, pong, 4 got auto event msg, ping, 4 -got event msg, pong, 5 -got auto event msg, ping, 5 diff --git a/testing/btest/Baseline/comm.remote_print/send.send.out b/testing/btest/Baseline/comm.remote_print/send.send.out index fc5996194d..777afdc0d2 100644 --- a/testing/btest/Baseline/comm.remote_print/send.send.out +++ b/testing/btest/Baseline/comm.remote_print/send.send.out @@ -4,4 +4,3 @@ got print msg, pong 1 got print msg, pong 2 got print msg, pong 3 got print msg, pong 4 -got print msg, pong 5 diff --git a/testing/btest/comm/clone_store.bro b/testing/btest/comm/clone_store.bro index da05f45210..5a01a497fd 100644 --- a/testing/btest/comm/clone_store.bro +++ b/testing/btest/comm/clone_store.bro @@ -17,11 +17,6 @@ global h: opaque of Store::Handle; global expected_key_count = 4; global key_count = 0; -event done() - { - terminate(); - } - function do_lookup(key: string) { when ( local res = Store::lookup(h, Comm::data(key)) ) @@ -30,7 +25,7 @@ function do_lookup(key: string) print "lookup", key, res; if ( key_count == expected_key_count ) - event done(); + terminate(); } timeout 10sec { print "timeout"; } @@ -57,7 +52,6 @@ event bro_init() Comm::enable(); Comm::listen(broker_port, "127.0.0.1"); Comm::subscribe_to_events("bro/event/ready"); - Comm::auto_event("bro/event/done", done); } @TEST-END-FILE @@ -78,7 +72,8 @@ function dv(d: Comm::Data): Comm::DataVector global ready: event(); -event done() +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) { terminate(); } @@ -112,7 +107,6 @@ event bro_init() Comm::enable(); Comm::connect("127.0.0.1", broker_port, 1secs); Comm::auto_event("bro/event/ready", ready); - Comm::subscribe_to_events("bro/event/done"); } @TEST-END-FILE diff --git a/testing/btest/comm/remote_event.test b/testing/btest/comm/remote_event.test index 2e7aa02d6a..31897bea31 100644 --- a/testing/btest/comm/remote_event.test +++ b/testing/btest/comm/remote_event.test @@ -25,17 +25,22 @@ event bro_init() } global event_count = 0; +global events_to_recv = 6; event event_handler(msg: string, n: count) { - event auto_event_handler(msg, n); - print "got event msg", msg, n; - local args = Comm::event_args(event_handler, "pong", event_count); - Comm::event("bro/event/my_topic", args); ++event_count; + print "got event msg", msg, n; - if ( n == 5 ) + if ( event_count == events_to_recv ) + { terminate(); + return; + } + + event auto_event_handler(msg, n); + local args = Comm::event_args(event_handler, "pong", n); + Comm::event("bro/event/my_topic", args); } @TEST-END-FILE @@ -67,13 +72,10 @@ event Comm::outgoing_connection_established(peer_address: string, ++event_count; } -global done = F; -global done_auto = F; - -function check_terminate() +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) { - if ( done && done_auto ) - terminate(); + terminate(); } event event_handler(msg: string, n: count) @@ -82,23 +84,11 @@ event event_handler(msg: string, n: count) local args = Comm::event_args(event_handler, "ping", event_count); Comm::event("bro/event/hi", args); ++event_count; - - if ( n == 5 ) - { - done = T; - check_terminate(); - } } event auto_event_handler(msg: string, n: count) { print "got auto event msg", msg, n; - - if ( n == 5 ) - { - done_auto = T; - check_terminate(); - } } @TEST-END-FILE diff --git a/testing/btest/comm/remote_log.test b/testing/btest/comm/remote_log.test index b7dd54abf3..42f3f8a594 100644 --- a/testing/btest/comm/remote_log.test +++ b/testing/btest/comm/remote_log.test @@ -70,7 +70,7 @@ global n = 0; event do_write() { if ( n == 6 ) - terminate(); + return; else { Log::write(Test::LOG, [$msg = "ping", $num = n]); @@ -87,4 +87,10 @@ event Comm::outgoing_connection_established(peer_address: string, event do_write(); } +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + @TEST-END-FILE diff --git a/testing/btest/comm/remote_print.test b/testing/btest/comm/remote_print.test index 4cf9d9b489..d77bc92e9c 100644 --- a/testing/btest/comm/remote_print.test +++ b/testing/btest/comm/remote_print.test @@ -20,16 +20,23 @@ event bro_init() Comm::subscribe_to_prints("bro/print/"); } -global n = 0; +global messages_to_recv = 6; +global messages_sent = 0; +global messages_recv = 0; event Comm::print_handler(msg: string) { + ++messages_recv; print "got print msg", msg; - Comm::print("bro/print/my_topic", fmt("pong %d", n)); - ++n; - if ( msg == "ping 5" ) + if ( messages_to_recv == messages_recv ) + { terminate(); + return; + } + + Comm::print("bro/print/my_topic", fmt("pong %d", messages_sent)); + ++messages_sent; } @TEST-END-FILE @@ -46,25 +53,31 @@ event bro_init() Comm::connect("127.0.0.1", broker_port, 1secs); } -global n = 0; +global messages_sent = 0; +global messages_recv = 0; +global peer_disconnected = F; event Comm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) { print "Comm::outgoing_connection_established", peer_address, peer_port; - Comm::print("bro/print/hi", fmt("ping %d", n)); - ++n; + Comm::print("bro/print/hi", fmt("ping %d", messages_sent)); + ++messages_sent; + } + +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); } event Comm::print_handler(msg: string) { + ++messages_recv; print "got print msg", msg; - Comm::print("bro/print/hi", fmt("ping %d", n)); - ++n; - - if ( msg == "pong 5" ) - terminate(); + Comm::print("bro/print/hi", fmt("ping %d", messages_sent)); + ++messages_sent; } @TEST-END-FILE From dab4d6c8bd296ab89ae8c88931c5efd8e80d4424 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 11 Feb 2015 13:21:36 -0600 Subject: [PATCH 051/256] Update broker submodule. --- aux/broker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broker b/aux/broker index 9def853ec4..0767494b9f 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit 9def853ec4498e0133735938355832e0a7628ec8 +Subproject commit 0767494b9f11fabd464cd95c125d5987b6d52858 From 88af106b6b5de8497499e1f6be9d317b6fbb4707 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 11 Feb 2015 13:56:34 -0600 Subject: [PATCH 052/256] Fix use of deprecated gperftools headers. As of gperftools 2.0 (Feb. 2012), they've been renamed in to gperftools/ instead of google/, and as of gperftools 2.2, including the later emits deprecation warnings. --- src/util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util.h b/src/util.h index db77888c16..50c33d5608 100644 --- a/src/util.h +++ b/src/util.h @@ -48,8 +48,8 @@ #endif #ifdef USE_PERFTOOLS_DEBUG -#include -#include +#include +#include extern HeapLeakChecker* heap_checker; #endif From 5a73c11baa783088d9a03460ca7000f940b72121 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 12 Feb 2015 11:40:04 -0600 Subject: [PATCH 053/256] broker integration: fix memory leak, add leak tests Leak tests won't pass w/ libcaf 0.12.2, needs the develop branch (actor-framework@a89485a3098965f104264808994fabfbc3a1bf61). --- src/comm/Data.cc | 9 +- .../clone.clone.out | 5 + .../Baseline/core.leaks.comm.data/bro..stdout | 99 ++++++++ .../core.leaks.comm.master_store/bro..stdout | 14 ++ .../recv.recv.out | 6 + .../send.send.out | 11 + .../core.leaks.comm.remote_log/recv.recv.out | 6 + .../core.leaks.comm.remote_log/recv.test.log | 15 ++ .../core.leaks.comm.remote_log/send.send.out | 1 + .../core.leaks.comm.remote_log/send.test.log | 15 ++ .../recv.recv.out | 6 + .../send.send.out | 6 + testing/btest/core/leaks/comm/clone_store.bro | 113 +++++++++ testing/btest/core/leaks/comm/data.bro | 233 ++++++++++++++++++ .../btest/core/leaks/comm/master_store.bro | 155 ++++++++++++ .../btest/core/leaks/comm/remote_event.test | 96 ++++++++ testing/btest/core/leaks/comm/remote_log.test | 98 ++++++++ .../btest/core/leaks/comm/remote_print.test | 85 +++++++ 18 files changed, 969 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/core.leaks.comm.clone_store/clone.clone.out create mode 100644 testing/btest/Baseline/core.leaks.comm.data/bro..stdout create mode 100644 testing/btest/Baseline/core.leaks.comm.master_store/bro..stdout create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_event/recv.recv.out create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_event/send.send.out create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_log/recv.recv.out create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_log/recv.test.log create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_log/send.send.out create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_log/send.test.log create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_print/recv.recv.out create mode 100644 testing/btest/Baseline/core.leaks.comm.remote_print/send.send.out create mode 100644 testing/btest/core/leaks/comm/clone_store.bro create mode 100644 testing/btest/core/leaks/comm/data.bro create mode 100644 testing/btest/core/leaks/comm/master_store.bro create mode 100644 testing/btest/core/leaks/comm/remote_event.test create mode 100644 testing/btest/core/leaks/comm/remote_log.test create mode 100644 testing/btest/core/leaks/comm/remote_print.test diff --git a/src/comm/Data.cc b/src/comm/Data.cc index 77b2a496bf..46fc8bc8eb 100644 --- a/src/comm/Data.cc +++ b/src/comm/Data.cc @@ -414,7 +414,6 @@ broker::util::optional comm::val_to_data(Val* v) auto is_set = v->Type()->IsSet(); auto table = v->AsTable(); auto table_val = v->AsTableVal(); - auto c = table->InitForIteration(); broker::data rval; if ( is_set ) @@ -437,10 +436,12 @@ broker::util::optional comm::val_to_data(Val* v) ListVal* lv; }; - for ( auto i = 0; i < table->Length(); ++i ) + HashKey* k; + TableEntryVal* entry; + auto c = table->InitForIteration(); + + while ( (entry = table->NextEntry(k, c)) ) { - HashKey* k; - auto entry = table->NextEntry(k, c); auto vl = table_val->RecoverIndex(k); iter_guard ig(k, vl); diff --git a/testing/btest/Baseline/core.leaks.comm.clone_store/clone.clone.out b/testing/btest/Baseline/core.leaks.comm.clone_store/clone.clone.out new file mode 100644 index 0000000000..8a7c89a19b --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.clone_store/clone.clone.out @@ -0,0 +1,5 @@ +clone keys, [status=Store::SUCCESS, result=[d=broker::data{[one, two, myset, myvec]}]] +lookup, one, [status=Store::SUCCESS, result=[d=broker::data{111}]] +lookup, two, [status=Store::SUCCESS, result=[d=broker::data{222}]] +lookup, myset, [status=Store::SUCCESS, result=[d=broker::data{{a, c, d}}]] +lookup, myvec, [status=Store::SUCCESS, result=[d=broker::data{[delta, alpha, beta, gamma, omega]}]] diff --git a/testing/btest/Baseline/core.leaks.comm.data/bro..stdout b/testing/btest/Baseline/core.leaks.comm.data/bro..stdout new file mode 100644 index 0000000000..eea78d39a2 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.data/bro..stdout @@ -0,0 +1,99 @@ +Comm::BOOL +Comm::INT +Comm::COUNT +Comm::DOUBLE +Comm::STRING +Comm::ADDR +Comm::SUBNET +Comm::PORT +Comm::TIME +Comm::INTERVAL +Comm::ENUM +Comm::SET +Comm::TABLE +Comm::VECTOR +Comm::RECORD +*************************** +T +F +1 +0 +-1 +1 +0 +1.1 +-11.1 +hello +1.2.3.4 +192.168.0.0/16 +22/tcp +42.0 +180.0 +Comm::BOOL +*************************** +{ +two, +one, +three +} +0 +T +1 +T +F +T +2 +T +1 +F +{ +bye +} +0 +*************************** +{ +[two] = 2, +[one] = 1, +[three] = 3 +} +0 +[d=] +1 +T +42 +F +[d=] +2 +[d=broker::data{7}] +2 +37 +[d=broker::data{42}] +1 +*************************** +[zero, one, two] +0 +T +T +T +T +[hi, salutations, hello, greetings] +4 +[d=broker::data{hello}] +[d=broker::data{bah}] +[d=broker::data{hi}] +[hi, salutations, bah, greetings] +[d=broker::data{bah}] +[hi, salutations, greetings] +3 +*************************** +[a=, b=bee, c=1] +[a=test, b=bee, c=1] +[a=test, b=testagain, c=1] +3 +T +T +T +[d=broker::data{hi}] +[d=broker::data{hello}] +[d=broker::data{37}] +3 diff --git a/testing/btest/Baseline/core.leaks.comm.master_store/bro..stdout b/testing/btest/Baseline/core.leaks.comm.master_store/bro..stdout new file mode 100644 index 0000000000..defdc9a3e1 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.master_store/bro..stdout @@ -0,0 +1,14 @@ +lookup(two): [status=Store::SUCCESS, result=[d=broker::data{222}]] +lookup(four): [status=Store::SUCCESS, result=[d=]] +lookup(myset): [status=Store::SUCCESS, result=[d=broker::data{{a, c, d}}]] +lookup(one): [status=Store::SUCCESS, result=[d=broker::data{111}]] +lookup(myvec): [status=Store::SUCCESS, result=[d=broker::data{[delta, alpha, beta, gamma, omega]}]] +exists(one): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(two): [status=Store::SUCCESS, result=[d=broker::data{0}]] +exists(myset): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(four): [status=Store::SUCCESS, result=[d=broker::data{0}]] +pop_right(myvec): [status=Store::SUCCESS, result=[d=broker::data{omega}]] +pop_left(myvec): [status=Store::SUCCESS, result=[d=broker::data{delta}]] +keys: [status=Store::SUCCESS, result=[d=broker::data{[myvec, myset, one]}]] +size: [status=Store::SUCCESS, result=[d=broker::data{3}]] +size (after clear): [status=Store::SUCCESS, result=[d=broker::data{0}]] diff --git a/testing/btest/Baseline/core.leaks.comm.remote_event/recv.recv.out b/testing/btest/Baseline/core.leaks.comm.remote_event/recv.recv.out new file mode 100644 index 0000000000..7dab0284ea --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_event/recv.recv.out @@ -0,0 +1,6 @@ +got event msg, ping, 0 +got event msg, ping, 1 +got event msg, ping, 2 +got event msg, ping, 3 +got event msg, ping, 4 +got event msg, ping, 5 diff --git a/testing/btest/Baseline/core.leaks.comm.remote_event/send.send.out b/testing/btest/Baseline/core.leaks.comm.remote_event/send.send.out new file mode 100644 index 0000000000..0e529e08fc --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_event/send.send.out @@ -0,0 +1,11 @@ +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp +got event msg, pong, 0 +got auto event msg, ping, 0 +got event msg, pong, 1 +got auto event msg, ping, 1 +got event msg, pong, 2 +got auto event msg, ping, 2 +got event msg, pong, 3 +got auto event msg, ping, 3 +got event msg, pong, 4 +got auto event msg, ping, 4 diff --git a/testing/btest/Baseline/core.leaks.comm.remote_log/recv.recv.out b/testing/btest/Baseline/core.leaks.comm.remote_log/recv.recv.out new file mode 100644 index 0000000000..3e0957442d --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_log/recv.recv.out @@ -0,0 +1,6 @@ +wrote log, [msg=ping, num=0] +wrote log, [msg=ping, num=1] +wrote log, [msg=ping, num=2] +wrote log, [msg=ping, num=3] +wrote log, [msg=ping, num=4] +wrote log, [msg=ping, num=5] diff --git a/testing/btest/Baseline/core.leaks.comm.remote_log/recv.test.log b/testing/btest/Baseline/core.leaks.comm.remote_log/recv.test.log new file mode 100644 index 0000000000..4fe7790779 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_log/recv.test.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path test +#open 2015-02-12-17-33-13 +#fields msg num +#types string count +ping 0 +ping 1 +ping 2 +ping 3 +ping 4 +ping 5 +#close 2015-02-12-17-33-14 diff --git a/testing/btest/Baseline/core.leaks.comm.remote_log/send.send.out b/testing/btest/Baseline/core.leaks.comm.remote_log/send.send.out new file mode 100644 index 0000000000..e2415290d6 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_log/send.send.out @@ -0,0 +1 @@ +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp diff --git a/testing/btest/Baseline/core.leaks.comm.remote_log/send.test.log b/testing/btest/Baseline/core.leaks.comm.remote_log/send.test.log new file mode 100644 index 0000000000..884517b252 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_log/send.test.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path test +#open 2015-02-12-17-33-13 +#fields msg num +#types string count +ping 0 +ping 1 +ping 2 +ping 3 +ping 4 +ping 5 +#close 2015-02-12-17-33-15 diff --git a/testing/btest/Baseline/core.leaks.comm.remote_print/recv.recv.out b/testing/btest/Baseline/core.leaks.comm.remote_print/recv.recv.out new file mode 100644 index 0000000000..6e5a37abbf --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_print/recv.recv.out @@ -0,0 +1,6 @@ +got print msg, ping 0 +got print msg, ping 1 +got print msg, ping 2 +got print msg, ping 3 +got print msg, ping 4 +got print msg, ping 5 diff --git a/testing/btest/Baseline/core.leaks.comm.remote_print/send.send.out b/testing/btest/Baseline/core.leaks.comm.remote_print/send.send.out new file mode 100644 index 0000000000..777afdc0d2 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.comm.remote_print/send.send.out @@ -0,0 +1,6 @@ +Comm::outgoing_connection_established, 127.0.0.1, 9999/tcp +got print msg, pong 0 +got print msg, pong 1 +got print msg, pong 2 +got print msg, pong 3 +got print msg, pong 4 diff --git a/testing/btest/core/leaks/comm/clone_store.bro b/testing/btest/core/leaks/comm/clone_store.bro new file mode 100644 index 0000000000..2a75bfa62f --- /dev/null +++ b/testing/btest/core/leaks/comm/clone_store.bro @@ -0,0 +1,113 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leak + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run clone "bro -m -b ../clone.bro broker_port=$BROKER_PORT >clone.out" +# @TEST-EXEC: btest-bg-run master "bro -b ../master.bro broker_port=$BROKER_PORT >master.out" + +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff clone/clone.out + +@TEST-START-FILE clone.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; +global expected_key_count = 4; +global key_count = 0; + +function do_lookup(key: string) + { + when ( local res = Store::lookup(h, Comm::data(key)) ) + { + ++key_count; + print "lookup", key, res; + + if ( key_count == expected_key_count ) + terminate(); + } + timeout 10sec + { print "timeout"; } + } + +event ready() + { + h = Store::create_clone("mystore"); + + when ( local res = Store::keys(h) ) + { + print "clone keys", res; + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 0))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 1))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 2))); + do_lookup(Comm::refine_to_string(Comm::vector_lookup(res$result, 3))); + } + timeout 10sec + { print "timeout"; } + } + +event bro_init() + { + Comm::enable(); + Comm::listen(broker_port, "127.0.0.1"); + Comm::subscribe_to_events("bro/event/ready"); + } + +@TEST-END-FILE + +@TEST-START-FILE master.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; + +function dv(d: Comm::Data): Comm::DataVector + { + local rval: Comm::DataVector; + rval[0] = d; + return rval; + } + +global ready: event(); + +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + local myset: set[string] = {"a", "b", "c"}; + local myvec: vector of string = {"alpha", "beta", "gamma"}; + Store::insert(h, Comm::data("one"), Comm::data(110)); + Store::insert(h, Comm::data("two"), Comm::data(223)); + Store::insert(h, Comm::data("myset"), Comm::data(myset)); + Store::insert(h, Comm::data("myvec"), Comm::data(myvec)); + Store::increment(h, Comm::data("one")); + Store::decrement(h, Comm::data("two")); + Store::add_to_set(h, Comm::data("myset"), Comm::data("d")); + Store::remove_from_set(h, Comm::data("myset"), Comm::data("b")); + Store::push_left(h, Comm::data("myvec"), dv(Comm::data("delta"))); + Store::push_right(h, Comm::data("myvec"), dv(Comm::data("omega"))); + + when ( local res = Store::size(h) ) + { event ready(); } + timeout 10sec + { print "timeout"; } + } + +event bro_init() + { + Comm::enable(); + h = Store::create_master("mystore"); + Comm::connect("127.0.0.1", broker_port, 1secs); + Comm::auto_event("bro/event/ready", ready); + } + +@TEST-END-FILE diff --git a/testing/btest/core/leaks/comm/data.bro b/testing/btest/core/leaks/comm/data.bro new file mode 100644 index 0000000000..bf614a2092 --- /dev/null +++ b/testing/btest/core/leaks/comm/data.bro @@ -0,0 +1,233 @@ +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leaks + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/http/get.trace %INPUT +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: btest-diff bro/.stdout + +type bro_set: set[string]; +type bro_table: table[string] of count; +type bro_vector: vector of string; + +type bro_record : record { + a: string &optional; + b: string &default = "bee"; + c: count; +}; + +function comm_record_to_bro_record_recurse(it: opaque of Comm::RecordIterator, + rval: bro_record, + idx: count): bro_record + { + if ( Comm::record_iterator_last(it) ) + return rval; + + local field_value = Comm::record_iterator_value(it); + + if ( field_value?$d ) + switch ( idx ) { + case 0: + rval$a = Comm::refine_to_string(field_value); + break; + case 1: + rval$b = Comm::refine_to_string(field_value); + break; + case 2: + rval$c = Comm::refine_to_count(field_value); + break; + }; + + ++idx; + Comm::record_iterator_next(it); + return comm_record_to_bro_record_recurse(it, rval, idx); + } + +function comm_record_to_bro_record(d: Comm::Data): bro_record + { + return comm_record_to_bro_record_recurse(Comm::record_iterator(d), + bro_record($c = 0), 0); + } + +function +comm_set_to_bro_set_recurse(it: opaque of Comm::SetIterator, + rval: bro_set): bro_set + { + if ( Comm::set_iterator_last(it) ) + return rval; + + add rval[Comm::refine_to_string(Comm::set_iterator_value(it))]; + Comm::set_iterator_next(it); + return comm_set_to_bro_set_recurse(it, rval); + } + + +function comm_set_to_bro_set(d: Comm::Data): bro_set + { + return comm_set_to_bro_set_recurse(Comm::set_iterator(d), bro_set()); + } + +function +comm_table_to_bro_table_recurse(it: opaque of Comm::TableIterator, + rval: bro_table): bro_table + { + if ( Comm::table_iterator_last(it) ) + return rval; + + local item = Comm::table_iterator_value(it); + rval[Comm::refine_to_string(item$key)] = Comm::refine_to_count(item$val); + Comm::table_iterator_next(it); + return comm_table_to_bro_table_recurse(it, rval); + } + +function comm_table_to_bro_table(d: Comm::Data): bro_table + { + return comm_table_to_bro_table_recurse(Comm::table_iterator(d), + bro_table()); + } + +function comm_vector_to_bro_vector_recurse(it: opaque of Comm::VectorIterator, + rval: bro_vector): bro_vector + { + if ( Comm::vector_iterator_last(it) ) + return rval; + + rval[|rval|] = Comm::refine_to_string(Comm::vector_iterator_value(it)); + Comm::vector_iterator_next(it); + return comm_vector_to_bro_vector_recurse(it, rval); + } + +function comm_vector_to_bro_vector(d: Comm::Data): bro_vector + { + return comm_vector_to_bro_vector_recurse(Comm::vector_iterator(d), + bro_vector()); + } + +event bro_init() + { +Comm::enable(); + } + +global did_it = F; + +event new_connection(c: connection) + { +if ( did_it ) return; +did_it = T; +print Comm::data_type(Comm::data(T)); +print Comm::data_type(Comm::data(+1)); +print Comm::data_type(Comm::data(1)); +print Comm::data_type(Comm::data(1.1)); +print Comm::data_type(Comm::data("1 (how creative)")); +print Comm::data_type(Comm::data(1.1.1.1)); +print Comm::data_type(Comm::data(1.1.1.1/1)); +print Comm::data_type(Comm::data(1/udp)); +print Comm::data_type(Comm::data(double_to_time(1))); +print Comm::data_type(Comm::data(1sec)); +print Comm::data_type(Comm::data(Comm::BOOL)); +local s: bro_set = bro_set("one", "two", "three"); +local t: bro_table = bro_table(["one"] = 1, ["two"] = 2, ["three"] = 3); +local v: bro_vector = bro_vector("zero", "one", "two"); +local r: bro_record = bro_record($c = 1); +print Comm::data_type(Comm::data(s)); +print Comm::data_type(Comm::data(t)); +print Comm::data_type(Comm::data(v)); +print Comm::data_type(Comm::data(r)); + +print "***************************"; + +print Comm::refine_to_bool(Comm::data(T)); +print Comm::refine_to_bool(Comm::data(F)); +print Comm::refine_to_int(Comm::data(+1)); +print Comm::refine_to_int(Comm::data(+0)); +print Comm::refine_to_int(Comm::data(-1)); +print Comm::refine_to_count(Comm::data(1)); +print Comm::refine_to_count(Comm::data(0)); +print Comm::refine_to_double(Comm::data(1.1)); +print Comm::refine_to_double(Comm::data(-11.1)); +print Comm::refine_to_string(Comm::data("hello")); +print Comm::refine_to_addr(Comm::data(1.2.3.4)); +print Comm::refine_to_subnet(Comm::data(192.168.1.1/16)); +print Comm::refine_to_port(Comm::data(22/tcp)); +print Comm::refine_to_time(Comm::data(double_to_time(42))); +print Comm::refine_to_interval(Comm::data(3min)); +print Comm::refine_to_enum_name(Comm::data(Comm::BOOL)); + +print "***************************"; + +local cs = Comm::data(s); +print comm_set_to_bro_set(cs); +cs = Comm::set_create(); +print Comm::set_size(cs); +print Comm::set_insert(cs, Comm::data("hi")); +print Comm::set_size(cs); +print Comm::set_contains(cs, Comm::data("hi")); +print Comm::set_contains(cs, Comm::data("bye")); +print Comm::set_insert(cs, Comm::data("bye")); +print Comm::set_size(cs); +print Comm::set_remove(cs, Comm::data("hi")); +print Comm::set_size(cs); +print Comm::set_remove(cs, Comm::data("hi")); +print comm_set_to_bro_set(cs); +Comm::set_clear(cs); +print Comm::set_size(cs); + +print "***************************"; + +local ct = Comm::data(t); +print comm_table_to_bro_table(ct); +ct = Comm::table_create(); +print Comm::table_size(ct); +print Comm::table_insert(ct, Comm::data("hi"), Comm::data(42)); +print Comm::table_size(ct); +print Comm::table_contains(ct, Comm::data("hi")); +print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("hi"))); +print Comm::table_contains(ct, Comm::data("bye")); +print Comm::table_insert(ct, Comm::data("bye"), Comm::data(7)); +print Comm::table_size(ct); +print Comm::table_insert(ct, Comm::data("bye"), Comm::data(37)); +print Comm::table_size(ct); +print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("bye"))); +print Comm::table_remove(ct, Comm::data("hi")); +print Comm::table_size(ct); + +print "***************************"; + +local cv = Comm::data(v); +print comm_vector_to_bro_vector(cv); +cv = Comm::vector_create(); +print Comm::vector_size(cv); +print Comm::vector_insert(cv, Comm::data("hi"), 0); +print Comm::vector_insert(cv, Comm::data("hello"), 1); +print Comm::vector_insert(cv, Comm::data("greetings"), 2); +print Comm::vector_insert(cv, Comm::data("salutations"), 1); +print comm_vector_to_bro_vector(cv); +print Comm::vector_size(cv); +print Comm::vector_replace(cv, Comm::data("bah"), 2); +print Comm::vector_lookup(cv, 2); +print Comm::vector_lookup(cv, 0); +print comm_vector_to_bro_vector(cv); +print Comm::vector_remove(cv, 2); +print comm_vector_to_bro_vector(cv); +print Comm::vector_size(cv); + +print "***************************"; + +local cr = Comm::data(r); +print comm_record_to_bro_record(cr); +r$a = "test"; +cr = Comm::data(r); +print comm_record_to_bro_record(cr); +r$b = "testagain"; +cr = Comm::data(r); +print comm_record_to_bro_record(cr); +cr = Comm::record_create(3); +print Comm::record_size(cr); +print Comm::record_assign(cr, Comm::data("hi"), 0); +print Comm::record_assign(cr, Comm::data("hello"), 1); +print Comm::record_assign(cr, Comm::data(37), 2); +print Comm::record_lookup(cr, 0); +print Comm::record_lookup(cr, 1); +print Comm::record_lookup(cr, 2); +print Comm::record_size(cr); +} diff --git a/testing/btest/core/leaks/comm/master_store.bro b/testing/btest/core/leaks/comm/master_store.bro new file mode 100644 index 0000000000..a5c1063e6f --- /dev/null +++ b/testing/btest/core/leaks/comm/master_store.bro @@ -0,0 +1,155 @@ +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leaks + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/http/get.trace %INPUT +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff bro/.stdout + +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; +global lookup_count = 0; +const lookup_expect_count = 5; +global exists_count = 0; +const exists_expect_count = 4; +global pop_count = 0; +const pop_expect_count = 2; + +global test_size: event(where: string &default = ""); + +event test_clear() + { + Store::clear(h); + event test_size("after clear"); + } + +event test_size(where: string) + { + when ( local res = Store::size(h) ) + { + if ( where == "" ) + { + print fmt("size: %s", res); + event test_clear(); + } + else + { + print fmt("size (%s): %s", where, res); + terminate(); + } + } + timeout 10sec + { print "timeout"; } + } + +event test_keys() + { + when ( local res = Store::keys(h) ) + { + print fmt("keys: %s", res); + event test_size(); + } + timeout 10sec + { print "timeout"; } + } + +event test_pop(key: string) + { + when ( local lres = Store::pop_left(h, Comm::data(key)) ) + { + print fmt("pop_left(%s): %s", key, lres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + + when ( local rres = Store::pop_right(h, Comm::data(key)) ) + { + print fmt("pop_right(%s): %s", key, rres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + } + +function do_exists(key: string) + { + when ( local res = Store::exists(h, Comm::data(key)) ) + { + print fmt("exists(%s): %s", key, res); + ++exists_count; + + if ( exists_count == exists_expect_count ) + event test_pop("myvec"); + } + timeout 10sec + { print "timeout"; } + } + +event test_erase() + { + Store::erase(h, Comm::data("two")); + do_exists("one"); + do_exists("two"); + do_exists("myset"); + do_exists("four"); + } + +function do_lookup(key: string) + { + when ( local res = Store::lookup(h, Comm::data(key)) ) + { + print fmt("lookup(%s): %s", key, res); + ++lookup_count; + + if ( lookup_count == lookup_expect_count ) + event test_erase(); + } + timeout 10sec + { print "timeout"; } + } + +function dv(d: Comm::Data): Comm::DataVector + { + local rval: Comm::DataVector; + rval[0] = d; + return rval; + } + +global did_it = F; + +event bro_init() + { + Comm::enable(); + h = Store::create_master("master"); + } + +event new_connection(c: connection) + { + if ( did_it ) return; + did_it = T; + local myset: set[string] = {"a", "b", "c"}; + local myvec: vector of string = {"alpha", "beta", "gamma"}; + Store::insert(h, Comm::data("one"), Comm::data(110)); + Store::insert(h, Comm::data("two"), Comm::data(223)); + Store::insert(h, Comm::data("myset"), Comm::data(myset)); + Store::insert(h, Comm::data("myvec"), Comm::data(myvec)); + Store::increment(h, Comm::data("one")); + Store::decrement(h, Comm::data("two")); + Store::add_to_set(h, Comm::data("myset"), Comm::data("d")); + Store::remove_from_set(h, Comm::data("myset"), Comm::data("b")); + Store::push_left(h, Comm::data("myvec"), dv(Comm::data("delta"))); + Store::push_right(h, Comm::data("myvec"), dv(Comm::data("omega"))); + do_lookup("one"); + do_lookup("two"); + do_lookup("myset"); + do_lookup("four"); + do_lookup("myvec"); + } diff --git a/testing/btest/core/leaks/comm/remote_event.test b/testing/btest/core/leaks/comm/remote_event.test new file mode 100644 index 0000000000..a329b527db --- /dev/null +++ b/testing/btest/core/leaks/comm/remote_event.test @@ -0,0 +1,96 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leak + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "bro -m -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "bro -m -b ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE recv.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global event_handler: event(msg: string, c: count); +global auto_event_handler: event(msg: string, c: count); + +event bro_init() + { + Comm::enable(); + Comm::listen(broker_port, "127.0.0.1"); + Comm::subscribe_to_events("bro/event/"); + Comm::auto_event("bro/event/my_topic", auto_event_handler); + } + +global event_count = 0; +global events_to_recv = 6; + +event event_handler(msg: string, n: count) + { + ++event_count; + print "got event msg", msg, n; + + if ( event_count == events_to_recv ) + { + terminate(); + return; + } + + event auto_event_handler(msg, n); + local args = Comm::event_args(event_handler, "pong", n); + Comm::event("bro/event/my_topic", args); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global event_handler: event(msg: string, c: count); +global auto_event_handler: event(msg: string, c: count); + +event bro_init() + { + Comm::enable(); + Comm::subscribe_to_events("bro/event/my_topic"); + Comm::connect("127.0.0.1", broker_port, 1secs); + } + +global event_count = 0; + +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::outgoing_connection_established", peer_address, peer_port; + local args = Comm::event_args(event_handler, "ping", event_count); + Comm::event("bro/event/hi", args); + ++event_count; + } + +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event event_handler(msg: string, n: count) + { + print "got event msg", msg, n; + local args = Comm::event_args(event_handler, "ping", event_count); + Comm::event("bro/event/hi", args); + ++event_count; + } + +event auto_event_handler(msg: string, n: count) + { + print "got auto event msg", msg, n; + } + +@TEST-END-FILE diff --git a/testing/btest/core/leaks/comm/remote_log.test b/testing/btest/core/leaks/comm/remote_log.test new file mode 100644 index 0000000000..6f20bf8cd4 --- /dev/null +++ b/testing/btest/core/leaks/comm/remote_log.test @@ -0,0 +1,98 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leak + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "bro -m -b ../common.bro ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "bro -m -b ../common.bro ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff recv/test.log +# @TEST-EXEC: btest-diff send/send.out +# @TEST-EXEC: btest-diff send/test.log + +@TEST-START-FILE common.bro + +module Test; + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + msg: string &log; + num: count &log; + }; + + global log_test: event(rec: Test::Info); +} + +event bro_init() &priority=5 + { + Comm::enable(); + Log::create_stream(Test::LOG, [$columns=Test::Info, $ev=log_test]); + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::listen(broker_port, "127.0.0.1"); + Comm::subscribe_to_logs("bro/log/"); + } + +event Test::log_test(rec: Test::Info) + { + print "wrote log", rec; + + if ( rec$num == 5 ) + terminate(); + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::enable_remote_logs(Test::LOG); + Comm::connect("127.0.0.1", broker_port, 1secs); + } + +global n = 0; + +event do_write() + { + if ( n == 6 ) + return; + else + { + Log::write(Test::LOG, [$msg = "ping", $num = n]); + ++n; + event do_write(); + } + } + +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::outgoing_connection_established", peer_address, peer_port; + event do_write(); + } + +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +@TEST-END-FILE diff --git a/testing/btest/core/leaks/comm/remote_print.test b/testing/btest/core/leaks/comm/remote_print.test new file mode 100644 index 0000000000..43fe50b632 --- /dev/null +++ b/testing/btest/core/leaks/comm/remote_print.test @@ -0,0 +1,85 @@ +# @TEST-SERIALIZE: brokercomm +# @TEST-REQUIRES: grep -q ENABLE_BROKER $BUILD/CMakeCache.txt +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# @TEST-GROUP: leak + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "bro -m -b ../recv.bro broker_port=$BROKER_PORT >recv.out" +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "bro -m -b ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 45 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE recv.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::enable(); + Comm::listen(broker_port, "127.0.0.1"); + Comm::subscribe_to_prints("bro/print/"); + } + +global messages_to_recv = 6; +global messages_sent = 0; +global messages_recv = 0; + +event Comm::print_handler(msg: string) + { + ++messages_recv; + print "got print msg", msg; + + if ( messages_to_recv == messages_recv ) + { + terminate(); + return; + } + + Comm::print("bro/print/my_topic", fmt("pong %d", messages_sent)); + ++messages_sent; + } + +@TEST-END-FILE + +@TEST-START-FILE send.bro + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + Comm::enable(); + Comm::subscribe_to_prints("bro/print/my_topic"); + Comm::connect("127.0.0.1", broker_port, 1secs); + } + +global messages_sent = 0; +global messages_recv = 0; +global peer_disconnected = F; + +event Comm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "Comm::outgoing_connection_established", peer_address, peer_port; + Comm::print("bro/print/hi", fmt("ping %d", messages_sent)); + ++messages_sent; + } + +event Comm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event Comm::print_handler(msg: string) + { + ++messages_recv; + print "got print msg", msg; + Comm::print("bro/print/hi", fmt("ping %d", messages_sent)); + ++messages_sent; + } + +@TEST-END-FILE From 961fd06cad004f1f167ebbf65f241349a2ea9b63 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 12 Feb 2015 17:06:38 -0600 Subject: [PATCH 054/256] Refactor SOCKS5 user/pass authentication support. - Rename event "socks_login_userpass" to "socks_login_userpass_request" - Rename event "socks_login_reply" to "socks_login_userpass_reply" - Split unsupported authN weird into 2 types: method vs. version Addresses BIT-1011 --- scripts/base/protocols/socks/main.bro | 4 +- src/analyzer/protocol/socks/events.bif | 6 +-- .../protocol/socks/socks-analyzer.pac | 40 ++++++++------ .../protocol/socks/socks-protocol.pac | 53 +++++++++++++++++-- src/analyzer/protocol/socks/socks.pac | 2 +- testing/btest/Baseline/plugins.writer/output | 4 +- 6 files changed, 82 insertions(+), 27 deletions(-) diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index f60c3ce41c..e052962888 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -94,7 +94,7 @@ event socks_reply(c: connection, version: count, reply: count, sa: SOCKS::Addres Log::write(SOCKS::LOG, c$socks); } -event socks_login_userpass(c: connection, user: string, password: string) &priority=5 +event socks_login_userpass_request(c: connection, user: string, password: string) &priority=5 { # Authentication only possible with the version 5. set_session(c, 5); @@ -103,7 +103,7 @@ event socks_login_userpass(c: connection, user: string, password: string) &prior c$socks$password = password; } -event socks_login_reply(c: connection, code: count) &priority=5 +event socks_login_userpass_reply(c: connection, code: count) &priority=5 { # Authentication only possible with the version 5. set_session(c, 5); diff --git a/src/analyzer/protocol/socks/events.bif b/src/analyzer/protocol/socks/events.bif index ece69140a1..224f570817 100644 --- a/src/analyzer/protocol/socks/events.bif +++ b/src/analyzer/protocol/socks/events.bif @@ -34,12 +34,12 @@ event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Addre ## user: The given username. ## ## password: The given password. -event socks_login_userpass%(c: connection, user: string, password: string%); +event socks_login_userpass_request%(c: connection, user: string, password: string%); -## Generated when a SOCKS server replies to a login attempt. +## Generated when a SOCKS server replies to a username/password login attempt. ## ## c: The parent connection of the proxy. ## ## code: The response code for the attempted login. -event socks_login_reply%(c: connection, code: count%); +event socks_login_userpass_reply%(c: connection, code: count%); diff --git a/src/analyzer/protocol/socks/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac index 7d634e2f46..b8c4165a54 100644 --- a/src/analyzer/protocol/socks/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -148,28 +148,34 @@ refine connection SOCKS_Conn += { return true; %} - function socks5_auth_request_userpass(request: SOCKS5_Auth_Request_UserPass): bool + function socks5_auth_request_userpass(request: SOCKS5_Auth_Request_UserPass_v1): bool %{ StringVal* user = new StringVal(${request.username}.length(), (const char*) ${request.username}.begin()); StringVal* pass = new StringVal(${request.password}.length(), (const char*) ${request.password}.begin()); - BifEvent::generate_socks_login_userpass(bro_analyzer(), - bro_analyzer()->Conn(), - user, pass); + BifEvent::generate_socks_login_userpass_request(bro_analyzer(), + bro_analyzer()->Conn(), + user, pass); return true; %} - function socks5_unsupported_authentication(auth_method: uint8): bool + function socks5_unsupported_authentication_method(auth_method: uint8): bool %{ - reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_%d", auth_method)); + reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_method_%d", auth_method)); + return true; + %} + + function socks5_unsupported_authentication_version(auth_method: uint8, version: uint8): bool + %{ + reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_%d_%d", auth_method, version)); return true; %} - function socks5_auth_reply(reply: SOCKS5_Auth_Reply): bool + function socks5_auth_reply_userpass(reply: SOCKS5_Auth_Reply_UserPass_v1): bool %{ - BifEvent::generate_socks_login_reply(bro_analyzer(), - bro_analyzer()->Conn(), - ${reply.code}); + BifEvent::generate_socks_login_userpass_reply(bro_analyzer(), + bro_analyzer()->Conn(), + ${reply.code}); return true; %} @@ -205,14 +211,18 @@ refine typeattr SOCKS5_Reply += &let { refine typeattr SOCKS5_Auth_Negotiation_Reply += &let { }; -refine typeattr SOCKS5_Auth_Request_UserPass += &let { +refine typeattr SOCKS5_Auth_Request_UserPass_v1 += &let { proc: bool = $context.connection.socks5_auth_request_userpass(this); }; -refine typeattr SOCKS5_Auth_Reply += &let { - proc: bool = $context.connection.socks5_auth_reply(this); +refine typeattr SOCKS5_Auth_Reply_UserPass_v1 += &let { + proc: bool = $context.connection.socks5_auth_reply_userpass(this); }; -refine typeattr SOCKS5_Unsupported_Authentication += &let { - proc: bool = $context.connection.socks5_unsupported_authentication($context.connection.v5_auth_method()); +refine typeattr SOCKS5_Unsupported_Authentication_Method += &let { + proc: bool = $context.connection.socks5_unsupported_authentication_method($context.connection.v5_auth_method()); +}; + +refine typeattr SOCKS5_Unsupported_Authentication_Version += &let { + proc: bool = $context.connection.socks5_unsupported_authentication_version($context.connection.v5_auth_method(), version); }; diff --git a/src/analyzer/protocol/socks/socks-protocol.pac b/src/analyzer/protocol/socks/socks-protocol.pac index 4e48ea0672..d9c31d2377 100644 --- a/src/analyzer/protocol/socks/socks-protocol.pac +++ b/src/analyzer/protocol/socks/socks-protocol.pac @@ -1,8 +1,12 @@ +type SOCKS_Message(is_orig: bool) = case $context.connection.v5_in_auth_sub_negotiation() of { + true -> auth: SOCKS5_Auth_Message(is_orig); + false -> msg: SOCKS_Version(is_orig); +}; + type SOCKS_Version(is_orig: bool) = record { version: uint8; msg: case version of { - 1 -> socks5_auth_msg: SOCKS5_Auth_Message(is_orig); 4 -> socks4_msg: SOCKS4_Message(is_orig); 5 -> socks5_msg: SOCKS5_Message(is_orig); default -> socks_msg_fail: SOCKS_Version_Error(version); @@ -33,6 +37,7 @@ type SOCKS5_Auth_Negotiation_Request = record { type SOCKS5_Auth_Negotiation_Reply = record { selected_auth_method: uint8; } &let { + in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(selected_auth_method == 0 || selected_auth_method == 0xff ? false : true); past_auth = $context.connection.set_v5_past_authentication(); set_auth = $context.connection.set_v5_auth_method(selected_auth_method); }; @@ -44,21 +49,48 @@ type SOCKS5_Auth_Message(is_orig: bool) = case is_orig of { type SOCKS5_Auth_Request = case $context.connection.v5_auth_method() of { 0x02 -> userpass : SOCKS5_Auth_Request_UserPass; - default -> unsupported : SOCKS5_Unsupported_Authentication; + default -> unsupported : SOCKS5_Unsupported_Authentication_Method; }; -type SOCKS5_Unsupported_Authentication = record { +type SOCKS5_Unsupported_Authentication_Method = record { + crap: bytestring &restofdata; +}; + +type SOCKS5_Unsupported_Authentication_Version(version: uint8) = record { crap: bytestring &restofdata; }; type SOCKS5_Auth_Request_UserPass = record { + version: uint8; + msg: case version of { + 1 -> v1: SOCKS5_Auth_Request_UserPass_v1; + default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version); + }; +}; + +type SOCKS5_Auth_Request_UserPass_v1 = record { ulen : uint8; username : bytestring &length=ulen; plen : uint8; password : bytestring &length=plen; }; -type SOCKS5_Auth_Reply = record { +type SOCKS5_Auth_Reply = case $context.connection.v5_auth_method() of { + 0x02 -> userpass : SOCKS5_Auth_Reply_UserPass; + default -> unsupported : SOCKS5_Unsupported_Authentication_Method; +} &let { + in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(false); +}; + +type SOCKS5_Auth_Reply_UserPass = record { + version: uint8; + msg: case version of { + 1 -> v1: SOCKS5_Auth_Reply_UserPass_v1; + default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version); + }; +}; + +type SOCKS5_Auth_Reply_UserPass_v1 = record { code : uint8; }; @@ -126,15 +158,28 @@ type SOCKS4_Reply = record { refine connection SOCKS_Conn += { %member{ + bool v5_in_auth_sub_negotiation_; bool v5_authenticated_; uint8 selected_auth_method_; %} %init{ + v5_in_auth_sub_negotiation_ = false; v5_authenticated_ = false; selected_auth_method_ = 255; %} + function v5_in_auth_sub_negotiation(): bool + %{ + return v5_in_auth_sub_negotiation_; + %} + + function set_v5_in_auth_sub_negotiation(b: bool): bool + %{ + v5_in_auth_sub_negotiation_ = b; + return true; + %} + function v5_past_authentication(): bool %{ return v5_authenticated_; diff --git a/src/analyzer/protocol/socks/socks.pac b/src/analyzer/protocol/socks/socks.pac index a9c4099508..9aed2820af 100644 --- a/src/analyzer/protocol/socks/socks.pac +++ b/src/analyzer/protocol/socks/socks.pac @@ -20,7 +20,7 @@ connection SOCKS_Conn(bro_analyzer: BroAnalyzer) { %include socks-protocol.pac flow SOCKS_Flow(is_orig: bool) { - datagram = SOCKS_Version(is_orig) withcontext(connection, this); + datagram = SOCKS_Message(is_orig) withcontext(connection, this); }; %include socks-analyzer.pac diff --git a/testing/btest/Baseline/plugins.writer/output b/testing/btest/Baseline/plugins.writer/output index 0882718f03..f7b33992ea 100644 --- a/testing/btest/Baseline/plugins.writer/output +++ b/testing/btest/Baseline/plugins.writer/output @@ -17,6 +17,6 @@ Demo::Foo - A Foo test logging writer (dynamic, version 1.0) [http] 1340213020.732963|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|GET|www.osnews.com|/images/icons/17.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- [http] 1340213021.300269|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|6|GET|www.osnews.com|/images/left.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- [http] 1340213021.861584|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|7|GET|www.osnews.com|/images/icons/32.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- -[packet_filter] 1412721099.419280|bro|ip or not ip|T|T -[socks] 1340213015.276495|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|-|succeeded|-|www.osnews.com|80|192.168.0.31|-|2688 +[packet_filter] 1423781675.402129|bro|ip or not ip|T|T +[socks] 1340213015.276495|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|-|-|succeeded|-|www.osnews.com|80|192.168.0.31|-|2688 [tunnel] 1340213015.276495|-|10.0.0.55|0|60.190.189.214|8124|Tunnel::SOCKS|Tunnel::DISCOVER From 062baefde09483277bbc94574cfc45793779f98e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 13 Feb 2015 11:24:32 -0600 Subject: [PATCH 055/256] Add 'while' statement to Bro language. --- src/SerialTypes.h | 1 + src/Stmt.cc | 122 +++++++++++++++++++++- src/Stmt.h | 29 +++++ src/StmtEnums.h | 1 + src/parse.y | 6 ++ src/scan.l | 1 + testing/btest/Baseline/language.while/out | 12 +++ testing/btest/core/leaks/while.bro | 80 ++++++++++++++ testing/btest/language/while.bro | 77 ++++++++++++++ 9 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/language.while/out create mode 100644 testing/btest/core/leaks/while.bro create mode 100644 testing/btest/language/while.bro diff --git a/src/SerialTypes.h b/src/SerialTypes.h index d2f227838c..e50ec3889f 100644 --- a/src/SerialTypes.h +++ b/src/SerialTypes.h @@ -181,6 +181,7 @@ SERIAL_STMT(INIT_STMT, 17) SERIAL_STMT(NULL_STMT, 18) SERIAL_STMT(WHEN_STMT, 19) SERIAL_STMT(FALLTHROUGH_STMT, 20) +SERIAL_STMT(WHILE_STMT, 21) #define SERIAL_TYPE(name, val) SERIAL_CONST(name, val, BRO_TYPE) SERIAL_TYPE(BRO_TYPE, 1) diff --git a/src/Stmt.cc b/src/Stmt.cc index cb716b3f15..d2f8c48cee 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -23,7 +23,7 @@ const char* stmt_name(BroStmtTag t) "print", "event", "expr", "if", "when", "switch", "for", "next", "break", "return", "add", "delete", "list", "bodylist", - "", "fallthrough", + "", "fallthrough", "while", "null", }; @@ -1127,6 +1127,126 @@ bool EventStmt::DoUnserialize(UnserialInfo* info) return event_expr != 0; } +WhileStmt::WhileStmt(Expr* arg_loop_condition, Stmt* arg_body) + : loop_condition(arg_loop_condition), body(arg_body) + { + if ( ! loop_condition->IsError() && + ! IsBool(loop_condition->Type()->Tag()) ) + loop_condition->Error("while conditional must be boolean"); + } + +WhileStmt::~WhileStmt() + { + Unref(loop_condition); + Unref(body); + } + +int WhileStmt::IsPure() const + { + return loop_condition->IsPure() && body->IsPure(); + } + +void WhileStmt::Describe(ODesc* d) const + { + Stmt::Describe(d); + + if ( d->IsReadable() ) + d->Add("("); + + loop_condition->Describe(d); + + if ( d->IsReadable() ) + d->Add(")"); + + d->SP(); + d->PushIndent(); + body->AccessStats(d); + body->Describe(d); + d->PopIndent(); + } + +TraversalCode WhileStmt::Traverse(TraversalCallback* cb) const + { + TraversalCode tc = cb->PreStmt(this); + HANDLE_TC_STMT_PRE(tc); + + tc = loop_condition->Traverse(cb); + HANDLE_TC_STMT_PRE(tc); + + tc = body->Traverse(cb); + HANDLE_TC_STMT_PRE(tc); + + tc = cb->PostStmt(this); + HANDLE_TC_STMT_POST(tc); + } + +Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const + { + RegisterAccess(); + flow = FLOW_NEXT; + Val* rval = 0; + + for ( ; ; ) + { + Val* cond = loop_condition->Eval(f); + + if ( ! cond ) + break; + + bool cont = cond->AsBool(); + Unref(cond); + + if ( ! cont ) + break; + + flow = FLOW_NEXT; + rval = body->Exec(f, flow); + + if ( flow == FLOW_BREAK || flow == FLOW_RETURN ) + break; + } + + if ( flow == FLOW_LOOP || flow == FLOW_BREAK ) + flow = FLOW_NEXT; + + return rval; + } + +Stmt* WhileStmt::Simplify() + { + loop_condition = simplify_expr(loop_condition, SIMPLIFY_GENERAL); + + if ( loop_condition->IsConst() && loop_condition->IsZero() ) + return new NullStmt(); + + body = simplify_stmt(body); + return this; + } + +IMPLEMENT_SERIAL(WhileStmt, SER_WHILE_STMT); + +bool WhileStmt::DoSerialize(SerialInfo* info) const + { + DO_SERIALIZE(SER_WHILE_STMT, Stmt); + + if ( ! loop_condition->Serialize(info) ) + return false; + + return body->Serialize(info); + } + +bool WhileStmt::DoUnserialize(UnserialInfo* info) + { + DO_UNSERIALIZE(Stmt); + loop_condition = Expr::Unserialize(info); + + if ( ! loop_condition ) + return false; + + body = Stmt::Unserialize(info); + return body != 0; + } + ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr) : ExprStmt(STMT_FOR, loop_expr) { diff --git a/src/Stmt.h b/src/Stmt.h index 32b90b4190..79406fd51b 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -310,6 +310,35 @@ protected: EventExpr* event_expr; }; +class WhileStmt : public Stmt { +public: + + WhileStmt(Expr* loop_condition, Stmt* body); + + ~WhileStmt(); + + int IsPure() const; + + void Describe(ODesc* d) const; + + TraversalCode Traverse(TraversalCallback* cb) const; + +protected: + friend class Stmt; + + DECLARE_SERIAL(WhileStmt); + + WhileStmt() + { loop_condition = 0; body = 0; } + + Val* Exec(Frame* f, stmt_flow_type& flow) const; + + Stmt* Simplify(); + + Expr* loop_condition; + Stmt* body; +}; + class ForStmt : public ExprStmt { public: ForStmt(id_list* loop_vars, Expr* loop_expr); diff --git a/src/StmtEnums.h b/src/StmtEnums.h index d34f642594..ad99c2365a 100644 --- a/src/StmtEnums.h +++ b/src/StmtEnums.h @@ -17,6 +17,7 @@ typedef enum { STMT_LIST, STMT_EVENT_BODY_LIST, STMT_INIT, STMT_FALLTHROUGH, + STMT_WHILE, STMT_NULL #define NUM_STMTS (int(STMT_NULL) + 1) } BroStmtTag; diff --git a/src/parse.y b/src/parse.y index f74880dc13..8054718d45 100644 --- a/src/parse.y +++ b/src/parse.y @@ -16,6 +16,7 @@ %token TOK_REMOVE_FROM TOK_RETURN TOK_SCHEDULE TOK_SET %token TOK_STRING TOK_SUBNET TOK_SWITCH TOK_TABLE %token TOK_TIME TOK_TIMEOUT TOK_TIMER TOK_TYPE TOK_UNION TOK_VECTOR TOK_WHEN +%token TOK_WHILE %token TOK_ATTR_ADD_FUNC TOK_ATTR_ENCRYPT TOK_ATTR_DEFAULT %token TOK_ATTR_OPTIONAL TOK_ATTR_REDEF TOK_ATTR_ROTATE_INTERVAL @@ -1340,6 +1341,11 @@ stmt: $1->AsForStmt()->AddBody($2); } + | TOK_WHILE '(' expr ')' stmt + { + $$ = new WhileStmt($3, $5); + } + | TOK_NEXT ';' opt_no_test { set_location(@1, @2); diff --git a/src/scan.l b/src/scan.l index ae11382fb3..b13215e4b8 100644 --- a/src/scan.l +++ b/src/scan.l @@ -221,6 +221,7 @@ export return TOK_EXPORT; fallthrough return TOK_FALLTHROUGH; file return TOK_FILE; for return TOK_FOR; +while return TOK_WHILE; function return TOK_FUNCTION; global return TOK_GLOBAL; "?$" return TOK_HAS_FIELD; diff --git a/testing/btest/Baseline/language.while/out b/testing/btest/Baseline/language.while/out new file mode 100644 index 0000000000..d37792c0b4 --- /dev/null +++ b/testing/btest/Baseline/language.while/out @@ -0,0 +1,12 @@ +10 +s +ss +sss +{ +7, +1, +9, +5, +3 +} +[number 0, number 1, number 2, number 3, number 4, number 5, number 6, number 7, number 8, number 9, number 10, number 11, number 12] diff --git a/testing/btest/core/leaks/while.bro b/testing/btest/core/leaks/while.bro new file mode 100644 index 0000000000..eac6f2622e --- /dev/null +++ b/testing/btest/core/leaks/while.bro @@ -0,0 +1,80 @@ +# @TEST-GROUP: leaks +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks + +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/http/get.trace %INPUT +# @TEST-EXEC: btest-bg-wait 30 + +function test_noop() + { + while ( F ) + print "noooooooooo"; + } + +function test_it() + { + local i = 0; + + while ( i < 10 ) + ++i; + + print i; + } + +function test_break() + { + local s = ""; + + while ( T ) + { + s += "s"; + print s; + + if ( s == "sss" ) + break; + } + } + +function test_next() + { + local s: set[count]; + local i = 0; + + while ( 9 !in s ) + { + ++i; + + if ( i % 2 == 0 ) + next; + + add s[i]; + } + + print s; + } + +function test_return(): vector of string + { + local i = 0; + local rval: vector of string; + + while ( T ) + { + rval[i] = fmt("number %d", i); + ++i; + + if ( i == 13 ) + return rval; + } + + rval[0] = "noooo"; + return rval; + } + +event new_connection(c: connection) + { + test_noop(); + test_it(); + test_break(); + test_next(); + print test_return(); + } diff --git a/testing/btest/language/while.bro b/testing/btest/language/while.bro new file mode 100644 index 0000000000..6828b00b41 --- /dev/null +++ b/testing/btest/language/while.bro @@ -0,0 +1,77 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +function test_noop() + { + while ( F ) + print "noooooooooo"; + } + +function test_it() + { + local i = 0; + + while ( i < 10 ) + ++i; + + print i; + } + +function test_break() + { + local s = ""; + + while ( T ) + { + s += "s"; + print s; + + if ( s == "sss" ) + break; + } + } + +function test_next() + { + local s: set[count]; + local i = 0; + + while ( 9 !in s ) + { + ++i; + + if ( i % 2 == 0 ) + next; + + add s[i]; + } + + print s; + } + +function test_return(): vector of string + { + local i = 0; + local rval: vector of string; + + while ( T ) + { + rval[i] = fmt("number %d", i); + ++i; + + if ( i == 13 ) + return rval; + } + + rval[0] = "noooo"; + return rval; + } + +event bro_init() + { + test_noop(); + test_it(); + test_break(); + test_next(); + print test_return(); + } From 8e4f4b46f7591a3779adc8e21d688f81ee436721 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 13 Feb 2015 16:23:43 -0600 Subject: [PATCH 056/256] Updating submodule(s). [nomail] --- aux/broccoli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broccoli b/aux/broccoli index d43cc790e5..9b6dd56242 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit d43cc790e5b8709b5e032e52ad0e00936494739b +Subproject commit 9b6dd5624254de9d18618562887979da1158da43 From 4bcb9d2d920862660feba80cfb13356952843201 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 13 Feb 2015 18:04:17 -0600 Subject: [PATCH 057/256] Updating submodule(s). [nomail] --- aux/broccoli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broccoli b/aux/broccoli index 9b6dd56242..420c5b42c0 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 9b6dd5624254de9d18618562887979da1158da43 +Subproject commit 420c5b42c0c90f22fc7a862fc491c8e554d05381 From b00bd7702f8962bcf8507adb0abe967c4c02426c Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Fri, 13 Feb 2015 22:02:54 -0500 Subject: [PATCH 058/256] Add the ability to remove surrounding braces from the JSON formatter. --- src/threading/formatters/JSON.cc | 13 ++++++++++--- src/threading/formatters/JSON.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/threading/formatters/JSON.cc b/src/threading/formatters/JSON.cc index 472023e0f8..e1a5713461 100644 --- a/src/threading/formatters/JSON.cc +++ b/src/threading/formatters/JSON.cc @@ -15,7 +15,7 @@ using namespace threading::formatter; -JSON::JSON(MsgThread* t, TimeFormat tf) : Formatter(t) +JSON::JSON(MsgThread* t, TimeFormat tf) : Formatter(t), surrounding_braces(true) { timestamps = tf; } @@ -27,7 +27,8 @@ JSON::~JSON() bool JSON::Describe(ODesc* desc, int num_fields, const Field* const * fields, Value** vals) const { - desc->AddRaw("{"); + if ( surrounding_braces ) + desc->AddRaw("{"); for ( int i = 0; i < num_fields; i++ ) { @@ -41,7 +42,8 @@ bool JSON::Describe(ODesc* desc, int num_fields, const Field* const * fields, return false; } - desc->AddRaw("}"); + if ( surrounding_braces ) + desc->AddRaw("}"); return true; } @@ -217,3 +219,8 @@ threading::Value* JSON::ParseValue(const string& s, const string& name, TypeTag GetThread()->Error("JSON formatter does not support parsing yet."); return NULL; } + +void JSON::SurroundingBraces(bool use_braces) + { + surrounding_braces = use_braces; + } diff --git a/src/threading/formatters/JSON.h b/src/threading/formatters/JSON.h index d7859f83fb..04209fbde9 100644 --- a/src/threading/formatters/JSON.h +++ b/src/threading/formatters/JSON.h @@ -27,8 +27,11 @@ public: threading::Value** vals) const; virtual threading::Value* ParseValue(const string& s, const string& name, TypeTag type, TypeTag subtype = TYPE_ERROR) const; + void SurroundingBraces(bool use_braces); + private: TimeFormat timestamps; + bool surrounding_braces; }; }} From 46713fb5c705b8ff1f6a6312141307801577db3a Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sat, 14 Feb 2015 13:16:48 -0800 Subject: [PATCH 059/256] Init RDP analyzer --- scripts/base/init-default.bro | 1 + scripts/base/protocols/rdp/__load__.bro | 4 + scripts/base/protocols/rdp/consts.bro | 287 +++++++++++++++++++ scripts/base/protocols/rdp/dpd.sig | 19 ++ scripts/base/protocols/rdp/main.bro | 200 +++++++++++++ src/analyzer/protocol/CMakeLists.txt | 2 +- src/analyzer/protocol/rdp/CMakeLists.txt | 9 + src/analyzer/protocol/rdp/Plugin.cc | 22 ++ src/analyzer/protocol/rdp/RDP.cc | 70 +++++ src/analyzer/protocol/rdp/RDP.h | 48 ++++ src/analyzer/protocol/rdp/events.bif | 60 ++++ src/analyzer/protocol/rdp/rdp-analyzer.pac | 101 +++++++ src/analyzer/protocol/rdp/rdp-protocol.pac | 313 +++++++++++++++++++++ src/analyzer/protocol/rdp/rdp.pac | 26 ++ 14 files changed, 1161 insertions(+), 1 deletion(-) create mode 100644 scripts/base/protocols/rdp/__load__.bro create mode 100644 scripts/base/protocols/rdp/consts.bro create mode 100644 scripts/base/protocols/rdp/dpd.sig create mode 100644 scripts/base/protocols/rdp/main.bro create mode 100644 src/analyzer/protocol/rdp/CMakeLists.txt create mode 100644 src/analyzer/protocol/rdp/Plugin.cc create mode 100644 src/analyzer/protocol/rdp/RDP.cc create mode 100644 src/analyzer/protocol/rdp/RDP.h create mode 100644 src/analyzer/protocol/rdp/events.bif create mode 100644 src/analyzer/protocol/rdp/rdp-analyzer.pac create mode 100644 src/analyzer/protocol/rdp/rdp-protocol.pac create mode 100644 src/analyzer/protocol/rdp/rdp.pac diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 04dc2a4910..2af8f3bc3d 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -49,6 +49,7 @@ @load base/protocols/mysql @load base/protocols/pop3 @load base/protocols/radius +@load base/protocols/rdp @load base/protocols/snmp @load base/protocols/smtp @load base/protocols/socks diff --git a/scripts/base/protocols/rdp/__load__.bro b/scripts/base/protocols/rdp/__load__.bro new file mode 100644 index 0000000000..baa1dd2eca --- /dev/null +++ b/scripts/base/protocols/rdp/__load__.bro @@ -0,0 +1,4 @@ +# Generated by binpac_quickstart +@load ./consts +@load ./main +@load-sigs ./dpd.sig diff --git a/scripts/base/protocols/rdp/consts.bro b/scripts/base/protocols/rdp/consts.bro new file mode 100644 index 0000000000..5d93e6ea5d --- /dev/null +++ b/scripts/base/protocols/rdp/consts.bro @@ -0,0 +1,287 @@ +module RDP; + +export { + # http://www.c-amie.co.uk/technical/mstsc-versions/ + const builds = { + [0419] = "RDP 4.0", + [2195] = "RDP 5.0", + [2221] = "RDP 5.0", + [2600] = "RDP 5.1", + [3790] = "RDP 5.2", + [6000] = "RDP 6.0", + [6001] = "RDP 6.1", + [6002] = "RDP 6.2", + [7600] = "RDP 7.0", + [7601] = "RDP 7.1", + [9200] = "RDP 8.0", + [9600] = "RDP 8.1", + [25189] = "RDP 8.0 (Mac)", + [25282] = "RDP 8.0 (Mac)" + } &default = function(n: count): string { return fmt("client_build-%d", n); }; + + const encryption_methods = { + [0] = "None", + [1] = "40bit", + [2] = "128bit", + [8] = "56bit", + [10] = "FIPS" + } &default = function(n: count): string { return fmt("encryption_method-%d", n); }; + + const encryption_levels = { + [0] = "None", + [1] = "Low", + [2] = "Client compatible", + [3] = "High", + [4] = "FIPS" + } &default = function(n: count): string { return fmt("encryption_level-%d", n); }; + + const results = { + [0] = "Success", + [1] = "User rejected", + [2] = "Resources not available", + [3] = "Rejected for symmetry breaking", + [4] = "Locked conference", + } &default = function(n: count): string { return fmt("result-%d", n); }; + + # http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx + const languages = { + [1078] = "Afrikaans - South Africa", + [1052] = "Albanian - Albania", + [1156] = "Alsatian", + [1118] = "Amharic - Ethiopia", + [1025] = "Arabic - Saudi Arabia", + [5121] = "Arabic - Algeria", + [15361] = "Arabic - Bahrain", + [3073] = "Arabic - Egypt", + [2049] = "Arabic - Iraq", + [11265] = "Arabic - Jordan", + [13313] = "Arabic - Kuwait", + [12289] = "Arabic - Lebanon", + [4097] = "Arabic - Libya", + [6145] = "Arabic - Morocco", + [8193] = "Arabic - Oman", + [16385] = "Arabic - Qatar", + [10241] = "Arabic - Syria", + [7169] = "Arabic - Tunisia", + [14337] = "Arabic - U.A.E.", + [9217] = "Arabic - Yemen", + [1067] = "Armenian - Armenia", + [1101] = "Assamese", + [2092] = "Azeri (Cyrillic)", + [1068] = "Azeri (Latin)", + [1133] = "Bashkir", + [1069] = "Basque", + [1059] = "Belarusian", + [1093] = "Bengali (India)", + [2117] = "Bengali (Bangladesh)", + [5146] = "Bosnian (Bosnia/Herzegovina)", + [1150] = "Breton", + [1026] = "Bulgarian", + [1109] = "Burmese", + [1027] = "Catalan", + [1116] = "Cherokee - United States", + [2052] = "Chinese - People's Republic of China", + [4100] = "Chinese - Singapore", + [1028] = "Chinese - Taiwan", + [3076] = "Chinese - Hong Kong SAR", + [5124] = "Chinese - Macao SAR", + [1155] = "Corsican", + [1050] = "Croatian", + [4122] = "Croatian (Bosnia/Herzegovina)", + [1029] = "Czech", + [1030] = "Danish", + [1164] = "Dari", + [1125] = "Divehi", + [1043] = "Dutch - Netherlands", + [2067] = "Dutch - Belgium", + [1126] = "Edo", + [1033] = "English - United States", + [2057] = "English - United Kingdom", + [3081] = "English - Australia", + [10249] = "English - Belize", + [4105] = "English - Canada", + [9225] = "English - Caribbean", + [15369] = "English - Hong Kong SAR", + [16393] = "English - India", + [14345] = "English - Indonesia", + [6153] = "English - Ireland", + [8201] = "English - Jamaica", + [17417] = "English - Malaysia", + [5129] = "English - New Zealand", + [13321] = "English - Philippines", + [18441] = "English - Singapore", + [7177] = "English - South Africa", + [11273] = "English - Trinidad", + [12297] = "English - Zimbabwe", + [1061] = "Estonian", + [1080] = "Faroese", + [1065] = "Farsi", + [1124] = "Filipino", + [1035] = "Finnish", + [1036] = "French - France", + [2060] = "French - Belgium", + [11276] = "French - Cameroon", + [3084] = "French - Canada", + [9228] = "French - Democratic Rep. of Congo", + [12300] = "French - Cote d'Ivoire", + [15372] = "French - Haiti", + [5132] = "French - Luxembourg", + [13324] = "French - Mali", + [6156] = "French - Monaco", + [14348] = "French - Morocco", + [58380] = "French - North Africa", + [8204] = "French - Reunion", + [10252] = "French - Senegal", + [4108] = "French - Switzerland", + [7180] = "French - West Indies", + [1122] = "French - West Indies", + [1127] = "Fulfulde - Nigeria", + [1071] = "FYRO Macedonian", + [1110] = "Galician", + [1079] = "Georgian", + [1031] = "German - Germany", + [3079] = "German - Austria", + [5127] = "German - Liechtenstein", + [4103] = "German - Luxembourg", + [2055] = "German - Switzerland", + [1032] = "Greek", + [1135] = "Greenlandic", + [1140] = "Guarani - Paraguay", + [1095] = "Gujarati", + [1128] = "Hausa - Nigeria", + [1141] = "Hawaiian - United States", + [1037] = "Hebrew", + [1081] = "Hindi", + [1038] = "Hungarian", + [1129] = "Ibibio - Nigeria", + [1039] = "Icelandic", + [1136] = "Igbo - Nigeria", + [1057] = "Indonesian", + [1117] = "Inuktitut", + [2108] = "Irish", + [1040] = "Italian - Italy", + [2064] = "Italian - Switzerland", + [1041] = "Japanese", + [1158] = "K'iche", + [1099] = "Kannada", + [1137] = "Kanuri - Nigeria", + [2144] = "Kashmiri", + [1120] = "Kashmiri (Arabic)", + [1087] = "Kazakh", + [1107] = "Khmer", + [1159] = "Kinyarwanda", + [1111] = "Konkani", + [1042] = "Korean", + [1088] = "Kyrgyz (Cyrillic)", + [1108] = "Lao", + [1142] = "Latin", + [1062] = "Latvian", + [1063] = "Lithuanian", + [1134] = "Luxembourgish", + [1086] = "Malay - Malaysia", + [2110] = "Malay - Brunei Darussalam", + [1100] = "Malayalam", + [1082] = "Maltese", + [1112] = "Manipuri", + [1153] = "Maori - New Zealand", + [1146] = "Mapudungun", + [1102] = "Marathi", + [1148] = "Mohawk", + [1104] = "Mongolian (Cyrillic)", + [2128] = "Mongolian (Mongolian)", + [1121] = "Nepali", + [2145] = "Nepali - India", + [1044] = "Norwegian (Bokmål)", + [2068] = "Norwegian (Nynorsk)", + [1154] = "Occitan", + [1096] = "Oriya", + [1138] = "Oromo", + [1145] = "Papiamentu", + [1123] = "Pashto", + [1045] = "Polish", + [1046] = "Portuguese - Brazil", + [2070] = "Portuguese - Portugal", + [1094] = "Punjabi", + [2118] = "Punjabi (Pakistan)", + [1131] = "Quecha - Bolivia", + [2155] = "Quecha - Ecuador", + [3179] = "Quecha - Peru CB", + [1047] = "Rhaeto-Romanic", + [1048] = "Romanian", + [2072] = "Romanian - Moldava", + [1049] = "Russian", + [2073] = "Russian - Moldava", + [1083] = "Sami (Lappish)", + [1103] = "Sanskrit", + [1084] = "Scottish Gaelic", + [1132] = "Sepedi", + [3098] = "Serbian (Cyrillic)", + [2074] = "Serbian (Latin)", + [1113] = "Sindhi - India", + [2137] = "Sindhi - Pakistan", + [1115] = "Sinhalese - Sri Lanka", + [1051] = "Slovak", + [1060] = "Slovenian", + [1143] = "Somali", + [1070] = "Sorbian", + [3082] = "Spanish - Spain (Modern Sort)", + [1034] = "Spanish - Spain (Traditional Sort)", + [11274] = "Spanish - Argentina", + [16394] = "Spanish - Bolivia", + [13322] = "Spanish - Chile", + [9226] = "Spanish - Colombia", + [5130] = "Spanish - Costa Rica", + [7178] = "Spanish - Dominican Republic", + [12298] = "Spanish - Ecuador", + [17418] = "Spanish - El Salvador", + [4106] = "Spanish - Guatemala", + [18442] = "Spanish - Honduras", + [22538] = "Spanish - Latin America", + [2058] = "Spanish - Mexico", + [19466] = "Spanish - Nicaragua", + [6154] = "Spanish - Panama", + [15370] = "Spanish - Paraguay", + [10250] = "Spanish - Peru", + [20490] = "Spanish - Puerto Rico", + [21514] = "Spanish - United States", + [14346] = "Spanish - Uruguay", + [8202] = "Spanish - Venezuela", + [1072] = "Sutu", + [1089] = "Swahili", + [1053] = "Swedish", + [2077] = "Swedish - Finland", + [1114] = "Syriac", + [1064] = "Tajik", + [1119] = "Tamazight (Arabic)", + [2143] = "Tamazight (Latin)", + [1097] = "Tamil", + [1092] = "Tatar", + [1098] = "Telugu", + [1054] = "Thai", + [2129] = "Tibetan - Bhutan", + [1105] = "Tibetan - People's Republic of China", + [2163] = "Tigrigna - Eritrea", + [1139] = "Tigrigna - Ethiopia", + [1073] = "Tsonga", + [1074] = "Tswana", + [1055] = "Turkish", + [1090] = "Turkmen", + [1152] = "Uighur - China", + [1058] = "Ukrainian", + [1056] = "Urdu", + [2080] = "Urdu - India", + [2115] = "Uzbek (Cyrillic)", + [1091] = "Uzbek (Latin)", + [1075] = "Venda", + [1066] = "Vietnamese", + [1106] = "Welsh", + [1160] = "Wolof", + [1076] = "Xhosa", + [1157] = "Yakut", + [1144] = "Yi", + [1085] = "Yiddish", + [1130] = "Yoruba", + [1077] = "Zulu", + [1279] = "HID (Human Interface Device)", + } &default = function(n: count): string { return fmt("keyboard-%d", n); }; +} diff --git a/scripts/base/protocols/rdp/dpd.sig b/scripts/base/protocols/rdp/dpd.sig new file mode 100644 index 0000000000..35aa8f9257 --- /dev/null +++ b/scripts/base/protocols/rdp/dpd.sig @@ -0,0 +1,19 @@ +# Generated by binpac_quickstart + +signature dpd_rdp_client_request { + ip-proto == tcp + payload /.*Cookie: mstshash\=.*/ + enable "rdp" +} + +signature dpd_rdp_client_header { + ip-proto == tcp + payload /.*Duca.*(rdpdr|rdpsnd|drdynvc|cliprdr).*/ + enable "rdp" +} + +signature dpd_rdp_server_response { + ip-proto == tcp + payload /.*McDn.*/ + enable "rdp" +} diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro new file mode 100644 index 0000000000..94aa26b6ec --- /dev/null +++ b/scripts/base/protocols/rdp/main.bro @@ -0,0 +1,200 @@ +@load ./consts + +module RDP; + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + ## Timestamp for when the event happened. + ts: time &log; + ## Unique ID for the connection. + uid: string &log; + ## The connection's 4-tuple of endpoint addresses/ports. + id: conn_id &log; + ## Cookie value used by the client machine. + ## This is typically a username. + cookie: string &log &optional; + ## Keyboard layout (language) of the client machine. + keyboard_layout: string &log &optional; + ## RDP client version used by the client machine. + client_build: string &log &optional; + ## Hostname of the client machine. + client_hostname: string &log &optional; + ## Product ID of the client machine. + client_product_id: string &log &optional; + ## Name of the server. + server_name: vector of string &log &optional; + ## Authentication result for the connection. This value is extracted from the payload for native authentication. + ## TODO: Perform heuristic authentication determination for NLA. + authentication_result: string &log &optional; + ## Encryption level of the connection. + encryption_level: string &log &optional; + ## Encryption method of the connection. + encryption_method: string &log &optional; + ## Track status of logging RDP connections. + done: bool &default=F; + }; + + ## Variable to track if NTLM authentication is used. + global ntlm = F; + + ## Size in bytes of data sent by the server at which the RDP connection is presumed to be successful (NTLM authentication only). + const authentication_data_size = 1000 &redef; + + ## Event that can be handled to access the rdp record as it is sent on + ## to the loggin framework. + global log_rdp: event(rec: Info); +} + +const ports = { 3389/tcp }; +redef likely_server_ports += { ports }; + +event bro_init() &priority=5 + { + Log::create_stream(RDP::LOG, [$columns=Info, $ev=log_rdp]); + Analyzer::register_for_ports(Analyzer::ANALYZER_RDP, ports); + } + +redef record connection += { + rdp: Info &optional; + }; + +function rdp_done(c: connection, done: bool) + { + if ( done ) + { + c$rdp$done = T; + + # Not currently implemented +# if ( ntlm && use_conn_size_analyzer ) +# { +# if ( c$resp$size > authentication_data_size ) +# c$rdp$authentication_result = "Success (H)"; +# else c$rdp$authentication_result = "Undetermined"; +# } + + if ( c$rdp?$authentication_result && ( ! c$rdp?$encryption_method || ! c$rdp?$encryption_level ) ) + Reporter::error(fmt("Error parsing RDP security data in connection %s",c$uid)); + + Log::write(RDP::LOG, c$rdp); + skip_further_processing(c$id); + set_record_packets(c$id, F); + } + } + +event rdp_tracker(c: connection) + { + if ( c$rdp$done ) + return; + + local id = c$id; + + if ( ! connection_exists(id) ) + { + rdp_done(c,T); + return; + } + + lookup_connection(id); + + if ( connection_exists(id) ) + { + # If the RDP connection has been alive for more than 5secs, log it + # This duration should be sufficient to collect the data that needs to be logged + local diff = network_time() - c$rdp$ts; + if ( diff > 5secs ) + { + rdp_done(c,T); + return; + } + } + + # schedule the event to run again if necessary + schedule +5secs { rdp_tracker(c) }; + } + +function set_session(c: connection) + { + if ( ! c?$rdp ) + { + c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid]; + add c$service["rdp"]; + } + } + +event connection_state_remove(c: connection) &priority=-5 + { + # Log the RDP connection if the connection is removed but the session has not been marked as done + if ( c?$rdp && ! c$rdp$done ) + rdp_done(c,T); + } + +event rdp_native_client_request(c: connection, cookie: string) &priority=5 + { + if ( "Cookie" in clean(cookie) ) + { + set_session(c); + local cookie_val = sub(cookie,/Cookie.*\=/,""); + c$rdp$cookie = sub(cookie_val,/\x0d\x0a.*$/,""); + + schedule +5secs { rdp_tracker(c) }; + } + } + +event rdp_native_client_info(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5 + { + set_session(c); + c$rdp$keyboard_layout = languages[keyboard_layout]; + c$rdp$client_build = builds[build]; + c$rdp$client_hostname = gsub(cat(hostname),/\\0/,""); + c$rdp$client_product_id = gsub(cat(product_id),/\\0/,""); + + schedule +5secs { rdp_tracker(c) }; + } + +event rdp_native_authentication(c: connection, result: count) &priority=5 + { + set_session(c); + c$rdp$authentication_result = results[result]; + + schedule +5secs { rdp_tracker(c) }; + } + +event rdp_native_server_security(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string) &priority=5 + { + set_session(c); + c$rdp$encryption_method = encryption_methods[encryption_method]; + c$rdp$encryption_level = encryption_levels[encryption_level]; + + schedule +5secs { rdp_tracker(c) }; + } + +event rdp_ntlm_client_request(c: connection, server: string) &priority=5 + { + set_session(c); + ntlm = T; + + if ( ! c$rdp?$server_name ) + c$rdp$server_name = vector(); + c$rdp$server_name[|c$rdp$server_name|] = server; + + schedule +5secs { rdp_tracker(c) }; + } + +event rdp_ntlm_server_response(c: connection, server: string) &priority=5 + { + set_session(c); + ntlm = T; + + if ( ! c$rdp?$server_name ) + c$rdp$server_name = vector(); + c$rdp$server_name[|c$rdp$server_name|] = server; + + schedule +5secs { rdp_tracker(c) }; + } + +event rdp_debug(c: connection, remainder: string) + { + Reporter::error(fmt("Debug RDP data generated in connection %s: %s",c$uid,remainder)); + } diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index d0fa1ded66..783f1e7469 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -21,7 +21,6 @@ add_subdirectory(irc) add_subdirectory(login) add_subdirectory(mime) add_subdirectory(modbus) -add_subdirectory(mysql) add_subdirectory(ncp) add_subdirectory(netbios) add_subdirectory(netflow) @@ -29,6 +28,7 @@ add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) add_subdirectory(radius) +add_subdirectory(rdp) add_subdirectory(rpc) add_subdirectory(snmp) add_subdirectory(smb) diff --git a/src/analyzer/protocol/rdp/CMakeLists.txt b/src/analyzer/protocol/rdp/CMakeLists.txt new file mode 100644 index 0000000000..445e853f2c --- /dev/null +++ b/src/analyzer/protocol/rdp/CMakeLists.txt @@ -0,0 +1,9 @@ +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro RDP) + bro_plugin_cc(RDP.cc Plugin.cc) + bro_plugin_bif(events.bif) + bro_plugin_pac(rdp.pac rdp-analyzer.pac rdp-protocol.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/rdp/Plugin.cc b/src/analyzer/protocol/rdp/Plugin.cc new file mode 100644 index 0000000000..770bdfc730 --- /dev/null +++ b/src/analyzer/protocol/rdp/Plugin.cc @@ -0,0 +1,22 @@ +#include "plugin/Plugin.h" + +#include "RDP.h" + +namespace plugin { +namespace Bro_RDP { + +class Plugin : public plugin::Plugin { +public: + plugin::Configuration Configure() + { + AddComponent(new ::analyzer::Component("RDP", ::analyzer::rdp::RDP_Analyzer::InstantiateAnalyzer)); + + plugin::Configuration config; + config.name = "Bro::RDP"; + config.description = "RDP analyzer"; + return config; + } +} plugin; + +} +} diff --git a/src/analyzer/protocol/rdp/RDP.cc b/src/analyzer/protocol/rdp/RDP.cc new file mode 100644 index 0000000000..70cad773fe --- /dev/null +++ b/src/analyzer/protocol/rdp/RDP.cc @@ -0,0 +1,70 @@ +#include "RDP.h" + +#include "analyzer/protocol/tcp/TCP_Reassembler.h" + +#include "Reporter.h" + +#include "events.bif.h" + +using namespace analyzer::rdp; + +RDP_Analyzer::RDP_Analyzer(Connection* c) + +: tcp::TCP_ApplicationAnalyzer("RDP", c) + { + interp = new binpac::RDP::RDP_Conn(this); + + had_gap = false; + + } + +RDP_Analyzer::~RDP_Analyzer() + { + delete interp; + } + +void RDP_Analyzer::Done() + { + + tcp::TCP_ApplicationAnalyzer::Done(); + + interp->FlowEOF(true); + interp->FlowEOF(false); + + } + +void RDP_Analyzer::EndpointEOF(bool is_orig) + { + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + interp->FlowEOF(is_orig); + } + +void RDP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + + assert(TCP()); + if ( TCP()->IsPartial() ) + return; + + if ( had_gap ) + // If only one side had a content gap, we could still try to + // deliver data to the other side if the script layer can handle this. + return; + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); + } + } + +void RDP_Analyzer::Undelivered(uint64 seq, int len, bool orig) + { + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + had_gap = true; + interp->NewGap(orig, len); + } diff --git a/src/analyzer/protocol/rdp/RDP.h b/src/analyzer/protocol/rdp/RDP.h new file mode 100644 index 0000000000..cb5197cffe --- /dev/null +++ b/src/analyzer/protocol/rdp/RDP.h @@ -0,0 +1,48 @@ +#ifndef ANALYZER_PROTOCOL_RDP_RDP_H +#define ANALYZER_PROTOCOL_RDP_RDP_H + +#include "events.bif.h" + + +#include "analyzer/protocol/tcp/TCP.h" + +#include "rdp_pac.h" + +namespace analyzer { namespace rdp { + +class RDP_Analyzer : public tcp::TCP_ApplicationAnalyzer { + +public: + RDP_Analyzer(Connection* conn); + virtual ~RDP_Analyzer(); + + // Overriden from Analyzer. + virtual void Done(); + + virtual void DeliverStream(int len, const u_char* data, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); + + // Overriden from tcp::TCP_ApplicationAnalyzer. + virtual void EndpointEOF(bool is_orig); + + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new RDP_Analyzer(conn); } + +// static bool Available() +// { + // TODO: After you define your events, || them together here. + // See events.bif for more information + //return ( rdp_event ); +// } + +protected: + binpac::RDP::RDP_Conn* interp; + + bool had_gap; + +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/rdp/events.bif b/src/analyzer/protocol/rdp/events.bif new file mode 100644 index 0000000000..dad76f801b --- /dev/null +++ b/src/analyzer/protocol/rdp/events.bif @@ -0,0 +1,60 @@ +## Generated for client-to-server RDP requests when NTLM authentication is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## server: The RDP server name requested by the client. +event rdp_ntlm_client_request%(c: connection, server: string%); + +## Generated for server-to-client RDP responses when NTLM authentication is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## server: The RDP server name responsed by the server. +event rdp_ntlm_server_response%(c: connection, server: string%); + +## Generated for X.224 client requests when native RDP encryption is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## cookie: The cookie included in the request. +event rdp_native_client_request%(c: connection, cookie: string%); + +## Generated for MCS client requests when native RDP encryption is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## keyboard_layout: The 16-bit integer representing the keyboard layout/language of the client machine. +## +## build: The 16-bit integer representing the version of the RDP client. +## +## hostname: The hostname of the client machine (optional). +## +## product_id: The product ID of the client machine (optional). +event rdp_native_client_info%(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string%); + +## Generated for MCS server responses when native RDP encryption is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## result: The 8-bit integer representing the GCC Conference Create Response result. +event rdp_native_authentication%(c: connection, result: count%); + +## Generated for MCS server responses when native RDP encryption is used. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## encryption_method: The 32-bit integer representing the encryption method used in the connection. +## +## encryption_level: The 32-bit integer representing the encryption level used in the connection. +## +## random: The random value used to derive session keys (optional). +## +## certificate: The certificate containing the server's public key information. +event rdp_native_server_security%(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string%); + +## Generated for unknown elements in RDP connections. Used for debugging and development purposes only. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## remainder: The data to be debugged. +event rdp_debug%(c: connection, remainder: string%); diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac new file mode 100644 index 0000000000..f95ff9f589 --- /dev/null +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -0,0 +1,101 @@ +refine flow RDP_Flow += { + function proc_rdp_debug(debug: Debug): bool + %{ + BifEvent::generate_rdp_debug(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${debug.remainder})); + + return true; + %} + + + function proc_rdp_ntlm_server_response(ntlm_server: NTLMServerResponse): bool + %{ + BifEvent::generate_rdp_ntlm_server_response(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${ntlm_server.server_name})); + + return true; + %} + + function proc_rdp_ntlm_client_request(ntlm_client: NTLMClientRequest): bool + %{ + BifEvent::generate_rdp_ntlm_client_request(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${ntlm_client.server_name})); + + return true; + %} + + function proc_rdp_native_client_request(client_request: ClientRequest): bool + %{ + BifEvent::generate_rdp_native_client_request(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${client_request.cookie})); + + return true; + %} + + + function proc_rdp_native_authentication(gcc_response: GCC_Server_CreateResponse): bool + %{ + BifEvent::generate_rdp_native_authentication(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${gcc_response.result}); + + return true; + %} + + + function proc_rdp_native_client_info(ccore: ClientCore): bool + %{ + BifEvent::generate_rdp_native_client_info(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${ccore.keyboard_layout}, + ${ccore.client_build}, + bytestring_to_val(${ccore.client_name}), + bytestring_to_val(${ccore.dig_product_id})); + + return true; + %} + + function proc_rdp_native_server_security(ssd: ServerSecurityData): bool + %{ + BifEvent::generate_rdp_native_server_security(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${ssd.encryption_method}, + ${ssd.encryption_level}, + bytestring_to_val(${ssd.server_random}), + bytestring_to_val(${ssd.server_certificate})); + + return true; + %} +}; + +refine typeattr Debug += &let { + proc: bool = $context.flow.proc_rdp_debug(this); +}; + +refine typeattr NTLMServerResponse += &let { + proc: bool = $context.flow.proc_rdp_ntlm_server_response(this); +}; + +refine typeattr NTLMClientRequest += &let { + proc: bool = $context.flow.proc_rdp_ntlm_client_request(this); +}; + +refine typeattr ClientRequest += &let { + proc: bool = $context.flow.proc_rdp_native_client_request(this); +}; + +refine typeattr ClientCore += &let { + proc: bool = $context.flow.proc_rdp_native_client_info(this); +}; + +refine typeattr GCC_Server_CreateResponse += &let { + proc: bool = $context.flow.proc_rdp_native_authentication(this); +}; + +refine typeattr ServerSecurityData += &let { + proc: bool = $context.flow.proc_rdp_native_server_security(this); +}; diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac new file mode 100644 index 0000000000..ea68040314 --- /dev/null +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -0,0 +1,313 @@ +type RDP_PDU(is_orig: bool) = record { + type: uint16; + switch: case type of { + 0x1603 -> ntlm_authentication: NTLMAuthentication; # NTLM authentication appears to be flagged by this 16-bit integer + default -> native_encryption: NativeEncryption; # assume native encryption, this should be the value of the TPKT version + }; +} &byteorder=bigendian; + +###################################################################### +# Native Encryption +###################################################################### + +type NativeEncryption = record { + pad: padding[2]; # remaining TPKT values + cotp: COTP; +}; + +type COTP = record { + length: uint8; + pdu: uint8; + switch: case pdu of { + 0xe0 -> cRequest: ClientRequest; + 0xf0 -> hdr: Header; + default -> data: bytestring &restofdata &transient; + }; +} &byteorder=littleendian; + +type Header = record { + tpdu_number: uint8; + application_defined_type: uint8; # this begins a BER encoded multiple octet variant, but can be safely skipped + application_type: uint8; # this is value for the BER encoded octet variant above + switch: case application_type of { + 0x65 -> cHeader: ClientHeader; # 0x65 is a client + 0x66 -> sHeader: ServerHeader; # 0x66 is a server + default -> data: bytestring &restofdata &transient; + }; +} &byteorder=littleendian; + +###################################################################### +# Client X.224 +###################################################################### + +type ClientRequest = record { + destination_reference: uint16; + source_reference: uint16; + flow_control: uint8; + cookie: bytestring &restofdata; # cookie value is a variable length field, so everything is captured +}; + +###################################################################### +# Client MCS +###################################################################### + +type ClientHeader = record { + type_length: padding[3]; # BER encoded long variant, can be safely skipped for now + calling_domain_selector: ASN1OctetString; + called_domain_selector: ASN1OctetString; + upward_flag: ASN1Boolean; + target_parameters: ASN1SequenceMeta; + targ_parameters_pad: padding[target_parameters.encoding.length]; + minimum_parameters: ASN1SequenceMeta; + min_parameters_pad: padding[minimum_parameters.encoding.length]; + maximum_parameters: ASN1SequenceMeta; + max_parameters_pad: padding[maximum_parameters.encoding.length]; + user_data_length: uint32; # BER encoded OctetString and long variant, can be safely skipped for now + gcc_connection_data: GCC_Client_ConnectionData; + gcc_client_create_request: GCC_Client_CreateRequest; + core_header: DataHdr; + core_data: ClientCore; + remainder: bytestring &restofdata &transient; # everything after core_data can be discarded +}; + +type GCC_Client_ConnectionData = record { + key_object_length: uint16; + key_object: uint8[key_object_length]; + connect_data_connect_pdu: uint16; +} &byteorder=bigendian; + +type GCC_Client_CreateRequest = record { + extension_bit: uint8; + privileges: uint8; + numeric_length: uint8; + numeric: uint8; + termination_method: uint8; + number_user_data_sets: uint8; + user_data_value_present: uint8; + h221_nonstandard_length: uint8; + h221_nonstandard_key: RE/Duca/; # &check would be better here, but it is not implemented + user_data_value_length: uint16; +}; + +type ClientCore = record { + version_major: uint16; + version_minor: uint16; + desktop_width: uint16; + desktop_height: uint16; + color_depth: uint16; + sas_sequence: uint16; + keyboard_layout: uint32; + client_build: uint32; + client_name: bytestring &length=32; + keyboard_type: uint32; + keyboard_sub: uint32; + keyboard_function_key: uint32; + ime_file_name: bytestring &length=64; + post_beta_color_depth: uint16; + product_id: uint16; + serial_number: uint32; + high_color_depth: uint16; + supported_color_depth: uint16; + early_capability_flags: uint16; + dig_product_id: bytestring &length=64; +}; + +###################################################################### +# Server MCS +###################################################################### + +type ServerHeader = record { + type_length: padding[3]; # BER encoded long variant, can be safely skipped for now + connect_response_result: ASN1Enumerated; + connect_response_called_id: ASN1Integer; + connect_response_domain_parameters: ASN1SequenceMeta; + domain_parameters_pad: padding[connect_response_domain_parameters.encoding.length]; # skip this data + user_data_length: uint32; # BER encoded OctetString and long variant, can be safely skipped for now + gcc_connection_data: GCC_Server_ConnectionData; + gcc_create_response: GCC_Server_CreateResponse; + core_header: DataHdr; + core_data: padding[core_header.length - 4]; # skip this data + network_header: DataHdr; + net_data: padding[network_header.length - 4]; # skip this data + security_header: DataHdr; + security_data: ServerSecurityData; # there is some issue / bug where the length reported by the security header overruns the end of the packet +}; + +type GCC_Server_ConnectionData = record { + key_object_length: uint16; + key_object: uint8[key_object_length]; + connect_data_connect_pdu: uint8; +} &byteorder=bigendian; + +type GCC_Server_CreateResponse = record { + extension_bit: uint8; + node_id: uint8[2]; + tag_length: uint8; + tag: uint8; + result: uint8; + number_user_data_sets: uint8; + user_data_value_present: uint8; + h221_nonstandard_length: uint8; + h221_nonstandard_key: RE/McDn/; # &check would be better here, but it is not implemented + user_data_value_length: uint16; +}; + +type DataHdr = record { + type: uint16; + length: uint16; +} &byteorder=littleendian; + +type ServerCoreData = record { + version_major: uint16; + version_minor: uint16; + client_requested_protocols: uint32; +}; + +type ServerNetworkData = record { + mcs_channel_id: uint16; + channel_count: uint16; +}; + +type ServerSecurityData = record { + encryption_method: uint32; + encryption_level: uint32; + server_random_length: uint32 &byteorder=littleendian; + server_cert_length: uint32 &byteorder=littleendian; + server_random: bytestring &length=server_random_length; + server_certificate: bytestring &length=server_cert_length-8; # arbitrarily cutting off 8 chars so the certificate doesn't overrun the end of the packet +}; + +###################################################################### +# NTLM Authentication +###################################################################### + +type NTLMAuthentication = record { + type: uint16; + switch: case type of { # there may be further type bytes that need to be added to this switch + 0x0100 -> client_request: NTLMClientRequest; + 0x0300 -> client_request2: NTLMClientRequest; + 0x0103 -> server_response: NTLMServerResponse; + 0x0104 -> server_response2: NTLMServerResponse; + default -> data: bytestring &restofdata &transient; + }; +}; + +###################################################################### +# NTLM Client +###################################################################### + +type NTLMClientRequest = record { + payload_length: uint8; # total payload length + pad1: padding[3]; # arbitrary 3 bytes + remaining_length1: uint8; # remaining length of the payload + pad2: padding[36]; # arbitrary 36 bytes + unknown_length: uint8; # an unknown length value + unknown_value1: padding[unknown_length]; # arbitrary padding for the length value above + pad3: padding[3]; # arbitrary 3 bytes + remainder_length2: uint8; # remaining length of the payload + unknown: uint8; # this unknown field affects the length between here and the beginning of the requested server name + switch: case unknown of { + 0x00 -> case1: uint8[7]; # jump 7 bytes + 0xff -> case2: uint8[12]; # jump 12 bytes + default -> case3: Debug; # debug if an unknown value is seen + }; + server_length: uint8; + server_name: bytestring &length=server_length; + data: bytestring &restofdata &transient; +}; + +###################################################################### +# NTLM Server +###################################################################### + +type NTLMServerResponse = record { + unknown_value1: uint8; # 1 variable byte + unknown_value2: uint8[3]; # 3 bytes that may be static + unknown_value3: uint8; # 1 variable byte + unknown_value4: uint8[2]; # 2 bytes that may be static + unknown_length1: uint8; # an unknown length value + pad1: padding[unknown_length1]; # arbitrary padding for the length value above + unknown_value5: uint8[3]; # 3 bytes that may be static + unknown_value6: uint8; # 1 variable byte + unknown_value7: uint8[3]; # 3 bytes that may be static + unknown_value8: uint8; # 1 variable byte + unknown_value9: uint8[7]; # 7 bytes that may be static + unknown_value10: uint8[16]; # 16 bytes that may be static + unknown_value11: uint8[16]; # 16 bytes that may be static + unknown_value12: uint8; # 1 variable byte + unknown_value13: uint8; # 1 byte that may be static + unknown_value14: uint8; # 1 variable byte + unknown_value15: uint8; # 1 byte that may be static + unknown_value16: uint8; # 1 variable byte + unknown_value17: uint8[6]; # 6 bytes that may be static + server_length: uint8; # length of server name + server_name: bytestring &length=server_length; # server name + data: bytestring &restofdata &transient; +} &byteorder=bigendian; + +###################################################################### +# Debugging +###################################################################### + +type Debug = record { + remainder: bytestring &restofdata; +}; + +###################################################################### +# ASN.1 Encodings +###################################################################### + +type ASN1Encoding = record { + meta: ASN1EncodingMeta; + content: bytestring &length = meta.length; +}; + +type ASN1EncodingMeta = record { + tag: uint8; + len: uint8; + more_len: bytestring &length = long_len ? len & 0x7f : 0; +} &let { + long_len: bool = len & 0x80; + length: uint64 = long_len ? binary_to_int64(more_len) : len & 0x7f; +}; + +type ASN1SequenceMeta = record { + encoding: ASN1EncodingMeta; +}; + +type ASN1Integer = record { + encoding: ASN1Encoding; +}; + +type ASN1OctetString = record { + encoding: ASN1Encoding; +}; + +type ASN1ObjectIdentifier = record { + encoding: ASN1Encoding; +}; + +type ASN1Boolean = record { + encoding: ASN1Encoding; +}; + +type ASN1Enumerated = record { + encoding: ASN1Encoding; +}; + +###################################################################### +# ASN.1 Conversion Functions +###################################################################### + +function binary_to_int64(bs: bytestring): int64 + %{ + int64 rval = 0; + + for ( int i = 0; i < bs.length(); ++i ) + { + uint64 byte = bs[i]; + rval |= byte << (8 * (bs.length() - (i + 1))); + } + + return rval; + %} diff --git a/src/analyzer/protocol/rdp/rdp.pac b/src/analyzer/protocol/rdp/rdp.pac new file mode 100644 index 0000000000..1d0f7f6197 --- /dev/null +++ b/src/analyzer/protocol/rdp/rdp.pac @@ -0,0 +1,26 @@ +%include binpac.pac +%include bro.pac + +%extern{ + #include "events.bif.h" +%} + +analyzer RDP withcontext { + connection: RDP_Conn; + flow: RDP_Flow; +}; + +# Our connection consists of two flows, one in each direction. +connection RDP_Conn(bro_analyzer: BroAnalyzer) { + upflow = RDP_Flow(true); + downflow = RDP_Flow(false); +}; + +%include rdp-protocol.pac + +flow RDP_Flow(is_orig: bool) { + #flowunit = RDP_PDU(is_orig) withcontext(connection, this); + datagram = RDP_PDU(is_orig) withcontext(connection, this); +}; + +%include rdp-analyzer.pac From 2fcddc6441fc202543e6e932fc7e09b92ad855d0 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Sat, 14 Feb 2015 13:31:23 -0800 Subject: [PATCH 060/256] Update init-default.bro Commented out mysql --- scripts/base/init-default.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 2af8f3bc3d..b4f0769737 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -46,7 +46,7 @@ @load base/protocols/http @load base/protocols/irc @load base/protocols/modbus -@load base/protocols/mysql +#@load base/protocols/mysql @load base/protocols/pop3 @load base/protocols/radius @load base/protocols/rdp From d0e2d64cfcec9c8de81e453ac63a184e59989041 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sat, 14 Feb 2015 13:59:59 -0800 Subject: [PATCH 061/256] Add btest for Wireshark sample pcap (native RDP encryption) http://wiki.wireshark.org/RDP --- testing/btest/Traces/rdp/RDP-004.pcap | Bin 0 -> 142910 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/btest/Traces/rdp/RDP-004.pcap diff --git a/testing/btest/Traces/rdp/RDP-004.pcap b/testing/btest/Traces/rdp/RDP-004.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a26dd5637f82d2d4ad3d74b79c84814644c6ea53 GIT binary patch literal 142910 zcmbTe1ymf{wguX_yF+ky4esu4A-E^F1cJM}2X_hX?!gHVT!Xt?fS|wOyxjMadw$0F zzX!W1s;lRkYwcNUR##Os^`$x+6aWtR^>}&$06>6$bn6pK*u6yr2m_a&2LO)|^41Ul zk;3~C01XfW0N4h21ObAOq;jPg-pH`)*lZAl2z(03P!Z1?dxJhbH4p&+py1$#AYfpi zARyqNUx0|Jum3@NL43jb2lpSuJ6!<41M-6U8SNPrfe(U^Tkj+oh#KjQDhQA@ct(V% z1tJ1|A?5%P*?|$C$A5988VG*j2>%DiNFZv6BJ$Je2oC`8%nOzi05AapJdgiE(HIDM zMj=`HR}}20Q*J{501NKj(_-PXC1->mT&efb`md zmHjq?{SV6F-%$)+P+0yI1swqRx&;9A0!!rq3jG%)PUt*mghTtEjEE5Uk|?mNpX>Up zL|v=jmH3PZxBh<+|ICi<&iF-%r2mH(5$@S32N1R9S&67Gi2tj^XGC=%;{Ur6C(@od zV&DA1u?C3B`K-h^iGMOx-Gu&&5+~AMPzL@L1*k-T&HpDQJ{RbjI#dtL-;`+bGD&!U z6oV63jP++FTHpVsL{Oj-e*s7I!2s5QdVd~&?pGjF6ARDTU?KjI%{s6qGC<%1hoEO* zkW$c7Z!Z&HkSuWEP7eZnJTc*bf{=iMfP#VmfUV_!o`Dk$T=o1CaLs>yUN!&)CwhMA z73lLep!ZlWzyEk6xG#tR00MyS4gm3C2d01w0O+F}6!;s9lU0zd*l4^RaDmIsKwU@?GYym7F2uSsL{Mpn%T<%PtrBt=_hm>TJC~zYcu^-8-lU`3POY zeL=*4{Sr94Ot>%84YZM$+5G1j4DfUVoK)bn5&qA#(V#oQf`B|vo1BrTwGT81Jp9YF zJ#z+wM+O{#fddY~j=+w=PQXCn4*}2Z64+W=Y_>XCQ%>*FXSq%J6%=EZRO01v=I8D}fTT zfs=1W7LO}6Ba&CYJs~@}F)Xu0jFfFFu~g!P(_!1Shrq?VyP(6A4P3E0|8%T+hI@WM z10(_B%^)}lt~-T?kl?EtSxRal=rD8mKdpbz)w`}d38yDCOWpOoMTdW<5a2gaJRb`? z&8GtX>09xcZn|N8zd0NH_VgJ%VC$V1Iirw!!B5ow^*;yKJM@)j2d#MyW za9Y5D1%5%aDS`#?1JR$ypSw1IX%hPd(eV$&lwXLjoDpO2ni#(z=dxO?|+ zt@f-Cm}oh0{{SZg`VLUCNI;6fx&tBq0ZmSZ{~OJeXPQ{Yf6y!k(yRy4jE1=Ujpo5K z&1r9hztMdELKF9oO4b8uHY;L3+%V|=PV)fl1vJYS;cqnOUuahRL9-c1vlmD+9AfD= znupIcZH*ECM$_VjCe9x;dx13jfHV*36n>|92=)TXW%{?n-YLu%n)ZLt>;uxA0@4hD z`0^Xgqdp)_GoTRuGU=8tG_n7nIR&IS0i?M~BltVbBd`}xCZNp<1C{hV{%Z$hn^JnA z$?*rx2_Vf4Ak6@XlHX_^Khq>w{wqzZ7n)dq(A)shTn5sdqGJA?<}ug{=;g{^X@)-2 z#C-gN<}#4xIgq9gMBHyQPo8NSw1WJtn$|BgG5?@>4y3scq&YxA@;l8Fuouu?K2ShB zu#nH=zp5EHwemt!;}4qqxM$}eK$;#7F)yIH!2Qw~xLY3BDuMt_K@tcRW}c?jFo3K1 zLC;Vh@GhbJV{?N#sq~0RmBF#S!1Oh56fy^1bfzPhzZs*wM%1Vv0q}i*9UX zKL-1bT|=uEugRoCDKGmOTm8IYRi`{P1Rg5gXUWn(^atJDz*j%awZJ%7!Ec^1oAT&0 z+7^wCX>ZG?)IVtwi4bg#R9E?8XbP*1SeevWIz)C1-d&yS8+*+@Da{O*4Pv_|UuBT$ zjLk<~iNH&{5B^Ny@5#EQON1bD%yY6ub5mPvJ7n2mK9nLAw_a6e%J}|$u=0~)=>7Vt zPhqH6TLq1g`3-rlp zj6bG`W93$QxC%~Ays`A8);|R(3%yH5W!hG(_<%NcDTvaEx5gPdKD*(S>E;H&h0vQ1 zZ0lvY;|?)X0IR>IRxszG1ns5k?n;5BTkeU2HCA*E@Rq~;c1U(5U-zO~Zm_>OoXv}B z$$nSuIY<)4s}4ovyNej$f&DW|0zVi)A2@5zJ-xG1&wi#0C58ah13ix>a{Gy>)JJpPOaQhaCk z9IqTU^3_Ca~c@fNZs$wwfdLRKE9!(`%>cE_1@-m zfgRG&_MI;)rO3|wCJQ%9-(z?}-z%Z7uJ9M6#Q8{WL9blY?W4P=aMLq4$VXO|;55Ku zxm*r?go1ty1~QO)|Cna~xZ#8+28P#PRAA1jvq!D+Q?bIY`pqI`2)gtsBB+3J(UOjG z1^K>Lyo9}4mPV+_#j1ErpiYc60-OSNf&^W}+yWvSc8GYChX%grLnTc?mkguFIAN}i zm49@GLAds1!=T$PNiVv0A}fNJ=2%E}ZWRzs>z>qV>sZuIu3lQ2MI`y3pF7Uoq8n6=fw4xL8G z$7+d2Zu|rZQx(`d0h=EP7jt>nAEIn9=v!UJZcb$xF|||*6W<91h9VIR(O8Jcjq$_( z6yHs%12D;W>YxzqDJj{}4MM}2>u%AuMjcxi7=zqgK8 z9k^!~Wxx-osNs44sIO}W44?>XY|rD*1_UZRP56w0{`Ox{u%A$quAbEZiu<1i&tvAkY00e#h~7jqQ^Jzh=Bo@R7YYCX)HA!35sj(ROsZ6g>+4_57p+_IC`_Mv%**X&ei^ zgHG#6m7>ok5Za*O>YoCcVlIT$;bYlLkw&b+`eVs_XlV^N+jlQervuy zr6>rz0IyF17YDbTzUHNE~bwG;_e29W+tO72cGyD^Y zx!gl!$Ogwpqz~T_Qf^mdF#}Vr`&Tw5UrTtYYCXY{a?XXR(F5tOxi z_oalNfoz6@57*&;?-WwQ~>36oGa$Q%ZR92c)ft&mAOSP8ZZ7_8@e9k;pPEpDJ&&?P<4>YFI zc||49D&^P%1DFCO@jU+27eI5G=tZTXzw3)&{zaugeenT5X9Ew8nf{|M5-K1}Ie~B% z9u)@cBHvKetVlDAnP(bI(#8SGnImqKz~pn(IbhWHz%8H0e?`@vCVq)3@OxB3m|sx= zUN2GE{u7k~8VHkEymsFpap_87vwkp!C5-IP7vT?54qeZ!d?&r_Fyt&|_#9bo|F4lr zULy1V5t;8-!{b*0=Wc{eCG7NGtR>eJ8#{co;T+rD#GGgal<&Mp4H2b7Tw@ z@V`}>^d+*;ACc{TMYh8Kv(nEw5Ae?F=T<$ru?Cna==&@HdPDfq2U|-Y)sztk$fKU4 z_ELfaNFV?&5PFUZ5%Hf&2Y5mQhv7E)nV@tCkVgQYGzu1Y69WNrFPKvVdnx_O4p4E@()wqZQ(N8_FQKLdHdPhYDj+ znm_E&XA`0x^WAED96oFM{Ra%*lnGTxIp9LhC0>sWY-X=J=mUP>Dc&03ljj zu3l)>qLMt@VXeSq0=i!0C;t2;Qe!j4Eb8*Nr=ONIklrYnQT8zSUoVmm($w6|nt1g2 z%@U8u%1`gf@hnh}tGNhAPU^jQ;9Y0DDU_Yw=N>J*J?6b$r4P4cOW#oS(8xJf$R=Uo zLYC-a5fzL`Xd72GUCmY@a{#HtHM!$%%h^3HY^$Q1AxsOvm-R#HDWZe%$;R32-2*HO z`g@|#6Mt2Mr!Q&D%iNhbg^P2A-~!qCC|Wy2LNHl9st&`{W^KqL5A7@+aC=s43;rsE z1Odu8a9%{&=3~<=Et^6Uf>ewUZlL0%>s#mUVDJ4T7%PIA_;A>hM^wAFmO^b~k5$#*+9o3DJy{&Ab^;=d%DpKs}lL|>pdlya5=PrbZ9)PYrY`{R*5M8qN?pfkRTqYPh8 z7|a+!JO3d}qz{tH_F$1{Qy;I_LPFmqI0}0(JZI3>{;FyfY{P{TiCsKT=2Og2>q$pQ z=X(sO{>o6zDmp-g!5J*CH@)mgO6O(ck-B^+aFi?i>u z53wJ9;NnWWv4!2nUATbifzG5i+4<^@T4xECOiLacA!T+HZ{PkI#paZ;bO+O=yuf&_ z=r}$*l<1YlEdr^!h=@=dx)G0XtiVIN1d$QrH)Ls{mZo4T12IN)l09(Mer#P->{6%n zIeQq()v$s#tTGTYX#~?i)@k(~D4xlt1HynzdkfLdMr5VNLv{^1G8^cjry#M4@XOk8 z*A1_rj#O0F$q&LxUZ~oRC*kju?nqnQ9rNrvhC-IDuPIbOMG#?-T{Qa{-p!R`O|*L@m^^>%;k_&$<3ik`TIHzY#B;|?rUC~5+x*M; zvtt4Vr^%l?CdTOR9g{5LSDzNh0(MO5XxYrrC5r97{T1#$swVP>P_eLF{>7EhYxD4j zVxMAEq6-vGO}K-)&u_;;enLC3!eS1kG+NR_&ARnV8BiBX>hvfZH~RLx-cimBWZF&% z?!ntQd^`S~$`BUEa!&Nfty1)G!;7`+Rei_zEt&Rkxvg)RU*?+gH72;w@HKtkcgenU zS)evLq`*_%qP0)#&}R7zUDA}2WYPSH!NTqG^*K!{>c1KT#fvfc{+=c|!!Kjt!v0rd zFgIQd^!JV+#J3E@qct06sj7CzhYGftRrbff$d;?%)6!-Apx8sg=K$twb+Ap!l^&UJ z1lthtMvQas#$qVxyh*BfiBhFc_^vfy|D!?~vZp=x6P+l|+?OEbQS_6pdXZZjxFcxB z*&|xNJo!zZtCq>dp&eqOgV=et56&vp_|3gf47IKtL;-^xw|I5? ztAgNDhNCR?PG&qE*>!CCJYMv!&Lb2vTr;lZPB=~K=9wCXL4VUu4jWDJPH^-+CGqHv zg@7UfKE|$tI+Uc_vcvDNKXoQ|B)^-9QJeJ3LodKCtlDAQtw6k~)@1jR{rH(~S(Z<& zfrhEph}NS3p}%t3jrTZWX}``x1d%y^A(gg-Q3wZn8oVejpDeao^xiBuV5!}&#Mrqqb@n^8F*=Tzuy%C$l1DUlG47aNW|Fzs;MR}yDIg*kV}AP zaAR}v6-r_757E6smDP|sH7?DV9d1Zhuz-mK^gBZkK^8|t778;QW@`Jng*Bh^@F_P~ zPVhSpL{BP(iHmADaP-D`X6qV0Ww7MyM`R5&M$NA~fcHmF73itC_*y}81P_B?*sE?I z{UWjOv_}}SV2p>F!ccO?cFiV1F7|hk9-?UqOK0FZsWe6qXd+5H((MV_6R$NNdk$dd zQA=A~CyKsr1}II~a>RZ$eHZbmHCZ$z)Ty6Y~pl z=lCgIt-@FCcd0v+`&D8aGU7&nDT=8Tqun6HB6h0~SXDAwi^9*k3O}y=b>V|#%LBx% zK6ni+4oPqF4>VbFl|Qo1zl~@S^o2tq;Im#IW_E^ z*n{F79mDVwL5S&cB^$i(R zPtP559@sJeVhofo#_;v`j!A?2%NVSt007L!y3W&gF=wdN90l(>`Ddsz@r_0H@mJks z@C6o*S|LGhC^Jd;`;RixyJy-%j0U6C+G0{PY=g`wbQ%t<<8p5S~US5V}Lvc0B*<49Z1{;M{_nBIPnX;lfvzmw` zIu1WQ4sCR!aAo2nZ1pc^9NxWNiJBMdY8O|eBvea&PE(KOuf{<2VhrAYq}lSz7$#Z% z)fnnb?pKKJ#QfQr20!tjS`>bGht`akAne19@)X|1VDGKVE_8M}FGbJ%ahNo>8K1}c zX!&XqW$)Vjpn+33AFXSJ;_?PGC2N9nVu5CF3K0tm+iKEQRAGO|5}yx@ed5D*U65)Y zi3wX@N=b4hi5cSNH>?{=7pfP!^jgip->IBii7(2ygM;?gm>R ziimo;@UU1iC7)4?BLLpJzNYh1AENQ_{wQUGinxI(+@nL+i)mfF1{*{I^=gldE})T{ zFnDpVppN%sV(>#-fT7GcZJnq)scedfFEmGh7UR|h@Nay3Qp(c3>DJJz^V%m+6z&!k zq4TI$tuQP(q|wW4+i?a|Zgy%~Jyt{?oQ_jMsLC9TH<7;TthPodpuH^ zN&Cddxd=N1fflM z@UnEFj~Caz((*aWvJJl~$j-|X9tbKqe!XkmM;kUXL$_(sImnX6+B_S-?4tX)?l{O^ zT?Pv({{0qZf+^7wSAhJs$o{R+HnK)&R?}=$m-`H)4evF0F%dhcos4SejXjbf#k}9` zsT=mBW^4~^u=jXWg0n7nhkTCl8b;b1|Avb08B9P$PlMQ!S_TH%wjaCi?dYAeYygIS z_Cfkex1A~Y;_SYX>pO$R{f*D86r#wm)}Gz^oRheIf{uJ3W-WDqs?o^XvA*rEG1t{& z0@NJ_X`9LrTbK+452upYkGTCtDKf>^-MJjv9-rT!&{1KEZcFnP{y4RG> zbK34_^|@$&fvk*;SxYyiweexgOj-VPXry0{f zdP9H@p`P7Jh&q&qmw9DT++CK|5U)KJiog=wMr*H5y9UMeZ>*)H-B&;KCd`F>X(zF8 zR#PbO2y4mAZN+mJl5@ox+Fg=Y*)w!YB`x6=D5UQsXMUqCcN4CoY5v-ZXRvk(;E>OX zH@SMHO>c5fhN8Kw0V1-seB4BEz5hnO#d@?WF3vWHE4 zcWh{{v(giK|1YbAmeHXEm#;iNy=vO0b?(Jq_PL6DN7`V1eSN_npkeAaYE%i1k^+{05|7R^_%HRjj*~u@c2k-+14` zzMppK8;7{e@Qa2pS_Su+x^)p_7>yrnzN2_VY!x!g+Mw_o6c8peOk2N^#b3pbO!lPg zkk)_hm;lxF&6$ZhIh#TfNQQQeNH2^Xk7)m53lCJEVq)ggcQ3^ zT#Nmdr<=sU%{OpflpK=9vKV2iT6fs$J(j3%lf6q&OINv1c^Rk9-`so4z*`h$w#al) zCj;&#O59(kT5Vm*-!dEra`46vX9dmQ8^k>^A|&cbY5C5P1^?JF;OM*HA@Xm!%< ze?}pxiuX>;W^**NE{}5}+E0Vmu z;I*)SPH1a9{i`tyhG1gO$bwsH>cmWtFGmk33Ris(_!c%^K)6E>!6bzqKA}{0(-X@L zxO6;z8#B*@kEh0s_$k3TwX8Q7pvu^^lcIG^rC!*X&$y)_Ph)1=GJL79^b}*>Th=w- z7pN5#(>9DyI1~FIAD0SY+;k)u$V84kCwuS$J9{E*NkH)9$5l@j+fwFiFmoRn^<%k|>ZrZHJdbs=}u05a&^waBGFdVm5 ztncMnS8v3rF2uu3m(1^f#*Mb^I>*O~7!c0xPpjZkQ1fk89&1fKMU16sdyuG=N_m$) zZ6r*M%5x{7P<}Ng^eJ1#R$KCdoN*y|BMu@7dPI1hrdbQ!ZyAa^bzS~#QtdlzhNu(X z?N4|U?OQWccyk$uHh(_l_Y~nY41zd6ypL zuNBbs3HNx zg|K2Rl&R8^z0pJ?=B^Y4NO*)*?$Y{0^$ItZbxW^;DFWqGxCN9)$P_>sMtre!zc+F` zu66p`X|4Ap-BiSB-DZ)6Zep#RG|x=nwndGQr4G9U@y*fgB%sw(RC>oK)AGrmgc-7av{8Ru4OvO(Sz7MU zR?OOtWO>P~RQBPxu|fchlCjR{@h*7;x(&(>0F~mnX(PwHWfDi^xp?r|SrT(&tW+4m zqTe$%ah6WubMY{L$(i?EKCzzhgr7_w>d$phswxcQYsOs$iLK5R#AXk1>ZX9!M*W)h z!@Fse zQ@Hhh6ogR!cn#i}3GwFI6t$ISBI4DmyJk$dwTPt9W-7dH@*WtzS-ST8o-}jCWBZ(% z_xJ1jZEVMy!nv>kNC|D1DpM)hf5A=`qpjxX| z5W!98Qc%Z{=p{Z*wW#RmFFblqjar3GRH-~XDj2=Fs$H;iM-;#&Gha+MEOAEjX|6TZ zha(u&h2ngte&|FT;QzF+yLlZ2sZ$##z`pYFbcgXuo>^n+^aeM95~ofpsTXgr6jAoN ztl9p!QH9dztNtFL0EK*wcE+M(Rac&1z8>72P+HC5@OV4D;`=xGU-Tp?CK(Ggz{klP-??`P)P36>X(;XF#Hy-IAbucSlPjeZTYumam`UB$G+*Z~d7A=CF`g~W zg;5`MO}+nZIaxns)F{nZ#~UyR|8J4;`){W6AH;HjiSCdv+h@Ndd|?>P9f9k6K? zK#8@Rki5Cm0dIBIBzVBQJiosQCa|y)V^fZ{jT>-YX)N$?9L=yG26v3hG4s#cCJ9$q zP!7$FVZlh+k6?t)C4CIv6xqzjG+#5E0koni@5r$2PYm+ZQjWn{?hdG~`+1maVTwY& zW#LBK-DJs}q-E;opO@j7AlVx`f|k>& zk{le*D)MDom);6I1aBjmL#rsYjNBH!GtSCRqUBja0%&@@>(a3R;ABBj2=GlYpAQ&G zCfFNJpT2g#Pk@04>we4c8$9b_s^PN8J{D3UW4?rrr$9Ue;?G>L=Me)z7hV2RAeA0UZ4}Rz6j`q*M6n z`pJ&ckvV5JN;kP;W+bsSm;E?!yG;T2IVHDk&J^2-YMRgthZsLC-JC`pSL#FBzYjH; zWFS<-F#endNyW`_?&pC8k8bTPpYrGzLx`&#m6SJa$!JgdBJTVNZoP4Htx?n3T(XKZ zFnFS^X81|943zZA_6(qbx7sgQ&Sp*XjxKdbpN{K$B z*OuG;{9y3M`Zv3nBQbbVsqLnrFf1z~FLKo0C5|2l9ni9&K&^g?FrT%2vQ5HkRu~2v z2H&|?t@DPPdQ9|R3MT4WS%!9S8M6JoU&}LiPH?tbDSD;+l+0iae5j2Hs5S@Qo*_9i zL2+^SRHoBq^E!{UDdtP$LV8}huM#xapH4_Aw0sU{Lr4*;@Qd)-Os$rYOSmN%A|#bk7=Y} zC%QX9uMS2NrK0VH$)LgLWW>)+B6X)ffM7VA*|(UHSXl=YmQtUMQ^|uWvg+r3SC@Oh zXIqM^JB@{kiMD}Wo-R@MiT}d#Hk%%9y;m`e$J){7+BqVB&)Bt9QaEO|&bV0UN-Cg( zx41Pa>}x{{YdkHivW8Lm-uXo~Sexvp?rW~4U>cg0MC-3>ZK5CE&NvtKD=NF-rbqXM z$u;FNC+?aE5IdjRd?kfG$MSw~c94AwxO_s0GfqyqMN_kIhI9!x3(vN0oNqUw#4z8H zPiTv8BL3V!%(e|FE{QoP)76P~6PM^}yTW(QB^~4?MS;RMg3vr`dlqRZPa^on~rnD^i3uor`6W*#!9Q+Gz4d zfxMs*uTs?M!|O)$Fc|X9E$^S_)1L%s?4)I1^Z046_-*y2M#u5=^BM>do*LXNbH9N~ zI%j5dNZA!RmZ5inGV)<|G(is*9@(yWvLx{x-*Zu$IxiuNJ;RVA$5SVCAb<3dfkIZH zuK$LW&;5{*+pt#JeqJox#%<6CLJZ6M4MGa?^8uuo(oAGFRf3Vac_%`R)8Ko6Hm)M5 zYNWtufE{ZqecOZg{)UklLW#ajPV*g1V*IOPY~n{^SK-(mJ-eehJcJ}CNs_*r(VY9# zW(|Z-3*Nb_qnr=n-b^^=S`qmEOpc?v7`<>l+aYB3b7GIBS3=)ZMVOvWD`%3q_TpBv zw>C7qlN7R6awG6- z{v~yHKt5YLG%-U3xE^*;-){jD7vQUgc1rbKsn)J?vzh;*y=#?5k)ne zx2LbZEsOak{PJy9Q~y`5_eAP|S`tvKt_+`OoCOY_)=5>kF6PoD2>r;6RLd=-p`YqJ z142EQu8PJ^cu1W5Fbu6*vgr-MID8n!gNpkhr4Y&69G`f5R>WF;wsGL$uhEI99_{8 zL!Xul$-TLrRw#)MNPt-hNCH^Y1?RIThEPeZ=_uUoak>ecjK27B4xggLe!Eip`pIKz zv(i|~%U<{_yom{n3i4GTObTj>6s;)Xa^{b`*zq^ zVmJ;3eViqKh8kEN(IRh7#cMjgV||rr7W5I9zCsndHg3x?M5}F^CSiM#p&6DPE1{AH zQfSUz7)gahh;dltR3W7T9@(Pd-Pg0*NTMHeE}x~|WBKR8^N0GPJwfof8WnYg@c3cn zd8o|vzSX@uDzgr*%D#UMt>5GytP`AvbqeOq z{J467DIqItCz&~r!EI*A$&Py$0>cmd1E;IGB!xTH);Mw=uX3^md1pDUkoggV zs2KlxybD!KkvQd17qz)7i3wRq7(K|<*2T61nkN|I2Rws|#@TUgTKk1Hp0JUASe^b( zRT#e_DB2XV3)6P9;!5YY=tVMrOv3%xhGLad{b`tUuP7=V-!}qnm24{HF&2!IC1%=1QB83%yl}6Zk+HQBVp8WKXwg3VyE@Qiw z%0rh^gKBQU7?eoLsGB&>dmxIP{ccdVO^ z3_e3!HQ`~%$=|7#gSv6!Gm82waqM{1&qmTQvJ{ZwVU*Tnchb=y6t0U;Xl@pIJBD3N zyE4s3DmQZQW?9?Ltln&>M|%Jt4XsCcV>Q)%OSDi-sc&kATB8$+c@|XQ8RrA-W!j^n zPsO!n>$Ga*ATvB8%<&bKqna$j^;a0*wM;>ibQ7RHQe*c`O)apAdRyK@WkBj};84r< zeBAi~+FkS%S6fb!d9Yn15rYhw2oaoACR=^?uGit3a0`@)12m z*BoSMYw7qnd&mewdWM6AQz8FK#?;TT6{+BWE3jzQd$iyUUWCY@9 z@7r!Eox81>f2yBxGHJ+9(a4WR4+Ol?DoSSfvTZ^$!>hN?4&nLM>)PZg9SD@xug%<+)*Ee49xgt+HFp!&6h)M9OdzMCqOcxfuQ2Y08ZhD6u^WqW>+}eI z@QF@L(o6N02JQDT=&4Smml153k$k_f5j$8lt{0jbgc)Ks8^MEm*;kNm7(imDJz{o+ zPZxU$hkKiR=}LynIP9n?M8Y_Az0i><8;2@i{px*q_1F&vtn7gyG=e6p@yHv8n_%P` z@DG_|>|7}`PByiTl}ZV)beFrO*tk_Z$%NdiKDtgp?2hlP`_M;@hl%F0$^x?OQZ<`aCf2n~_7E{ML=P6kCnoJAxg?I@C}Aa&~bt{YOv1sJ?c5w*CF#oGsVN`WK`lI z&q`d9V|jGh{0ZSjUltn!(=C6Q_aHQ(GK0*3Aggw^j85+%(kg@5As-qWHx0V)dp&r~ z$aYp=zDWVj`j%`=^J>cGYxkhi%4UU~w5!N;aW;nB`^wTt(2hlcfp-}UTljJQJsaWPypm+c$n5VcdAdrE=>L=IC=0tc6;^yQzhCyMjZ|kEU|!k7Sj1 zCKEH-0jj}eaBEZY!y(SGJiN~C3ts&CyogV>VNh9#nB4^s^H{D$Bu0>ZRau8!k0Wbw zs{1v)p>st_`Me%k3DKi11H0RO(*=4=8-Y-0Sxlp`XM-U71cGCxO%$%m)SdW0spkPH zMcKr94{}0}QtqUy9d`&-5rQ02tMd6#5nBr!ecUjwH|n$ssBtrFpp1q4zmB3ulh(e~O=1x3(A;?u6Ia3%MbVOwo@ou_+kk5kd! z1)6zl+jks8@v8rPB85ko{p)O6_YTOZVrh)d{ko4o{J;@3!Uy+x$~2VOa{X_{m~1J0 zA+Ofnm|tt%l@wBhlE5}s+p)FZ&K*(0PraYz{EHf|q;IMuR))1VMDRID z9=_7&OxBibADAe+A=G?q)n3O$M0p$EW2|w3Wca3At`B)WGdnMylNwx8Oeo*@N$*;F zAqqoLrRbh$=Sj=(yg?YGBsT~?mjy1}HYOj862Eaefuy6x_sN1OZ2Sj(tt%sD3x*r| z$UsMhLvkm{*=<`e#pfu<;$kB%1P7JiWvKoyj;oBXjrR6sJ=DhUZr?$SVY77Eg71C0 z*Vui>Cm=#v9g@+1n|EIb2@-ttVa=`n+N#V9u0-WTp#1TYXeVGk@GD*T&v~&#O?4%+h@TI!X1>~bsTL~2D?$xt}v!C902z=`euWX5> zW8M-7!Ip!GK?pqI_x^5ECEGvT!OwuPK_%c$kz4PHP5z!_T~8k@A46a2LzTT*Ti5s% zS5pL{RhwocQfcbulvr7iFu8kGVN+>?^2K-U(Y1rKK1g1*eA|-W34?x&53yy=(m+%i zl|tDG`W%J##qEuy2Bv4qiPd?hug);z@)k+^s0SOiIe$ZtxISV>wiqEUb2l?kcDaVZ zfm1n6E#imhwp7W#>>4zmb7T<^Cn;XH*zAh$NtF!|OsqLWwVZ)XWw+BOz1;2=Px1f4 zIPAZP`5roMAd`R`CLpP9DJH&MAszfXmdJ5@hX$kj!n6oRP^|4w8`9w%vh~+tDP*7A zPOD; z{dV%spyCMU84n)5$A-00r;RGE-(l>G(k$aVt=rHui1D+vo|f%?5uYwW5QsXH4^xZlL6w|=>jpK`L6zw_^xBckE@@3T;GevY* z^#bbF*kx$LA`X(DO|g3FLBj@XouwTZbO2vqG@3UjX?u$}Pi_xL9(Hp$di(-kMXq-i5D6`Oa#b4rT6Vn3vAwyAdrGg(q-bg0$I& zZRDz+)BM2vS7Ts%F@`_B`!4&>H%5TpV_+!!S7V?a*6|*v?#vh`P>L8VIR64^ncnz4 z&h?#tL%v&^s^}ecpOT`(3W{;d2)xEp=Z2XK@sFQ=Z}V%UN~LDIc%iaX#6yb9dR|pu z>FKXM-Ye=ZbS*C+bc9Bh8aIN|pEhtyNrZ%?uV&$t7T*6L29q*|hL*s3{-CTjd`$O0aOU&FZetnRcoSWAuF>?;XheqC%)ArajqR+}&qZxEuh2q#(# zPEpp+Wj5z`eFu-`3t|Dj1&F5XD{pC2`~qbcR_mm(9cU|6H9Xf*F(DZfm!P~qOCODbHhpsL$XKdotL^7FRQQliwxhs~ zrSCS1mr+l!smOz9dRv}(MQADe%U21?K10*fjflDtW!Z?-2`R_7A`bz_ud|s_}Swl`x)LO zF6regAmu9uP^Nj5uPMawm_|p7YRuuI_4(qkN2#AgR?v~zXMWPz9dwxyg)FWoR((Y0 zJ-dP{?fRt3MJrcNoc;#80Fw24Q`eQ(w7E?695;v0Tap0Tie)}`I^yd_!G+I9+%R~V z;VE_c>F;>4b@^x=uhlvw(K)p?@l+y281M}%z*N1ihHG+Lm$Rwf)hCsha4OT2TZxTN zHjj!-s?aH>HMJ9av2KlmoAO5%S!*o&Tg3^5!%#0a2Xrk4AtpW;9VXX%%MLWScQmDk zlZ=tiS!^+kq)N!Im3H#b@e5UaV8^co-g04gm2V}wi|fx}@@ed3u|}IZ$pVKbx_$Nu zsU(D7;|_#H0Ax|cW;8t{Je`NRwur*rS9k?%l3vG_WMzgR14!8`zS_>xDQ=oV)QM2)4}h#V`8xU)fisC7(@H-#-RA)mocdC z007Ea_Kvtt9%{v7^GU&7(UbRD-Yfjf4yLZKI?TXMp5q2v&E~+yDv-!uynH&eXfA=@ zv2nHw6CQ4<{>V3_b>v8)RV^~#i-P8bh=(gdkY3pAj_X3U5>eQp2D@8ARTdF~E@yE6 zN%=IW{lWY8L0v2y0kq)0mPRJu3!xCHTTNik8nhN2fu?Q#UV~$DO-LeB*iV+lzj=`H zOu!UBcL(h`%_Lx&f4TU~{$dP&{Obs%#9yBnlnwsX7-pm;)2E&_erGmG8&>Zp_Jmz$0V}EY)lC3Cp9-1ozl(NP0@7G4DGIT-aS?o{2EIsq5SG50uTbN%v8N$_ba4+2^(d(w7hqd{B>!=Zzb&LZOMo{ z#atUSYBpA|t1irDdN!nX>Xa=HWhlSAiodS$l&0uScZ~Cu;&{dUpx3*>_w_P>`$>XJ z*=aRz$C6iw{5~kZ5`w*X_TDifGOD{)n4D}`u`jrpw5{^4--NEAigdHsBxM}EdHvM& z@z`@w+*u4Y&Jd-IMd^(7>vDg$j^>6Kv!XlPktNf?2{rD}e7(c4*E=YPPwtaR~+*-RzJcH^b6&8jX@)3={$aOWp%Rn5L;Yo zQX1bdUxv@*GB9kDWR5;uzQZkJuXqut!6XHK1{7r)5Dv}9UL_5N^UZJYma&~*?SaRT zT67|88AqmPEIapw+b~A_KYX2KSX@i6u5ot{9w4~81^3_(B)GdvkPw2qy9OsfaCdii zcXxNY13CMivy=VgNB@1RR!z@WH9ftmXr48L@r=7GT(7=)ii{h!Gm=K8k<;3|;X4?H z#n}~b;FvEy*ppDaGrLRs7$j@W0rr7=t&ONrxH|AIz;Gea^F7Q`yRVHdUjrvZH|4`= z_H%?)w@{0I2%~qHiCa_iCz`x@P0!|X!HygYO^5DYl{u||W}__Jk04!LQr#CzlUpIT zKGbDaqm$Ia6dB1Rjul*IRo897Znn9~;c%_V*rqd<(-|>loYY#9L4_xJ$u{h6ih@_Y zZ{+73{hng(Z-b;{`y-qWSc7H+M7Ans=^Pf{YBNlpt3Vxm6ugW_XF^+nJ8UtpD2!dW z#x@Ffp6UnfS^Y*oU;4;X!<+jBzkI@UbyXKy=_wTLe&qusF3`yHhpuQX_)6FtCgRz^ zQ1ct4A#IPS3Kic3YDV_cj3f5ZME+WN;Ul6P-@JhqQ2)4fAgV(vKJq7;V3Y16Kr)cYSif{e?lmTMh!uL$owjWseR@xge?MXB zhhR<#ol&{K0MlmLPpF^QRoQ35I)_#gd7RHiXUF2V*nOA2jK<6L5jN5J?v`mWs1E4B zH+^=pc@K$A2Tltuc+k50hDZTRY9rAwtC?(@lNb>**4_AKH^|fG3oAvV%tb#W7csXp zPkcX$#L#s?u4kO5XXO$}kWHZ+UtMR;TVm|~g+rPWJuQZ%_(8;K2_S}HH_FJX zeux{+GBHqF{X0r=VF4F7vM(W*x~REOVVZ~k?*LU%Y@OGBr?VC`@8s~*^r1-Od{tM3mDZlzJ zTmmS6NiXcL>Bair!BQsvC%t5x{%3lrNPMGZu6k8nzw6Q&WVOLw7-RL&epP!1Wl~oiHdU zjU}|{)5RAN?<4>->~9A4{B6Twe(4;_H4p=F{p>u@Q7Mm`Cd^Me;99%Ro3dnj{yC!-u!I7EvQ-E830$_Su`tlLF8Q2pH#)5Q+Tb0?ZF zED+TXgiX?e+(b@Y2X+Zxd~?N;8dh5WOjnp?gX9kZwO@*{7i5^xf$v}Uc@lxNYsFU^ zOy+ClxBAP$YC;mTVFzBJ*Ox?NhCJN)Z7m#4MScmhzR(Sru!4;ji78! z{1D#<``K;wqjE{^hMJeDx>B%x8}*y4B7=WL>euBk>cIg>AzMaOHtgH)scLJb1#g=^ ztyt=|MUSF0is&56_+-bb!gmSBPb!nu3^*yP#3N|&mHr3uU3&OIpXt-OvW zB4)uX9nCuYTdA_pWicj}y|}NT@NT4F2)r;?25A%c?YXy;Ud2gYopS}()LP&TwpA0b z7O#NU`~xIA@FVQ0Vr-=_b*6`RQf|&zvA_bEt!3Wv!W%;iuc=Tb%$a#WWO(TzOyzIl zZtkskG)Iuy)RJ+4#pFGA?I3V&-_JJ8N_>fD>k=05yWwpE{9w*aTu8hZ4+WYLW@f<~ zH;mBUS30^HL#jL|pMk0$=nwhm=_*+$Ty(1H@GvMkv()Akd4>c})o(h2EY1TK@8>2B z^S$qTlml!@ORO)8D8ybAKE9-LB;BRRh}n8lMibKb7^K-8^$RaG`#5 z0fk6APB;Xw`CtSly3jGXXTms5!0bnb9Z*=azWGywOj8MTFNw$_e7NbpPVTWY;a1Wq zxUKx!YAmF%!x|!Lf>&wf^r?Z$3D^J|9x^A;5Vq^_tLun*FhAiD>zYaDl4jyL9gXvo z#2feiy3Z`<7kdF5O*j)#7pxOL~@cnv*&0-(K zNcao?85w1*#~)gt0`FS<)N_<#Cb{N7hk<=*bKU((5c>MqvvGdawQ zV!n11`PDCp2nq@WR0>m6#={Q`Lv^6$l9_nu+ZB|k&SQ_l5WfMaj;h~_)x;sN|LrL9 zyH)jj`&X;`zgb;;ReOL{{@qurFC9gGStWh3`usf%UP_mp8%x{9ngoOseZ=!4lm&im zv}VZZ!7yI%u2lYuVJ{TQ zmH$Ke-GB0Xhu3U{|8M^16y;(X0kmjBLH|KkhR(=8GM z5Kv!6&e*XF?gQ}A`;ED9$+UY3M9b)ad35V#ga}5Bt^kX=cR$GT4Ht@wG+Yl`@Xf7; z1CY--V-py71|u^I^7v06L2&K^nc{!MG_y0tH6=(BijU5Q>qW|>sF^$u{mmrd?MQ7h?m zrW#bYM|!&ak9H*81J-wD$Tl@z9q4)b-%n;~Mfx;0gZ6h>f&)6A(islYVX$muD;<*% z+}vV1WWl#DOEWgN3daQ=eUSDXt~gzCYYAxna_D`nqm8H+3Bfa5 zLv}Pa;S`q6vde1n0Y4MHoFa0Mct;VwA6=Ce=&3JPi{wRSp-bZxYC$qnNhaUmvB!QH zKvAzG9CTQ#V#s!funRV(#L(~5-C(K?vg@=Hck`l?IbD=F)`r*0} zG`Ddz^Q&kp|HicR7h6gm-C6+xTZg2;b$SS+i?wX%#EP)|u4^HLZ2a4{Eu2c=vwpsb zILBayk0j&w5oIp#C_}mWdadiR!@sV*>x3?xb@?>T5aW0x9qwOdgKXc42qU7u%!Wj8 zH-B6W&g&8WDGXg(n7sb-)=ElWbSG^5zK# zuB*=ww5oc#>b}|D^M;50uz{bd0k3 zawpE4P*$#FT`(-&$oJ8UFxPYo+|(jv-ovSua7NNTEAqHi?z5lIhg z`!KrPCEqqBXzn+wBbuZmi)r|adX!X3EatmU@P~qCA zsJn8P&Dl04OAA`Al1AUL7g9xP3H-naf!o@j$V_Q7SwO^wip`+&9HK&V-hPUD-Sjzl z1@rD8Y_`Y9J!?IfDEfIvOWQovT#glf3ieS=YGTUO8&k2z8O zv6d_U0?PM$-KB7#tQX7JYk$@1*H-_?7XQ|2?R!Ap5C*iRJrDu(z{-Osbktt1n0lTO z;I)0+8fam|<+#Pae`mQPFya!7$Z6x^oX1hVp%^MvSz^-|-^<|5((MU{ zRMY@^ca&plBvl8D1!Xq1m+FkYzrik8bQFua&_^?sdrSy0Qn$IMpUTlVpzlnd{6vNqd|@#rSEsqHGIHBY38tP^V}kyyPw zw@Y?FJ6aJ~xw9k=%^137*yQA;@Ovp)8D92bVfgg-9h;)G_ue{MPiMAW2APp458QI= z#~Q764W-mkot4TKKZEVooMOuqEbD`)9;!!_3BW<|yM%_Csz3INX`K~+Za`1c1-hRj zTio*;^K*f z@Gq~0D1IqG#ASajBU|duX|zJYVLcEzU4Y{^T#Bv6B0}b@AT5#_s~4qBB2dnJ{{s?H z>8_9J(#FS(yD(4DOu(*_gtN(=mabdOfIdsl`pAq8mO;pwd30#Ip<*noGA*f6q*)wQ zU3tiX$=g6NpCYAJxq0Jg0c4;CZ`o%u;;pn^${9zsY`uR^uxT@=aaK`H^`4J*(7>@1VH1E;a4VB^R6vS-sK) z$;Hqt?}p?RzToL77~(oPJU%~?9<#zO7Ud-q)wSzwt0!!Ed%~(8-cWVQi%=dKt&`7$ z(ZYR|B4hGU#MaGae(sZP)bpakHlP>hMnH#KHG{xO?hA5=A{@e6tFgf1y2+mGN#GVM zGlLwLY*(DpJD8hF5$fi??E6e;6hepa5q}&x_U$s0Xk=#45Xx9tl38Ja(T{%TdV#)7 zkaxpSY~cvLcX>$rw)aRgmhUDDR~A-Iw1OwSPVGyt6Mo>j6(EMrc&$&p5B7@_<^PZY z(dw=BhMhl#`w5;8$jIsaNS;U8mbf*>08F0%Y?Fm6`r3OGn+a#}CsTw`%P7zrMZv5C zgXR%D%H_0{qf=h=_s~s#B)jI><3I7;yg~gAdj$=SKdsmQ;8$<3ZH>GQaeM$XnB1HF zVgGKTwc0-xWDn1Q`6%|Htr8jaxI5>B0g>MDl7^c^iNIBn`y$6kMax}gn(Cb=qgGXZ zbpy&7ZDPB&W+Ixv`)aeFQv!0GWAuo3=!v6KFi64nt2Es@2+Jl2f(oL6}4<`bT{Qn3kNPTAyw%;IdLU!%hy=)-Ee^=+^bxqGaxZyiEmFJ3Mxi!0LQ231X(nA+|W!FU!a}_Op4Ql>9B<)Jiv`=m2h< zuVlnSvYsO=ua2h8C<#6t{e){`fsbEKEuRI}{Vi!nSt%Tw&fpW1xNeG}uX7hgYKQ%Hh_}^+|?$;XG{NK83u>Ftj)&tIkWS-`& zw7NdpC^(sU8H%PofSmDP8SM$flVEx3bd@Qc&h*RVCPO5JBk#bQV9AQlDuuo#?I zaFVb4iS8uWiLf&HCH(L+VQ3K)WO5X&`d|=32-%~K@kp}=NYU2D`!blmKE{R)Qo~0Z z!|CjDh)wdr&}2bFSu|jTI%G7(U{V8{x>tkGk9O?>IDM$WHsOM%(WExUoU^w3k z9@52uHt_}o<~t|H*!-7Gjow6p(`cKD)u!CD5jIJS@iQc*cE_gM(KwIv-iEw*slu3U z4tE;n6q-1XI*!c}_y0%?c%$r$gQ#0k=g${?d2scU#MqwV<_gwhvWYZ7Y~~DFwN9}5 z%Mx&gq?%P$r;=ULu%q$HLoVA0??*RfN#XiigYWx|O1@edB)~)tDwPXRx|8{m1m>7o zHiodNMQ8>Jd=+)pUD(&(0q+yyWhT?rye!kssR8z!50j_UdY`%LgJfcoi7$L`l1iCO zb>z^@*|je;5)x5rFs^kh;iNG``aZW2Ur-R#eA}i&159EpD1AAE)GlE6D+X0g&d;** zXBznMK$9F_84dMxcJ)cMf#RMx8AUq0-qji_<<7EYj0=i1b+DEI4`g8J;}lIrwaQaM zr46isr4@6YXW{z%x~S@R_(TbJ{9M=!WtQx%zDw3i{_Pg5K6v-MNz9j&Za9_817F5k;O{Rwn zGPF=oJ4`*IR#6OL@K+?5u4H0=NTo{&*;0IO;M?=NTTg6m#mzj(3Zju+h5oqR5rp@A zo&|?ONt*d{O+wCvkyf{T&LE>-w%jsf3dS1K15pEb;%rbh1K}?gWyd6B03!qLA0X|K zG`h{1ri7FqlK2ZS@>oD5&4nq(Mb36913fjz113&BL@dhm=J7ND%qwwNxOl=SafM_@GALBR7l9!sVh3N*kC_yGE>m*k9QDz!o!%; z>0J_k9NdV4TqV$8RFMnI>m3_x!=2>Io+&gpB|?>;)1EXaMP!D+^gPSB$u+$kBj#0Tc}iG&4N|4e(dy-ZicX+1+ERw2IWo~019uHN0tZ7a8A2K#W~Sm9+H^IR zPp^)bY6is{n_`&HeUtTPVzDP3H104LTJR3AH31*J*lFi3NCb_KRQA+a%vyn6fJ)oF zp1#C{AgMslFG6dFguzt4IFl~|W{g-;pdX*W`6{<{qb8Y9sOz&7>Yl4ub%4T{CrC0& z=GHO@gDbrP-HGYs9A`O)MJ;$RWHlZ!-1zWy{SB0R+qu(mbr{Mh5J%fQqO%y31mje# zZ!UE5t<^_chp2%YS>HDf@hxU1bqX!_5PH12m9WX4v(U_5Rt@GLxgt}h$5?x<`f0Ek zXcWGHi$JuY1sfskHdeb|c01dn3*Xk-m#eSewOV`JYUdRV4Sk1-w75cU>!3iBq69H2alfd zNh5|Rzffp<@|ZH*!OcSOb@b4TUYr;)?8}x5)nubCQZ~!(qC_jfiE%=!KUasOeOuHe zpUUca5i9;tQ^00OSSqsR{Au%3{jRuJ2hJM%DRMmm{RWBdkngdnCNb<5?thYve`9;sx@`#Z zFt+xp7Xpy&3ZAF(T#p{ZbEZeQx9!s~Nerrk2Zca}XOUb2v3gdne1>UL|3Yr&WE37D zpWYoF=7Lnvxc+B!Gq)c?G^7EEIOUp1T%4S#pPrlGhW8{dN~=>2^=RAAeOAyv0h28k zHypz^ON3^FT=E_0f#eS=HHzDELCmik&3|>~6mR;5z;YFwGemTV6D_417aRwyybsw7 zMk0JigN}b{@g2EcozL*dGKau=%*H3?nzqm%_UVdOPmw4N9h2-GX;?rnLIZ$(B zcEROzl9SbknH#Ml*Ic%br=MXXjh!jF3jwbWEEfv*YxP+-Dh=pm!{TYviRA3@qMQtP zVpVRY1+Wc{D>RkprZZ`3&ni)hpS)g5!QlUErTY1`QpNr4RN;Rr)w>S?fPT#{x{GY` zSBmp1<+q72FZC`Zwk*zv{G z3lLD;yPuoy^YZpR-sMr~;OGS)WT|egf^exE$P?v91X0lGG%iCzVqt;aL81MSmb`ls z?fb%t6Wh~ZsLFp+(np;Vb>+uS8g^qSvk;@iR;`swmEGsqp`0Foi{Wc*9v~NiEZKc3 zuMl^_kL|=;-7_^&2q8I_t#&RkLAXqyYFEOgaKdeyqgPd0kJf&)8TyeuqS{b@ETXX# z;V2?HC0O-2ElRC}Y}kMQOV#dj-SE+rzZ=qrqS<|j$1Y~NT<5iF^~9%E&536bK_Y%A zt)Gt%%o-?|3*{6e4)V3~t|2cFfy#dPfLsc}qPkKkwO(eEOq-I*8PxDN`spQ9i=|J^#*Biv>Qc&W@Vyn+5Qro9^K>z|EkY2y zcb14**SBdbN_lJ`P6+b^B7DFlUtb3PBuD1&yiVR+=a0>$*S2YhgJ?t*p22tG@;!a! zIay^7mbcyyWLNftqM|lrXt^%)@+7Ol(y*JXLv;uz-Xs|sPI z8ouY-$7e#OX}HLDs?S{;1edgp`1l$}87{PQK_8~us6gINeOB79qfgO@yOD?{l{Cs2 z9n60R`LO4zu;P4-`UsQMBLNxDoH5w)c7cBh{!4AQh(WW!X3CpcFb7$#F8R5hq)qS` zi5NRalEjVZ=UzTQ2}cTgnnYuGHIks zP>!Bah5w1nTbH5`O>}~Gl~UA9Bj{4O;;F_2Gx+=^QVZ~>)#U$glm4yirA<1r70h?M zNoIV<>4xsro5#K7tjlLZew-krASK3f1XkzOHp~x*2rR+c%%LkdQl{y|A%(_9{@wDt zeqzm68kwgbfHFpezBrB{FmhPEa^OS}gte)@a(xub})v8?V$eHa|18p3}$dq20r@ z1at5LFR}SunZ~<>xPkCJodt_Mn&j-~9CZ;jSTGMs5-Pw${ogM8fM?p131w`KK;z^k zO8#=ezQ_5l6QiJaZt+1?rFc4gb^h!cD+TSpDYyCm_@amp@wej{&sPfapAO@K=h*D+T4hDYyCmJW;jm zUnyR%l-C)$FNqH@^%gK|^yM=Wo`3m_{_zD&{;w48R|?{vzPwPL*>wAVJ(0=hzfyc& zDF}a3J{Z6F@((4|<*yXqR|@=pQ=Zv0cz*ekUi?>z-zx>~Pm1j2i!c9B@=E?n@qeYj z{x{{BO}X@!FNTYMr3AcEVE&{idA|7a52bJEuav-73iN+dp4sF{e)$3m0r|JR8}v$n z`jeuL_~Oey6bs0|Qi5M8kpE42W|NHj<;(TEzfwY8DG+~BwC`VbooK-?iX$f^kR{+o z!pr)->;uxC~8)k`=AkC|JY*x{~3+)C80qy=Mqt6*+tB;Hrw8_@<|IG zdT$=jDMQn$eM3f4xjk)**b9uHcv1bgT#&D`*u?(JI_D(ct95~Y7oGO>|5$GWywKEx zvO^|iKry(6FG9o}mlex*{=%IT{%dSPUt^IBKaijqM0hSBBUoF%A&&8XA6T+8^H)0vnK>D}y z(x5eWs<{w2mL^h`<(JhxofPlhzP|GYT>O7x_UC9V{@2~5@Z0VZ0PHS6HSjdSZ15{) zqkyqN=YR_5W&Q3s=;nR&i|54xzj+Rr3;N6Ri*mqNUav-SKzCxorCgOr>5xDi*ZV&0 zaj>mbBJdUT?9g;X=S+g?30(cBy=&Q9RZaLe0ezaifwA5XG2fcni$eJKlnWvaK`Pfh?)6!~@0P8#~W-cX;oiZ1Ide4*3)}ChO&ZZN?7Unw`P2HCY zQ9DR!k(unjpI31ohdTJcmCNJUhB$Zag3{Toy!piI$HMw_3DZVmh2)5%kXPg&=RHnY zuQg{Ex}@E_wj0j_o`+Ydk0A^hx>Q73X@s@VOQgk`OP37E-|I&UEuv;-WqwRo?^4C* zI!zD<&(u#VU|ux8CvvSHF8n;ZTf(B@FJpc#AsHZAX)-E2w!7a^DXy4TcWHnftxn$Zen`|{2G%n z*>DHf!jz_%O8VdzuZ#8L;@AVhZ9U}Afriv3JmCth#uKtFzV%q2}ZAQlmT8?KC9t=Sa* zAU9>P{uyUOU*cRU>3Vc~LF52w-V&4IkpAGr%Qb=0OF&Z7jE;k+5)YUOwlgNbdBG+7 zdmt%Sy)<^$jnV2BjOy$jb6z=DByEl=ZKQA1SGv-WFXwBt?xwN;CCC0z-! ze4=(P8XG-DwwYq@GnPQoGyB8scMb8DETPT!Udr*svUx*~yk>#J9h#Y@6zLg0?!@Io@*G40%Q9}W*^+;nDM7%y2UYJxLKbzWFRAYp7)KjoqZn7?@+2?X{2q~Kfd_5 z$5kGv^&-B?lu$siV1U_Sfc3isfcf9YyhuP%>c1u6M*klP=+g#BfVVb(U6K_ux++mP z-&qe46qhB6c$qvbo0R-dp7nd>!5J1HD-CLNrKJIhg8A~wM;vu3&ojh|kA6(7MpYK?~k%k|{)RTFb`wIT9T9IuM|c`u7p@g2z!VD{HM)*&3Qwd@JN>UYcswcl79%Zj=6s}O(OC8(#+1vVz`Spz&IqID*8T;r6T zOPmJHP7;W^hJXkk-;6`rPf4m7C8DWgQU!fQx(%tLB;)JPMr znmxpjIq^97P|FRlQ#Ww%zH0ZyFeoVa_F>r&ZqGStZhno@6BGex%djxU=krS*9$3AJ z^>Y5Zc}S_ZsWxCZ@M_(`Q2AD&NQ+2oXd+peEulm{@Cp!3%LL83R&(@M_`dZI*0g!T z)FsTA4*Q|+u-oL&C{k1&Q|VitL$ddmvd^9c^YPv0S4B_Y1mT*Fhz=X4Q?(*ie4GwY zHcrs!^hXG?-{_%XJ#8;QT4KpXv5}m)jfCjD$>H*@mhXJbtgH9veyp|{wZf0sh^@)jZp5lHw-f}j zpze~Hi{%T;we;r${<}g-F5rT8=f5 z_aISbmB%Mm$Omv+Ukt+JWCYr%MRKr*= z8}OTWCK!D< zLWQl4*)J<9ts%L@$BYh_k(*Y-w9#b81-)(4w5>ObN$Dbl(xS%A1SI4+6jcD2N-w8g zyx&{d6ry8eIddY&5{AF6(K%YnE4pN_n=`V;JXF;n0d(kJK#nxK&pS`&Xn7s zBSEH1oirB8&zszQE^{`g^)EuNH>!&OD)pBe#saV9j{KkH&O-;FL_DFQ{#EXPDE%MG zpSLGsUkkOze{0=CM;xiW0DzK41vm$OQOuQ8C?Hi}px5=gVgi4-k9(n%&i*F_>p9Iq z0HBy2#5~c_@ZoQ5pN3s2cu&k}B?Y z?aFfXVfB;;>*V|K6oY!Iv$TXqL9$uR=egniJ_;F^_2ZvyKbOAxxAuxtp1Lbi1z5i7ReH#Luy z6T9ykezL#l0*Zm71&>f4v9UDs#Xt9rAdEZ7*PU1vX-$3!^rs9cAVNT(U)CRiM!AoF z{kVQRO?ljY{kQ;uHj4rT`rF=2(e}xlSgtTS1gCLGc9h<-OH&i}OJg)_l2ouE9OF)Kg&}w>XJQ!AHtn zf$GdNt5vC7i6m+`t-_%PQ51mA1YKa`pO!tnh?k+2p^^Vc!n{_mnB)2NTfDyoLT{jy zR1JMx@v)5OJtm09ARZXnAe@*vsvk9DGIjKQ<3L_^;W!+PG(ws3PZ7y?<}-r_q0+-oXfnIuhB> zY9=G-vVPo3&SAy57vDNyp@EbEz?bz0Rs25jl{)hqb@d@@_Ee}>>01P}skim$&y;7|+mzdz`H z|8b=>`Qep<^Pd!~XKmu0|Nn#TWi0!FHQ)yw5YW4kq=D+&z0>A9#4}9xDZneKDuW~9 z*NCPl`!Fw_Gt|KV0R-lC{c%`fIVt&S6XZ9W*4U>2&jB{kXJ2iK{Lf*-GD53Jv(zwQCHf9-)Y(4&9$K!G_B(3IL}2}<-d#W-lWIA9v%XV+q}un$B>(kwow zTI8%K3Oq;JTBOWd!1~>CJC0tiq9TCC{kGVZ{y`C-FTZLXFvI8jsr$AngF$5 zb6m>PvSab7+p1|~dyuWpL2BiW_pPuWhE}^TVLl%7R5Wr^oZIM(@H;XxH3-3oThZjt zW`D#g(NbVlSR~5mp_jf%A4}NaIa?3+)*(18Ji!-5El!1*!5)Ric=}Oxo$0yiHSi|) zR^6K*=OqA_fB*pG|8@NlSLR9S*SK>27T4~VxPAld&I&_72Qy%B7;HdLu+PBqUWi6Z zF#mg#@3)Kwj&`5+64IjIj@zC=UPB7VXcbm~ua!@(%U5&*agaE^t>ZASa^`QJroI`y zzp{SAxi}6qQfmo<7c!E8?p6)-d4EB?n^saxys#nwBkp3 zeDTl=(*)t7J38jLbxON@ldXz<2go(bx=Y zm(TcFG-&PBwC0oU4OIu&^vIhat3!<8%3ar(#ZiGFrA9oofjkBjrnFMcJVp5~b&2oj zIE`t;y1cUcRwhTQ_|v1TXHQ%3II#9LBct@#X{d;TN9K|$ZSV~g3QJ%PoqTjP_LmX{ zh}^`n#HDGo7Cjwo>NR^L$Qaa8R8LC+*%ww(HQu1o*q_Titbcq2c6N*2l5d)-mMj06 zC6f+>uf`>3kQF6Yv0LLUJ^TiajylL6?ngWy`(>+^)IAWI;K*YXk>jEti}Tdwhbu4< zSaCi!5f9Z{OB3w{w!$J#S!?HSKaC(j_0Hz(4`9(3Kf9r;)OUTGe3%tlHaxXk_&!~u z-frO6yuu6T!)R%~;cuFn^g~TaMUQBl3H)o$=L%4W&$FfTv*K7|zwENxGIbnZln?ra+k9rh}qC^NEdz?lQ9R=Fr z`EKK?!{exlBL1{$H}=DYR86aMhl_pF?nJ*eJ}E!wa&#l)=ORJiG=sA#3z<=6#^(9_ep0+mc#?uy(s4< z)EU5ph%$NhNo$|qWf@E^qm0d~@qt>zPuM^yKv(i0l%p~ z9F`#BRz0r)2VC6Xiq+!pW*E^aGAMvhX@0N`UUBK$wC5_V@^?#Rh2)gDTQ-BH;yYuO zOq7)uLXS4F(xmud^c96sTmVc6up$Cx2Y zx!e|33Jg=D#{+lGJ$Y+}D6oI6Mw06srPE~EQtP_7V!akdW;X1#HaDiyi7V^$qL_p$ zFn_BMWL`B`_zw*R=JCg{Jx0e^nFf4! z%3-QcMFnG3kux)fy)1Q`yppr>1frnDklf*-G!HaOBBmI8kOjL@htIk@4o&@8c^u*x zR@+T9ssIaH3D0|2_EIOQ715r^0%Yfk$#3!)=8q|=(J&GuQB9p1 z?=zwrM>3K$?co*#A-G)hWfC1 zVWz{;@({E&M9AJM$tXVmxgm@voglmsfjehYUxOWfbnH*l3Q5g6nIgymIF%-9qZ1SW7eW7?n{V?sI?uiW!=MYZr8zr8p zMl3C3u^k;6!>GwZ;OXvl-b&tx;QzLu93STJ8gA{Q4|UTVpZSSPFEj}JkF#kJ@06;z z(#;Im1k#f!iSAE(XDOje0w_p(R;_u;4aLs%`1C)D6Xm>8tjHDKLT~Ae7q{-Nl|)H( zBIpZSg@R9?dJld-mkK_Fv7|J~oauzdNDr_l9 z?P~ZlG&kvBrVMpcDSph`Y;p765c2e!n2a4oIV;5a!_OOzhuF;O;GAIIcK0a@PqKQ> z1w3rP& zoBdIyUH0m1`IZmUrT!}4t(`|O zdmA^`Ytuw0Hcbw)pnwCEKCSgICG?(^Vs=dOXBkwUd zVHM58*0i4L30!z{$_evzZd_Y`}dhIidjta@8Tai=AYtUtQv3!uj&g<{;(Gq zudw)L>JO;r3X#mUDxiX$YAzUVjFmqAzW7UxBPHJka-B_v9E5jSv{yhKwK3bJ?zZnW zZ(4g54p`zl<3hr+vzlr+o*CKd)XieYdyp?a)5SGbF2(&Ia1ek9svljh-my+O%sadp zahTmU&i}#XZCKu|5D(eLqSf2Q5)Nu&sHbTbmXSn8hq`e&X%twd(7HM-hw!eEZo@DcqeklVM51lUTttfY z@5}Kos%A8ySE}uqHnJrKQGu<8gfpk&N7FQiC?o@7CS(Ydsts^FEssMtpe7Ttx|b>8 zfHW~zO!F(Id||o^MCiZ7F(&A|LC~V?Otq#yM5+_o*7kkhuiHm*K}H@Zd|6jm=25r% zkhrkwD5kZ$wlqIt=Xb53$m)JsD`dWxt5PmvOrXx2+nS;zRB?x zB%5%~X%;vhF2d_VYQ~Xv!uk^r-z|?U{?YIvLFB3Vq-JAje0;1#h z&gL6st-+SaM-hykQ@ltl8)@|HKs?D#6L0kfth@SsUB;cjW12YXdHK5lXniLRM z!wN$p_o)v(sd@ctl9#Egw?y>x-KfiuZEbm(2Iik&FY1zG$n_HJ^OZ2pTxH_hp^(fF zbL0H_I-=B|XlUZs76M=p5xs>ebND9u5>5hc;~Pq<2|4u5P)7VK%5pKN*GLnn6-D=U zw_uq4m`*1yy+?20Wx*i>}`CU8d()1vnA*4XVXS@?6zGy2<+hcALh-(swAU9{vdyW7%!9GYW$lIbqB1_@^1dQkS>rzx zmtdRrNjx)o+!noghnFoN?jwv9MD4I-yKwEnR7s=Aw@qOY)%qhZ4Z~7?r5R}m(kaAo zC6T7)3BqN1ZjWlKXSrJ{#NqL+VCO>D$rfvroBz(2Q+!zdA+xKt=+L#5BrPuaPx)oN zc`H6=tqj=AD!dapS+eao6DhdTP-HJcumli-znoIZz7}9Ye->cyfbj*-C)lXJ3b5j% zzZPIwuLan@Zyub%tNc@d0ZvnZS^`A_7mt-g6)$T|c`S7O_qw5LW^hG1Mzc!yss$w3kS+re#fodP9)D7pDM9|&vlgSL%06DEIEb&{^Ild8+iurZWnDI}UQ)e^J zH-sh$%Q&6!24|W}T^;^;F|JEY@AQ>2fGAYIuj+aB(U=HkDSC+?U=TG~_p;g-YYL6Z zJY6sY83-R=c)6dvJJ7|-q%yV(IxhK?Ce}4P4?p6f{tar!dWt(g355E3yy})ITt?Vi zh-BgPJy&_s7c~Fa=o1Y}`7@>lwaie&vW8=BzuMhML5IeYb ze_!C`rIac0rBq5+^6%r9>nX!Gctg2lW*`q z=j^-X1E9j%3x=K5|Hs!i$A`HD?Z#2!UW9ue4_k8!B zbG~2yn16R?_MLs6*?nhbDf6@&JQ;1%y?Zziz>*Ds_RVjK(TAmzS~c3WA;qhW(Z^xo z=R7vS9Ubt*;F0Q#Qdc5pJ(>{HP8DxsISsh$CoG2pi{MWbvXm1GF|R~%MJ9&>NTEeq z8L3nXw{AD7su00WPj*d=E}DRSLnVWbnD?z#D?({!e_bBrUc-=Dz#>36EQ**SLO9T_ z*x_f$2ZQa`4IA9yZ?@V@?Qf_ohVHrNM>n%3hGR(-(Iy2E2i|Rd+szO1lOfBr`U_}`mw}L60AxY3{8gtDfd3zfKFFhl*#wG;PA6CYs$hl5^3~!(eNw52Sgr%cxH-Dbk4% zcD~ALBJ?1H;O!M?&I0Yc-oR+t3DD=rr2Rg}l^u*V-6$WRd=2JUy69qG^=O(uVXi4k zQFSZeCSg^2TwrV;2qZ7|=`t6tg`o7{npveta}oa6K0M<~u}BpIwnEQAhvdngQhR&G zYOuE;n51@AMYFa$YO%p7;sdWx;IyVLgPAC-!OVhF2@=B1{N`RjN5Q$0f|s5b>n!c! zD0d^zT66-eX#v;cKwlXdsgU&eQh=+bd>gt%O59p;ec*_JW4o+qvZ)yS40}g!sk*xl zd^B|GRsR5q0_DS0R=0fWrT5~YTRK@Sn>h=xSmeefLlaGRj@BoQ23S!e(tMD}z7Txw zoUrtjGS%AvS7N)(m^6>(0*kL`NIS?oRM}YogOWKBvQ?J^PYA&uJ@10f{)m`GABg$S zEUODd;lB~H^exLOkoS<+e-v_v1Pa6pCLU3;N(aT_*hp6J9GQJ~g>8!8_=v|mzw9tA z(9$)=ad>cp=o_D9IXx>-!Q_wt0kV#Gp|Ie+c^VNf)k?bY#xL+s<=VFG^iuv=#06$(A`(5acyuA?o5ZCX`vFzRv9_o6d45(v^C-5Mg z7rei(4uO?Kar#=@gz_Z`I_4H^Xz}+HwsbeVTh7wwkh}OzY-7j~MAqr&$-}tm!bE6m ztO#;7y`rG%_O4?G1NbD|XSWnXO({HWi%Q4}@S7Lo?sR_+Sb^^@t2qRxu2XgvSvvH0 zsihjuytX<~&kTftYR0;4WDWdQdje{g}BA$@MvmGdUWQ%&v|Xr1MJ#`=@Bixx?w zP`r-0w|_}Cb}Y8unygrP{t0}jS|L>L^eviAQYaJR*E}x>mV?7Kkv>?}_6_?-Cxe!8 z>^}Lq(Go+eXyUMYu7mt56b1LSelOr@Mq#Um*&V)Tpg83AEeU}a(5G8H(B5|KwU<~< zQSqR+ujOw==oJeuWqkp)7QaHhKa5c`iz?(WYr0yX<@9*GZlEu+i>Di(G+@k%P(=IQuN+(0mH^OrTP|LxGI%5Wi^Js#zYu?kn!}ZS^>_0 z^yx@ATzJI{pTYM~`Oh;nD;MTV-JsBjsRi-wDMn|`i*ZC=n z$=skMf;NOj)41|5<42=uvV}20w+o(TkENo>FRF`ChVZDcjx{fb(t2+m!j^m#HVz?wdWBrb@dTdfn3-_(sVZ$AA_{uZB=7NcBx;pnYWIz$;IGQ*kZ`Dbats-t76DC>F2suW9)nwlXY#UoOViT$*s;V9l8}E_w-L6wYpWrpA zH#vnE;TK!nHW3IMzL2dFjo_n1Q51P=I-!kq>jL?eyo&XEiN_EbyW94~3K`m3;K{;D zR-=7Jbf%zh!uxKVmaWwsivb9eF(caqGCs1@`*n?Yp_Y7ty5sTlUE{;Dsd$oKhP^_~ zQN>_ixZF#k5QSc{g&OdcLsJ~ADW^MPTapz5?zKC7<=sqZ=^PABX2Hr6jDT%FSH8ER ztQ09AIM0J0;=C&{%+sC$Czzm0^JYKorrT21d!*XQ+nM)W{(bNTNPR4R$K5)ge;$0%=>I;WvBgAEy?`{-;5*vmnPkHCK92)aoBRbUQl5s*; zn5AOn#p5c>RP9ryf?-EvL7nz@XQ6oWsXCXok|0?ns^m`>oQ*Yq`svbb+lZ&P4Z5RJ zwMUa2@-%4{#m+1hXUtw(%+=ozVFRuZkM~f?P(!w)5*~dRz1O+F70IG}hJDG-R=%Of z4ygT2VT+B6cDuxRm#V_}7WR84?HIuO&EKpR$i|cV8u^FgZ6)wJh~Ek})cRznVK=nXhzWV`|C1BhuF&#*Iw8k)5q z_AAS`yGxp$lN4N8r0ARU!#phJKFPEx4*LRg`exCl0L;%S%gy$QOC2`i631XT2=#YP zwO^6@Z+Acy%hwO%PnVlWmMo<0_a;bt27vwCSOcuIv0w!VfHBhI6j`j7A2Xchpkri` zqAG-X>N}v95?PQlHMlpVvb>(?5@383%z=?>*>R%oO%uqFlI73g6xQ|H6rO(0KoM(- zip?#`{qnd1BbmMnFFZ5Fm=2pHF^$nrRZXlq&uJUp-bQO6YI{B-9}G49p-X!YZrZNAFUBfDvLR0L${oU-0ZMU>Y2clqC`p?V$8Ti>}OZh zXKpY!4jkKrkJI9aJZ2yt zW8^mWrAPa;>1E)7-|Fxh*;o029?l3Q_!ny}?wT7`D>w(e>aLrq&OJEtqqz^UvO( zda*-KelaPLcD=j@R48>B(CJ)`+sirVfcrV>yud+K#ySkK-E}~ls(3v3qxA}d)5T8} z`b4#2Plje{WKJDj71ugTQrbyI=wVXi)QzI2d2$X#S#ZM!FZ`WkY{dA5{6C4aDuIz) zhh1JJt|xmOSP!5JRKE;OXI`3Low?=<{#FO7+>ceT1Twi@I3vr!OMnUfafeNVLE1*A zmg^l?FjHOzJVC)eYb{8K>|S_*kJ~qZ(2yZ2G=wm< z=Ab44I}G1fz3$)0a}8x-4_rrQvkCC&2Ta4?>{o;6i~1=R-duIUeWK&zpDN%y`0dJ2 zWwoJzsU^$&1xCR_4U{aqjVbcg;Cvd|uoDu2GR5j_=L9eS&efOjGfo)(vhFp0$>&}f zgz&x8gK1l$hUOx8^F4om>TS-lg*Xi5RT8*4lxpeF&^#m&Z|tOUlrKI%lPs~&XBf7} zSeC|d=c@tPNmiW=S5euq@;Dg#ty~%*9tEdKc3iZv$~7-qS0SbR`(ZZYwb97i^75CG zblv&!>WZm~6gAWE5^@{EW{Do%0b^CjA?j_zQx;^YcQnCz$)2GH z(~$z{X({(kq-H#8v9rcc-esB%YlxcB6~VH6M@+-3Kaz#Q2U+~P++zUq0z2}ZEFd@j zB8#K9Q9Ryw;$8kj7FLgCA7oMdPuwMN{hKU^-fl@xF1t|lno9%vCGeg zC`Z#Ci$$50tnLJUte1l7%gac%14Vy^S1V_VBpa&xv!R>Gg-TGhSmylQxuaSzznFCp~6W8sJ zwvqxCe%@eMz+~znQt!}C!$cE)(u0fTR{xyG;;vKXJk2k`%SM^sGcGcCba(vOnE+dW z{~P!M3|~w{lUI836VB*Y#5N_KE0`D-by04qZ=Vl}9mTP*SCi^f3$|K!N;WY|{?^SMtKRa0oktGx-v#2T$Dd>KR* z8jY6G!E6Vj7~`12iPub^WPT0g8u1qwEz3hZyQw|QC-~UWxQb3#;4l8|0U%Uq=w%hF z%<_#Pm#gz-lxiGgF#{N8G8w8~r!MsxNo^P5FL<-3gX+3*aCiH2%gMH_;7SE8iA1tq zd_>rorQ8KvUqN+=n;OHPtrb^Fr6{d6BOFK;{3kNACXq~=Uw3oXi402=3~x|;VSk`X z!oT(3gfmQOyZMD{W8T!t&Jb;o)KGwkeVj>=><)hovR@|c6G|Qm7%jv2DNhCok7yz4 zhy|cE{X|<(sp5EAYW(pWcArW3zU!u$a%d*WuH&H}GJ5H|qJhtG5nv9EDg~UJ(bU!6V43JXjfSn7tr1 zcawFQ6#9Y!l_BOE1g5fiwgn8{g6%OGbr$V(d3k+Ap@p+^K}?tRLX)bonPxqr7VZZ1(_%=j1k^)JT7s@Y-DY23YJ7OE}tCpxzfP)Is zyUz`l0f7lA3WM;MxWbBMkWGO`!s#8DbJB6r0aun{OdQEl-XUtzkQ3ZtPJkx(q|p)w zauqG6fyKni+oZ^YGpFGbIye5NCh@0>G41p^;;Za(I9W6dGseJ=r>{Rd>4n(bfaXKL z6-`GvGas3o@sB+p!prV0^2g#wn1&ExK8x0e!>hUBL|mr{T_W;^EL~72^nRV`mHyPO zK<3VuP`xV>n5xT*bxDnNnbehFv_yLuitO7!o1TuBA~j-%%)AAwNUN}qmIz`y!vjiEde|* zhg6MC-d4#zcuUY!FeEpA=p8W`-w^W;2N0zX4CenY1{1Wsa|&q9Uz}2U_eb0<|G?dU zW<9?l_TRYs$^9*skG1A4UPzS-c_0vbvI{CkPSU?)9_zqhhI$P6MV4I_o>QoD%@5f5 zEbf%1PfF~j)_OQ~hgJnU*u3NcQnwycpU`~LZtGmgs7mpwIB9}E=qPFyE3-}?kOVNx`bcb*gA0w{b0%3E7dkTH8%e7zO*}&;TBiv%kUPO zZJ!=negzG!+un_aZVxO@4FD+dF!>A4&;?dZ+H=m+sW?Q&lVXjhuHdf=ofw^43%$%! zuiXlJ!p5|OCGn&Dbo#8EU`-l0xY(yGcPp*Bnl1(vjkwOk!&^^$!7mwO%kbx?``dsb zGS3T-Z?7+}_ZUL?qJk|?JWN(&7iNq;)}>b+Qn#QUq;4hGq6&Me7e;0mMVV{2AmTa| zs^cJVz}K{#;GUL)t5W#65NAuJ3fjVt;C};QTbslq!@e@bPMHQmY17PQ05tlHqrD$# zuUJ5j7Xy6OJ&Vp_pV(G6I))nBmtKYix)C=%_DOGSWRy3=9M6jVJ!1F758CwW6a zfGRQ;>hay#dq*91u9~V^{#Vh-OH~K_G>KtB(t6nuLEpeY89b>@2PgmMief&j2y=~z zq;=OYt~Ha-EV%w;tnKsZ6G`+rmmveufkWjpWQn^%2|u2ts93$!Wkjbskw_eIsr1WL z5+=;zo@|J73*Lg&_I1zVNsct_NjQfL@{ z!B4yS3h!FT0v-2Seiwv8-esWEI%{`LLQM*SXhLX3?>xQ0JS8_NDQM$#aF%pDv~#Md z?sNC^5Z?QgNH!rE*D1oLlZ%g*Ak3s~2o30@w7XBUqe$7P6Yo-e@czIy!@G$n3gv;6 zs52H=wXw47^@!&JfxXv&Q7>0w3zmZ#_4Mi^t5)+9)St3yD?SkO>7S7*>04RsUv(nN zg8%^IC~8{U5#1V$@jb^Dw$Er5Kq z3=@v^T5&o;iBp-*tAt(jiX#-E6%t(2$K969w#Rtimd>IjQp?W4^zE7FX%OP`9Eh$@ zxish6A|SnH1Y_37Xq*UayI`U(xS%el%uiwb*Hq>| zGUr<%SF5*9zm-?RHi|z6AdNvfC5|nnFjycvt2y^c$1OApp7ARtxj|IQq9T1mL4mZqh2|esa+0pCPntux@SH_ZI5e=is}&fA@(yYR zVfPq$YCdmBZ0O&FQ8SUZ*9Nw%T+Jr_%ELEN;h(@|^jy3C2K+;?|c>yw5~jKg(|`MMfm`d3q|gI;kU9&~nt zm2jxxBKDvfY9aXF=NQ`TAy9@TF2eDGqp4@Ps3J?7`x@AC9Th4r5girWzb{CAYVp>j zX0t_?6Hr<83=Wo#|QdUFDUIbz3@}!fpmfG=$BvhSo_^;{tL1Y_wzQQ{Z&Y??S}I~&Z`S9(0*u|4pl zhxpjld9bkjs*-&pSe#KEK?3wXa_%V#9cv&$YjkBfmT+s!RtZ0@M0f@)7f5Ud+vJ<@ zaMbydXCKnr0b$$tx zL!O#>JUOf??L&FfTas$|EH|++emqq!m|%!s1_Dx)bYf7n8_oblL^_z^eBo3fB9*W* zS`oWKtl))H|du}Ywo1o90W6`UXkYEw3YSmk!t=MV*VjgRsM)n`TiTJQYFg4KYP4L{}riL1%YSY^CLgOlZa;YbiM#Z^f8T!KvO7aHuzZacWzuO+&P zqvUIYo`sg~l@t*95@ftH?{@Hb*;ec_&F*Me^)DvBEus0pb$gV0i@qBk+>>9i0kp63rLmtH*uMc003|x2^2?y zk+h$dqV*Z}gHDVLQ@8KuWDW`v#AtpOGvERDl+{6b%g7xcLhUuV4e6zyg22igs)gCI z&``@6A$%e##TeY&XgqOc!won~SYLUJd*aP3zpNJ*^W{C$kRY14qodbX+L#Y2FT7_L zkyyDjL4v&@hG8U5_+e~EAR4S_cl%{eLvmnd*qL*vh0oaeyH6+yodoT-SoZdGPTKIC zq2|id6UoQDDudkUWm6G728<2X$&|s&*rm}KUZ|+=@X;}VT$8rL0s@Ns=OG{{_{A+e zKa8FATl7lu0ua)e+J@(SZ;imt)W0~7DwvT)PFvLMf)p_z@T|?=SHykVpx3XY$#nv4 zptex(lA?IVQ^);52_pC7aAO4c_a#!yfYP({j$YRrCrVs~xvGs*Uo?!_dv@x|c|_c- zvd#8O%w^MI4NiCfULKp`!zOQ&BRHd^KvNHKme!SX>AQ6)lyl8zl&xSBNRd`-{eBoT z9v%hMSC>v&x?Oy6R4vcnJhQmd+2D0En?M{YS~drzK<1ED6c)T8_>m8P$ibAUED%p-pJwd<1Wp=jgFbHq=ax?VPP`HmbJH^bbEyA@_Ubz}D~ zrec3%IDXPrEUW3wB>pVVm0vHxu6&=nxsn*_N;~sZI0M;!*YTnrzIKuOy;^?dCM1dM zH&dY2Kz^C&nY^0h22xSQxP$h(vIOhEJ4a%G23sQmh8W?df8aje?GGpp5Zy3!bCl?N zeVh%hu6(aUK@s~5dyP7(6@6|%hglD5FB@KvMxJa zdzf&tI#7{LXs6`N*b`q8)SgW7tI+Rt#{GJqJkS_!2lEMUR4Eu)a@U1Y?ApM~&e=n4 zB}+uwXA^P@Z4oZ}*)_hVjrO}$;q%$VMEA2IgYs9)Ilv?u8w7$yJlnSbX0lM3G?>ci z5HhHqcj$&gIxnE1Z?SpSeSio0d?f<$pvOQ;cfd2y34!m-Q#lqptzyuz#_s@=HhugM~ z47f$wWjf-;f`caIgZ0~fmK~MleU;Tvp1Ho6xp}cA+5mBbK0pazy^`f zttBq=2!Fs1mXkOR3j@ipWi!CB;0VEkHU6`n4zD}lg!YO5UPrWsOx#xF&>`bTnRg0{ zn5P@$YoRK)B8ureJ-<$D1x=i-%GI-Gv(Ejlbo$JE?7ab2nIVwKI1WGhROPi1FbiAa z1=qM+y;l0|c`s)Bz@Y-7#CJ3}J)BwkH{+oB*`XEdJ52i5A3 zrM{jD$Zve>I`RYtGM%g`u0?2=B!|^WvrazFR$JX~zs;&Q*Q3l>hK(RJS-!5u` ztj-UZ4~B=6a0JY9S@ouG*bM^x7_ON+xG(i64^GEMkFCfD z>a5H-jJ-XiXTCny;gZ!&1}dn^TI!JDZs-R;M+ke9h9XVyYR z-LG7c(lM4p7KfbY(9@rk+aC91Vy*rWQP;vM67Yu}AB?PAnt>ggKyHW?)sg&vDq37@@nt@7Pm<0Za;Hc0@dSqIa)?$Zxar^1^rb`4ml!_u4YqD8b_Q>@oG0%RbO~^0w*DwZU?hc@ zXNZo|s=Ayn0$*!T(bFMlmN|zMpA|`W1QqB#X<wF zA>Cq2ra5E_$zS*Il`{D&Jd8_|?e~;lc@dtB8zVa=2karuP~DEc>fG545V(b_10_Z1 zdrkroI+{W}Y9m)b6Xr9U^(}(*CC^4l8O{PDnVbnf(_TMvVL^zlyueOq#aEqn z+50;uoWb_HCrt=h)I{Cl6_l0Y+`+}I07AQx31VGABJKF1BDdf1yYX1}*#io0=FuK4 zRHanuV$vJ%8&yc0#c!|1%6qJ9UFH)7Ozdy-7D0m!Vhm;+ur=(PUp-iGx;o0x3Z0G^ z7i<0+kh@y4D>QC1Sl}fn{0UjtG#2;+nO2R@Za-Pq)w$NxewUXLWV$_>IgGQyvT%Yw zwIey(f92Thkv?|hj);ob*g(XziGR-m?^`{x0IN7vzR%mN1fk}XLhzI(X4 z5iH4z<}A*8cjU-1-99bc^H(e`uQLJKG@Q+DM6;^KSQ%9UzA{6YWo#ruzWr9!MG2{t z^2z<6{dns$(;FQ>T5-;A+vS?%_c}Rv2X}5M!@r9Ic_sYbel!h}gz6}_?ubS9K@Pj! zhP0Ys?iwN)c*Hzhz1(faDn;7;-t%H;B%elT2d>jT#;H-9cQ?{AZws8cp4*-%e#jeM z$OFJk`{OfafwkC=qD4jURzqkzoU6Om&u zF`TnnT#yqa&e&K$SS2xTzNlFkLpdd5V9}Ftiwjgq6-`&;B%eBI@Il06SF8mDtQkX_ z?+Rm+!XUUMx~X(!(?u2mu5<+_^a1JpzDXrv=nUL&49J~ifLDU$ehT@{`E6}Uf*-?B z7TmbUzYB4a+Cbok%@?@)`QdGy4uMtJX`v&t80k)69zeO&IyiI|WTGI6Ba-&q)~7Yp zh*z!1qjbhS+|QjMfdlBwGZqa;+=SVUWl0P6@^ehg`QuW^|)#~whcF zCK)uB1MA`rvv~GgRxkeQ4_aq_d(xv3pEOy8^Mg+mDdQRV$MbJ-`C=shT%K+E8@-f< zs|FAwn=gZdZ1BHSk#iDpxgzZRP+Op!;-EuEPfin3-H3ETlKT2PFX6QzN)NvtNd}wd z^jA1#sG{AdY|)_1?09-a-hN|>x&NJedKEsA0PdCnK9_pyP7K1j^9W@kPPGppyhJ*a zy+?i=VEC7D0fangv)Jnc3|rRSFUBh0V^;V#{?80>@C z;+z)UM#IeG7BKcWYm4?nL5XDJ+eE#i1H|J3HthDvoM1!NVu%AWiD?gf^ZIxdXG6iz zRN5F4@5X?OH8hnT8GqEf@8&c}?KjIwebO=qn?E%K4Y3)TXOq$_NVf_UUu zp8ee~DZDQn0^heN>E-_yn*6($1^KM{M}Wii-vEdGTn_$$@anAv#QP|}Z~u6(Z2ve| z{_}0o3-Xy8w#|D+*MY z3|f#0b=e3CjiQIZ$bmV#2T=l5S=5#j9)I-4<2t|>q#8W0bO=PoRf!-8?bJ^D;;rSe zl*H}HvF9h!-V*_tCsU_0bb`j}9}I*n9+KXH_%K>K!J_)mZL911Oo^u`rR7WCLAKOE zssg!uZpj!KvDUHMTQ20A)i1AqrU#0P&?|c}Q#Qu13YZZAz$*+w!Zpcs;t3g#B&ExS zSa+P+J6skLPRY`PjwSl(Q`hDXzl^>8106V&_1mVo)>kSn=`O_fyF{}B*YSrxN#jE% zh~WN&8%*eHVX~B}a3#Z&8Rmx)bxr}`>|;+Cg{vb_GtX)-zS8X!`%_oLF-*N*vv(lLG4Hv@dkxS1+Ckc z&bcB2uq;jMb-8g#uxx7M9^zLD2~n9fnMcMh|rMYU6X*^gdVls5-* zSnVD?Q|2a!DMM%>Xa343Jn))K&OdXU)>e3&608-1lQBsb>Vlok(d4P;{JObbcpu_M z$4y*)v9H7AV0YyZRy1{5zv}2f39V3Skf>?Xd>$A!x67oW$k#PaSCL9o@oC^>3tZU} zQ5Ut>&7aBix3OSEi^JKn+Y9E+uV8D}A7FKN-V^tQ`}*3OaI2UiJ`!xiRzSs~y|W>8 z#+<+FF}vn60}QDWmIfVy=dVKI)Bz%x2VEwEt#YNAY$9XK{bTOZ7NEhuDc=s)bY>8Trvn6;^=*kUAWf(;grQm3k_fx8x{mR%ksu>g7Bu;!i7Puya zIk>QezT8Oe^fCa}WWxiBwJwy=yNb{Zl~?W^+eSMjkU_Og@TJ&%g5=9qEoHK%WWx9% zxELkA$o=r}FpG}gY}6-1Pke3H(8lc0y=++HjyqAJp^BLnPhWOo?}Q|-=TBIZO(DD( ze{3Yah$RxQjz2h>L^JKt)}@Lfr%j`MqVph0??pW{%)(*b?A*oe>*r1G*`$N}>6)|mJiTQsZ>XdL4AVlN=Wj!#Z5E!&sabTV1=R^u0~ z!zeht9_sDx5zsc)1PXN#xVdNw>l$uYR=t*i^CKh~ga_mMGPIl)4Y1(%)zmIEfTNT| zBlr9TSMwK^&#-hsCol7<37LJGT_`1k5MmyCNyq zcvM?DnlxJ<6sA6h}3ov#hN`pFpiB85S4HEtF(hp8^*uFni<`I!f>SF5Y2AnR2(*&E-^>x2fx1Hr#fhghfeqBrLlE;t|!KbNF|aOZneDf5JUp*Ij0IxnoT)1S^*J1xhZo`FVD7OH224WI_J&qKOCqvKKSOp zJ#H>|W98uQ+Rotr;+ystD1eu@WAMBDd-Xuh9y>pd!Z80_J>J;ASI;`){U|*6geLG} zWwOi|RMe`f2yq|zgSowR%?MyCgQFo;95XHj+DiuK)`9aBJjL>P9!N8cVE6I$ zqHRYTG1wQO12Re z?eXp(6JMF@Dfb6s=ZH4u?=WY<=uhs{;D6qjhhw+7Z0h9D?yd&9l3fjES{-sVV?be; zA~*V#Q|zl$5szZ{sZ*6@KD@H<;^o5U zJ7lw#o)01*_3C(Q6lKyOB$|T`Co=rB9^i})9JR*LWGWjHIUtp?3N|nbyyw-W4yIyP zY|mHXXNvCgducO$?533XJQyr|qj{}a7e>Y|JMc!#{;v|h{eR#L)Kd#%M@Z9%rRPps zHEEEUwy*nnkTB9Xs=!iLZ#(bO2>`KfinYbx_4b?OtlMW7F@BcxU%at|kbo=0&kR1a zHM{55Y16HL={kdG&FSV3@ZVCurTIk2zB#R#P5&xY0}G8dgqwL(y1R;(L=0^l)vYYa zr)0@7p(;RRF~(aVoyyiOwdZEJoEm~B)hxvE`LmxQ6boFOEmx@Ct6V;Zqtd*JSad7q zxLUU%wZ#miUOQ?do=Do~v(kILaVg}c5T4xvLn2eBVx)$rzKPEcmbQ1UvB|$G;R3v8 zk2ddrVSp5&m;1{M-SYF(#Y~j`XfYM{vb$v8vh|i-imXA_fhMHyRJ+$5u_qJo3fE!F zt0cT=a9Si4{J~xy7~FZ0Jai$r9y{mtvp+J_IKFV$VT}_>iuPcY%4sYf>{7{*kjZ2I zp)|zrPi@w`Kpl4sc zMBW*k3=<2}D=VR1Pnz+h4z zC$0U>IiJLv68lY?jpD&KPDajV zeujaJgA|%f^y6YeM&9=e+ssroT1Gn+T)cA$Z5Z^QFjeydQ#t+{!wadt=Yehi-;(Lv zWoUqBK!6YVH>LufK6brhYVE%;RY>)3OjUWyE$;RoK(m4WxoSGIjHP7}mN1Q5NXBH+ zyJoU9b){WGKlSr+r=bXzfE*;H@Z$GnawTko5wBH@&;(Ye2uE*Vvsm+trNAeKnCev; z+)!C%vSbD-btlnA1<59tS z0OkmWJm$_!yn=e=hM#wZi^$7**N4RznU*BBO6CB;vw-wSDf8DOn~DrCODk<05!23b zK!tnUCpkg_Xqtk`g3D|=d7d?-ltz794ns0aOETRPONLc8qB>DXO*!}NS#Z@ee69_5 zdV7a!8Tk}`**zZ>naI}+(mk7y;h{ynzj9c)3hrv|E%)uvAJb`P)QxklEkx zLAC$sSugS4v)+(xXIK0LHGfrr)!^v|O|PddNnX!Fde+8}8e#lTIFaL>tsiU5wrkjP zuV1=wr{(N@Q7uLTFYx6X^P7k(S##{|xzP;l-?ejj)9w#Jgz<;N)BV@sMO@w--fZ)& zkK+3%CF{`tuZ`osZ{<}Udp>L|{AUm$;_|nRA(8*n#?cG_5cs1ne+)p2;;k>P&$o@! zl21LbCaSYJoQW{|ExgqEdFH+EbNc;)1_*y!(s%h!i$Bjr4jQNEO6w=K<1c6a@-B{Rs8Qa-1STJCJh$&ugIH z6KdTLiYEwu3tKH3U161fFQzn#Z2D!Kh7I?w7~2*!fYX~!@A4nTOlD0#6g&N=V$PVD z7a|{urFecQ#``~t(Z4GOzbeKEI2#nvAHpHKv6KP>_lOAfiy>m87XG0N?{wTc2inVJfNfTkD6Hh|P?@K5N4y%%48%^T#M= z|LZ8|FA+#-|J!Hv-8W5^a;YzrZ)V27$8W~l-yath^mBzG5QBDq*PLh?=1+AQFCTNt z|7*^v56$1^G*tbVQ}}PBG1t1%b14s2LzhjIy-{Ym> z-g9Ln?8$K)_xx(2$Nq8wHuG_=aC+0^4_o7{DejwtJ^kxDs$pJyMt$2F{J$LkTEiGY zSb!2BfDifi_6JIPqI$RI>+L`7`HcFvJvx@}_5j)cUwe-10u0^_dPdRLWYz2f&th($ z3)>-2qbm-!p%vQFbt9uKe^3;V=AkaK)znF66;Ij74Bw*b+LfJVP;mh@OC4Qy#}Z`A zhJNXQ-HyGK(dyURNzvj>zoqyUFisgU6gm?kwOYI%)PK;~5(NhBZtxtHp2fY@RLDoi zpMXaS#g`k#l&?+4SD|Lu_jQ-dv)k(+28!vv3VEe1ngf|8Djz-aw4lPv*zM7ovvNR? zw%1{6z0rnI$Z`-chLS+lJ`$HW4d*jm7FaTIC1WGc2d?4a3LALU2AL&Ggu{Bz zQf}|lje5mxKHnr*7V4&L$X6V7i}-9%4TvP^nQdo_w!!c~)j>2UK4h=1nRZX^Ucp)Pm%Rs(uH; z^~q4KwzNDeKDVIh>nY_O0u_Cjj=jf5b@K_!0gnK?55^pulGz!JQS-DmjHVg_{kr4O zJ<`K2>mVEYM9|%A{5?AA4T1_!osXqpCWQ8g`P_8P?A!(b>dS?ZV)c4J8xnx>RsA=K$E3VL_8JxzQO zL85i>ZiyAuwji77&N!g^#+fkvTgE0r@nIcDsfZ~>Vq}mCiiN3`D8-0b`bA}Z>9G6W z<*yDn(XS!4rK(z^vQ7KxL$(Nf^u9=;Dc!j&2C^B}wvaAgKHpF(iMh1Rz+=$?*kcv% z*QbBw8IOskm2nCmdkvzPJ<^v+M;rU_A{*8%`|q2(Ou2xyMzqL$Oef>0 zY_HhJI8cf`?zXd2U@<^^egiZE^h<>6I?Mcwlk3f*{}~mM2U903pnd|S5Wk$=czS_l za0Vhs)Io(F`{1?gfm`wUA_Z|2YXnRPBac5}bSHITC*~-GkDh)N$J1!e4da0kSNAtK zbd4K&lv2&FfFs?}2iK$XD=Di|LZ+@A3U| z&tI6n@ivOq+rD_0e{T)|nJ1bLj^h94=8#1HdvoaSd~g)$|8Nxg``-ACr*`kpw7HRt z_ifslJ$Wh!+mY{GW4TsX0Kd0s-sL}YIXuyQ%!T>Sx#TGSo=fPhKHOXRQG+EgjE_ss zwHK&w`4|-}u>OvEtLeFXWuw zN4)5Q{X-7;6YaZ&Rqp?^P?GnEM#K|Gq@V;@$V`F`y7i@86D zm*GpX7CO2bBc7}K{R3BS;r-+(e1RXMXy_O}qXa*D7FOt#qkWbs+`!KXS?kE`w-+Xe zXghp2<|S}puBBa52Y2Z!h9^?=Z%`lIZ3;{0Gp<)9X^Mkwb;K_<_V0UV(q8sdvwvy2 zEO(%i44=Er)fPQ%NG2i_s+r%JY9^<(5 ziQ=UCS+dZx^5ZJw<$BhP&aa&mIrxKqkI)KxYcd|ABT6o|)7@897o?PYnqPt^fzDT~ zajSJi?d$rIh)<~nZLrWY#3%a?UqYj`G&iZT>Zub5U0y0ug(YR*QFyL{pv1NPSlWt@ z+OA6|jpkOEwQt`$pDmwlsqfa*1Qn<13t=`#n(8~HW0 zck9(OYNZ$&JVcZpAt0jpk7c=Eyk@R7lDsjLht}+Ia8$uRF zc5k?!zO*aA-~5hT@>nv3@)FrM+_d@YNYA?B$YfL_0{vvDfQ65-9a%u>Q_k!gx?ZI; z+blWM>ZdTCg|}2gvz0q7arWWrH2gK25T&?Cmu<9QKyIpx;px z|7wwAuI6qO5xkEj_dsW2UgXU%fmK$n!l3!!Rv4n99ts`VLaI)fI0PDtcQfVLY>0~n zausdwj_j^sU%FaQS~fa!Mw&by+huyNH`{PP0*|XV0-~0o@Pl@&Osrpxw&k7MKkFr% z57!fR9Dgnn9J`455XaoF^C=LCDJRe4kmXL_c|5(4vZK9Z>ZL z+x3+N*#OD|#@!O`|HfT4x2u(f3Mfppgzz7>cyZjX;AhFf`4VL96R6=6Tb##NYe@G% z){ZroMS`sNvQJp^1@*SO_Ah#rQHSZH!`J{+W7p(H!6yEPwp8f#cKhb9i@8|BINH7V zPR?pfK79G81kDlo+>A$2;YUds(=1J2T&WrKkflYZ8h_#Z)J9SiM{eOV=+y2wL)~&) zd@e-z{-?Io+_JjJ0+T0--2=k54$sv$ZYdxQ_f@7TU%FV~80A%za~SjDyo#!s9o1BKLYaN7GcW?A1%p zB^iW@vWH%Ft2B?-P{|4L|DD%C^3WGaK@W7HgFHzo!4qT6@<*7-d*4$4_t>N{aTS!8hO|hAP2; z%AD08H`!hLVV}4k;+fmw2h33vgwE-4GX=ytY$wJ~XwHP5F!=|T=UFqz<-WJ&?B%_z zWZ$A*;Tp~cUToV4T*dkuc@6jX-<){!oOtuo zDe*m-7iGAJ?GwU;>JPgxOb+}hrvjC%+M)3WlP9!R{6rm`x|Tf&v6&1+cnjG9BT4BH z*}DQ^O$fj@@RiP)t?`9RE2i&q=lpC=0~?SY#Hpk!c?s*@KPnM8_!&c4lvUuzK2^lm zA`kJM(HDJmp5*9YNjc`JfB*P{;tRr|V%?lJ;fb%1v2LHbTba)0p?1{1UuCUZ@VE5| zJLKf6@1Ko5#Bw)Q%+jxoNI@~`M|`!w^1knT2NR+`w%;O?Lmr}{s>dB^tM##!%e)-& z$H?uk3fH0fx3L9@#nGBNf1MgZdMjc*=*Sc#k9vp}vNt?}5Sd)x)yYA5q}#i+snJY3 zX~Sl2Xm?7MQXxdohnLRKv?LTVFob9$`v)H%lVJVM?zFF9yZXBdv{lV786B458 zs`QcO66ZCfG}qx`mW`@&y%-7l>uaDjH~Rj1zVYFv!o=(*@+K~=Vr{{X-6nNg=D=?` zZ-J|*oc$cpf`v#ziXukq(g=Fq))CbFh{!a@?9kZt@|+iw%_;LH8a1bMhrTapbl1sH z-db@^m~1?f(EWAeQ{x;3m7j6`tR!TF%I89b0q#*0SBj6>C#p zzqAlpQW=gTzWW7#$Ac?Z^VLu<+F&w6k9FCnhK3ZijHIvI{jUZjrY6j!ytHr`8HS*p ztOK;u`GcLpu*jR$?dgMWT1my)IPZ{5TBaddmRpgNz z10qil_frD*rC+&;TMPb<#$vT^4B2j*bl{t9yN7bv&p3&=`C$%*D?YD3Uro%r<;Z+D zGzKjci*+$Q49nn`cTKfDoACWd>ovW$zMnOHNKZ?=n#QXtMi)9OWc_zXN2qW7;5k7b z*?&qwjhu;lJnAQIStB-HR>mmGXy76X;n#g*rKeY}CS~_R6{&PfeYhU8J>%D`i}18) zbENa5l}=}RQYKfEht#^B`!}I!Nf)@tYlDMDL(KLF_`JTl$-8?-W}1gp%ZkFO#>q}= zHBX<>H-E;qy-58+g<4tbAS~|5Si*qyeeTP-rE8_YO!peaAOXStq?O4q>(CQ*qlP27 zDY^5fI1JPIwwyY6vZ6Jn3>i4BeB)`yUAMT!jJ#ar6VEl3(wgpYFd$52Q@oGYpI=)k zuFB6Qri>eQJw!y(TWk3d{NAJI>38-Tvz+~A-7(%ZN7=qaw-9LkMD~=uO&%d6i<$Ru z{Y{{4$(e+M^1Wz>s(QYcygzF{rpM$`cg1(Dy=fAy{>5#u^r_yBGx?+#Pw_#pPn7Q| zVT=Te1mj1>l3SeL{R>V6%o@DHEWL(Qa2-Pkr1KE*%w6+ZzDL*ZxN>C?^b?vwCd%m6 zVxjlq*FDfEbw9}680S;?O|P55L!)q>-bAcaE;?a%U~H(nM|IASORZ+V_>}c&?lCj< z&5Y>gY&_a|8HL?s6pI%%17zZ)x|yt#knX19ZzS_Uif<~iX>0Dj4=zvTpp+p3ovwog z7v9z{6Sim`{k>>ve*+iIA;49^UYyx+;cZrK!!|4K|8-sMZ&#ZY!Fzz~h7koOO{G!l zV1z#oofvr4eo&adW$zN%XXit8W}BGwa9+0Q!2+i6z**nEABmmF@7~9q7=~*WKTYX| z`-a9P@!vcl1;Wu~n@^Uo;{Hv`FhzWO*!iNv`;toF<;)EU7=2Fp>b#T*I3EM zIrNK_8oTdP!btyPeLm@tG0P5tpPz5{=M*thkHs9Bz~^iItriagmZ%I(Ilg=fE`GG~ z>wGXH2O2ot+}?dkK*aD7xYZk5@f&mlC;DEZwB^0 z)N%PnN=z+FjPlSuUiyU{|fI;juSy6K_qi){tk%YFD|9 zIBDZfU6x+aN!C;QH3q|)jG(UYl}<@^<^tW_gH2o$WCL4o=7=;Fo6x?7oD7dPn)ysu7ZS?vD!Xfr~n+OS%o0 z4P)bt_lCo7iFIjCI)Wo| zNdk>hGmPv|L~V{NyAMO6ukdfR$d|~uD3l&MzpWbMP%GZ~=vkV;%WjPtIsf4>v)aqF@ZfS3FEoM?rSmP!UN?v6@Aq_2M4?^*BF%mhg+Iz>@ zScpA?q_Z*z9fe> zizo5Fq_m`oamnLKpg$MggImu%Tj z)Dn7G6e$$Fd=|oUwJc2)SEFK44(F0+w}QSp24OsV?r3iooP|sHwfS48fzZpC#1>L| z7Y+_+tbu!wkO@}!jomh%53lG9F3h-x*nU~5(1qf2n&#_DbiY$C=79)4KyNN4bKMO8 z>NN}lX_pA2Bi-q;Lw@SodkP{ciAZ9K6h=|y zTl9iiKm7Di!p!;SIUNcV9J;L1=kceNIPul@_NZRnE%#Iw>&y*QEzbnkrvpH3IEPkQ zuvPBx?^VuV6I|tbc7TdM&`YKruq^~uJg{B28KMD{AC{o8|JP;)n^!i&^#l_%{uWi< zE|2|p+wHMDm`yI4rChe%*>+^O+QHU(Zw?1B^mfs{JSXm?!_)SZZE6HQ`bm^&lR zDCr0-5xt(y!hSh~_1XQ)Qsfq~9?2pSz5(Zp@jS2ibIN{18ZA4^8o_D|zVq}AmUb7f zbsaXRIHZD;vXTqcJ+af1*TZG#T-%oEq1c(NNq`DCjz{iV@JY1DIBhSOURC^ zUXc9I5EA4)T&=*=WCWs@-6Z->ax`juP{(=bO*shmivvC{)VY*mh#O0{9e-x>JH3e& zrKPfH+_ZI-V%`1bx2zYxP3@v3&=dL&CmcV_oItyNTLbL(jgdh(c26d7$?jEQ zs_QKaSYwd~ythJKsV71B?SU<CTm?vV>Mr6x=@rX~xIDf(a0eZiyF?wcVp ze4pESSK3J=>bo$XX1$T7HI-vE)U(jM9e=K#zujVq`tF^b6JAji|AS>0){v0yU4sTI za&F;da6nvM2oNX``oMO5Dk1DZ1z}U^+DW`I?bTGu2dC1ru7d7S#A)F;6%#4s^z^Lf zl6_=&N*qW&6oUB2zQ*pda+Gfm7Sa0F$VB&&IZru7E%HoECK-p_!>G8a{5^z)V$4fV z>Qi`|rAh-)Kj_J_E>MJb{OWK%eDr00)9;cn(`+cXTT-yeJ^A=Y&j&J;cFCKX1=^x{ zcVaXiwq5v)Ip8=B2y4rfJ$*1UZbI{_$v{s$({hsj6U4RFL9ZMX@-^lo+A$JQ;DympGBMIdpF| z-@7k<%+0?Lj9C#$`xs0yvn-~YDMBb-GgA^($TIOsZWt|Q!d)ImoX#@t9j!ASa~@O=Z@8u>}0;~qb$J{G6=^K4=YmeN3H zQif7d8Kq&4aKpE0UVLezq#;>aRgp_&2-u)6M0q1XfNKG;cHI{smQW$k7ba#lS97LX*dS^-l*k@GZfC?7KJC%1o` zqcSdkA7!~~Sz!Bv1PetjNMR130B3!egw3z|Yx8TFV&9Y=xEQk3CGux|P>Mu=b1?*Z z2R0DS{|>~I9vH~78rk`!nGkH2a{bQ%80@#LvZRL?p)6u<8+mse@6J|DmMkc1l6Xv1 zD2Tt=1(}OQ!^ISaVRBri|qRYE8k^s{4mp0f1UxI*?#n0I0TX2%mlow(&1 zY$feYB952l1aeEfj|4dcoC$1yIn#Hj3D|4-wVkMG^i{9e-9WE_O_p+LqSIjtlF!_9 z=pGkz=_}A3OJls^^(Pv~l^SD3RGlun&tmw*b)|$!c^vM~EGnN2X(e@hxL1LHU+8c5X zc+a9x+`c^aJ7PR>?BypctjoQT8MqE=@J$*Cj(x^uVD?e{+dgJWV7Ai%WH(?hOtMH2 zRv_UM zq_UL72C3qpXZrQ-2NTPok4b!P(H&2JFHptj7n-0Tu8fjM{H8|Pgj(DF_IoeOEJ~TI z;|-KlZLC;MqT6r7TYDdIA^lvUp%q!2dlG(YsDQu}O0K}I{~o_>+lzeDUBfQn=94vZ zBf9Bxe3JN38)BZpxO=)^t)tq%7$4k`M-)SCJEwq135*}4yl&=Fxv6{ul0!bZI%2k}&M`R0cJPG?{$16tF>H9P2b6QB0WM;0!L$3bG`TH@O zx@_LqUu|r9ltJC%H<2OF0m;C2T{nm~)DouK?0@~*96Y#%MFHj^KsWVLf#;8EY)P9% z66SekS2K*BOy^wIEt>Q%0#=9?=SKn6NWwaQ+JY4F?Ml*4&uF(m&5|9(nMu(Kp7#~3BXlRzgj33(8XK>P+g1#Mso9$j+} z;3w4XhrlASa~l{%i{QFltp)A7z}2!=x$ms`Jdqj!ls0nG0^4Kv&wzqEj~szTWE*8$ zmJROtD@&$s!!L3ISgs(p-aUAKC;xU2rl8g}1rI6qEf@hG@M(+r;{!CGZU8T_0ox!@ zudxhgQmn8nXJJp#<6g74gNM6(>h9DfGgR>feERY64+9HmL99xC zcqgM1FJME!xHbe~U1M-jPPI2weSWQ3j^vG zatZ*9S=xQH*=Zg+t3K}D#^x5_p*p%#QM;Chvf06kT$~o{=tX6#iTxS`TN*-uCy&EF z!LqKvjsY)eVP+EkP}#)Td&dTER;7biduSY||MFD#{(}kos5T-A>x9wCh7u49V+3A4 zGpP#7LvZbvydI!DU4T65t;2uhDGWk_$Ji0Z_}VWkEV`~37kmR5H)_iBA~5s3OuFB? zBrqOh_2lb%c+=D;lug_wXgBpxly8LVZIE%%ED}Tuumafrnu4;E10ZAkcmFWx7T}X| zO&SnLAFXloo8h(r16%59Rq=s_w|f6E!Rat6#0XFXY=3#E8q^ua_}aUfmIPOfaZLcm ztP-|*^@zb4C}k%O9kCnvXsLVx9V< z!_#LC)CaHlANrU8`mnc(|Iz0I7Y4i;{20dgTKu#$xng`73ovFOGV$%QIJzHC8IK~F zT>sN+$6_s|xDIB1qY76ce62PyPu8+?D;~J{f+XJd#=7HjmzY zuX=DM!k>yyy4FNg2f_3%@=*%P>7VyNQmtGM)Bv$weTDbY=kym)9^9UP$Wsi+L)wb+ zN1oSV*zg#;!WjR$X3*j*#u`f?V`JU;<%C5=lFN1lJ=TWsmA%JW5i4UWbUIr$y4cE2 z4rWKZfgodEpdtxpa=F2<&aPpNUSW-vfLQPE-IC^iVAo5Fv7PEhE=!{NJ3_LX?7?WK zC+hjelB*?>-%J{a<;n@K`Z@CwrVjc))HwsxL2l`TKze{)a^n%;ExztB#=F-TpItHj z=?gICwuyF?KO3}XqE?aSkYb4<`w-oE*Rci5809CANsOp3U%IT;rdJd-VT80V*>@0> zUjhl9$9lj(kN*p51w3r^$B90IPQ>EO9*WTymS&dDOMx0k+k;6XGU{*ALt{sea{4ss zu5+>I?LfX*5KLDR-o9xTh~N^aI4pnbWTgu1Yj;~B|LCN;iwuvlCyes71kXzKit<+) zkTMqUuzFKhc=Gl;oRs~i#x|V6R&Se>MV|4_h4>gSMvc6Xu(i|C7~7M-n}#;Kf7br@uDA|u?pkaQ)5-BITy!dst65Y6iq zyeK`V1PX*L_YZ+G0D-1k)cy#>2_)Qb@(AyLa?ZHo`~q|&mVnRHjIU{Kc6hkE9ohDK zZH@+Tj1}G`7MLB_PSL@zayp)s)#?W+?;PHM2j&9<+rK6dklp_gi1P*rmL(#ZifB+q zJ9R77Foj2~_)RKJszAn~-C1yqbM4$z}$6nY@6y+be7y0;6uX>Nn1n{R_D6eOu%bac>R> zKs0Alml_@GipZ(LSQ&*g&k^s(3+N4j~4}n`;-+!#mY793* zGzNjUss@vTl~XZ`)T7?In=sx239F-`!>bAh!Jw9}8RPN_D%=Zz0&Z7e&oJ`ZBZ~+j z?kh{x1M4V^;Ps;YE?#vjH*l(BP$uOQA54aQ_y`h7%B} zvT^;7NDWmt;2Aa;#{9>BncHw)F;_tc4SUBUNHg<6uS#)yS7gya>t$(|`rC@His7Wm zemRU@B8Ev12$gX2LCz6IaKm26KhdVyMsW=(_;lFG|XQT zo#mXU-9;)Caxc#6*s3xRZmwQ($=~^0L!ptR=?{VpbRoh63x|QNTmu812>Y|rqbq=5 zu>|)*2?U}J?h`>I8B18?;-NNfYC(=EvMlO@4!tS_dJoL< zG1Ta8Zu{Xp;b_F4aU2&7DkiwdWXwb}zxM!9xs;{j~3ZSR3~tPB;fj&)n| z0r`-R^RNtkcFu`F2iWZiHQWpos4W3=VDZ1Q+upkx!@J+W7+8JA9X01H?iJT;{`SMY zVH(-el)T?hM>Tqr`VGSQE2Pk~%50M)KM)Og3kzOIiiDvpTtl-4&}@O4g!d62h~~e6 z*`RALpIOZv|?Kr}=gG&olNjs=q}{F;?* z0m;Ccxn9HIA1iMi!7VVqgmIp`#u=!Y|KTir0dQs$Yx;gmga3UZfd}Py5oU~EwcO2$ z_bLTQgAT7)Xpep7a-&?gM6#Me(n~oQ@Fa@*CtU3n+>#S0k$cbgo;2FZc(<>F?%$m^ z^s-}9*xJ5TA~n!1LAQ~iL`;2{QAH9U8de^>Uqr1Tff6Cd{X?P!K%xf?@qZ+GsDcG= zIgb9PSr@K269c`pF#XESbyISgBzE3@G0N-=J#yvUEx@uyicE2s#>VL|kyf`f1PQAy z{I5;^_3E|C+6+h-DgJN5b|}C!xGR4SfebOx}l&fJK^8mx*at|I4xH~>3i_$*N?J82< zN}g|1O5ocR6|vdPnqL^c6ev%1;{D=lLX99R0*EQU2{${Ag<($r*W2v)0L&O*hG<~+ zgXUkh9R3wk%o9SHe)>`?)rs1SI(RAu0$c5^R8AMA2a`FE=4z69o z)J(djW(>u?ojzcGmIgea5DD}moCG(=j)QTYy2e@migQ6B$XUGeMKdp9BB~b;)o*30 zd6tL+9qC{rBg)hK?XV5%dF28~Y@JR&hz7X}H#?4pp-o;x3%)|L_zt4A7^fL(OZIpi93BQ6UHpn60l?S0$LO95Ob^~s9p8!*9;+k4TfLiT~bHZID zUcoqz{a0suhAYmb)F5X=+ro`oUXP@!@GhdazP5%qZrK}~km&w0WL9cVlyOd;QY5VG z^8qoqjRE3}Wm^_mve$BhlccKO?!4fQU%YdHO)er(T5QF11=YJ3_6 ze*Z2oZwOI9TjB=M-U5Z^|2rma;=&XP{f9!XfI^G)7=IL^55$JY`8AC5=rzu+SDZU{ zK+fbf;|2E4MQtTL=HfJ4;sQ9Se534I*t~0IBP3Cudi_nc>tjj8LC#KWz;$3?D+;#1 z_M>XhH!!r3YiOxgX!NkHRz5-`qqWBS236a~^`_gO+n=KHx~9r}6;~X=&Zq-!I9BoL z|IWz+(PD4GD+q7?1Qoi>`G-R7fI|Is0}x0*&I?ejG>;PUMsG%4`Bl(!G{K9RW!jxJ_K39i^>rDI|co5A;%x~=fJR@zPn!fc75 zyi5Y(?{zp&9qjMtJAtsc_uz%^tx-^_i z2}|KEh_?}k3U4oz4#OL~hWFqK&m6pDz_NevI$=sW6?ewZ2MMn%?|_@BN*5hzNx_>F zg>^kMN7HgV4yO(TBS?T3MYpR!iO%Q$A(11n!u|XNTrUE9u>`8ZaArWpKP7U!qWl}S zDktfqQ~7E#A`w?6#zb}aW0vWN<;!^aMz5W2qq6I8VzBHf2Q*B=&^B+tyY!I>L;G?~ zprk9bNf$sMwsZyc7h^%Gu2kQGoLMD!Z?mcehL2f$7!WJ!hh1)ZBiJ!6rU>4%1>q95 z;1z~rc`-enLfJD=^oqr_yoB%hBX8n_N(-r9$F@Q8H&M~L73sP)Re!2RGYKFwi zaC+Ab!Mus0Ox-xaal_Gj$r!pv#K$1#H@xtQwY#tq3H17@IIuW6drhGh+x{JqaeG_)-&1x+oqC5;}oS6Wo?pB zKM{~~)&|_<_bm*q=f7xz0mBogI4`L^tV+V1p$Q`YwaPB0ic&y4Y2-i%FcM`j8P>EM>akD)l%QecUFW(DKyUT27PchkeWTcqAljK0yx_TK0aJ+k zA3ih=D3tW^;EzHt5#R>TcQDQ!*Eo+~apr9WInOEZAgb-r+k*;yorf%%@4S%X>C;6C|vKhz-#L z7J0D!wbCm=-~SUz?n)bi+W-_}%)@W*l>54pex{|f4I*%&%8A_-gvLcP{SIKK@uK!{ zZa4ywf`Q`m{~dh}SV3t{?f)T-10apdN1(V0_JUi61CMXfzdXmu;fgPm9prnEU~<6D zQT=UfS~+xJ6VY*ir~oaLVVnHBw>aUFpP#n%BM`}c2L}=ihyu31lyQgF!jPi>>!VJw zS4c5Hp%4iIQU0IX@%O+N|9*7e8u={Vn?h1d@@ziLUN8D%E+P4|JxJI}`sPUe+?{+T zn=L7!4hY)Y1c@8Q_%}zkr3g|j)p%_S?tzqMci{!_gXb^_vHl_9EFhugN6tSITI}Qe z|8Fy1uP8YjgoC}DeEw%IWS5#jMX-T^Z!`Y+I0tx}5dvuh9#~K?t>q?tI+fP-lpqJ= zH%4lxSS68!{lODR>yajRuLiYxKgQ=z)bWSru`lh#YzBexl#nApP5^bm_Ls!#&`&Ul z$*)Nay!q~lrbY&xcC81D8Q2=3U`nYNIqS}gc;~hr^f>sAYSEa8UW@x>wAos?U9taq z^qEqZ5T2(@I#j#gGtI|HTjYZ4h2!>DX|-ZS`s0VU7(&{@930T-vLCoIKE$kQS&F4> z;H=RW++F@XuFBEF6tNq)7b0iC#m+`@ti?6qmX2SkvGYuo+cMz|&Nt*U`B={L=e75t z4-JifyqlidSwPFEL zE0|t)tR3*iKKl5#E>0R*LL$yBGoz~ua$wDdxAGmz!<^z; z!NwDfV&8cNa4n*mTfi@zfnJ7yUVthCto>zBZD<2*B!$;TGIKQ&YM}T6%$ch%N_Kz3 zz9&6G`^nX+Z?+^NH!rBMsjFs=+Noka%_0lEcHA>Q z{$h;&Mt~LKN&s?r4R8Pg6s-MqztQbb5#(@u?U7MWnJW%{0x%9r|8Gj|x`=~Qs{E+$ zz>Cgb5jq?(T&&yiV=B^Q3`_*xIWydi})M@mD3sKL3p&+QDf zptDerkt%Sy^Z;N4w!bWK2igd;#I+p61>?#R1#f_s+>~$gX zf9)>+dXN^{1nc!$8ODVI=rs=b`=5F((;qLP?L&g+CC#v2^8f24|F0J^sJd;=zr5se z9kNBd4e+i*!I|s9D|^AG$^9(!5$;e+Xx1ReoU{LbF~9C5tcS2N)bZIhFNp&zBnRw^ z&#G1bFqd&ghG+wVg6%I=<)ED~<|Wsd1FI!4et?h5deXu5J~=F6Gc8{!k| zmCwO$d&uFXZimA#CvE$O1i-E8i|y+FH^p;C(BM6tF$I$QaIG}p0^F+p;{q!00df&v zRZULgk4{wLSat{x5ucLR97FRE)Vm+d*XtU9$S?u01pe^_nujGNt50T8HP?}%UDw*i~dgMxc`mN;#ZBD%Te~U+Wjs89F@zb z;^b|zN3LzWS~21&x7+hrHQJ4%G4Q?o-%9o@c671t-|l?k%X5lYc1XdrXnxbKmF^HV zQJMUk>o>zg{ED0)F7-ENbJPo=>N5y7LB$1l2C0<47-N2@5l*jCB*osjPB{kjm=j zOTXxVonevjd9mK-Pt!HpH{D+8pT7MBIUxV=mf#Nmo<_LT#F(NrL9VBdea5A>2$Ahm z46j5fW_pLc#0$A*@`Z7#a2o-lATF0kig(0xq(=@h#z}Vix98r-xAY{JY}L4WwQ?^) z*@)_DS9d}VRH6%UQd*}3XHNL5iBiXK9TAv8i9xE{9xaymW_oG(a4SHvJw~SpC!IGeyaY$B{ za3%Ig)LuhhUk}zI)3K*k`ETYNTa=h@MD)9_s-&j+Dqhh$mDnv+X{o2D`U)SP8~i?VOsb90q_c=hRv-^N(zDmcG|+7z?nnMyV5lb#rr|TM1;2PS)?F^%jQnMo>+bIBQ>UvJD{uhP1PGk z8purxFQM^LKSl27%ysl0p)~dSM-F74Kzm@> zlSrExUlzkAuy*vKcH)RR~H2Z4b&oAso_9hX+=bGM5v7` zJ(-G~JT@e7W>8NF?I=lC4?e_=3b7(T4Sy~mh9YIzn1rhHrXfZ7{?Ce-vx$^CixjRS zb*qeCWAcyY;#dl8>EY3d>S^>u2@i$~sD+04Z5PK04OoBu3RmIs%U$>WCN>e72jSn2 ziN5>w*&wo0d57DwqJjxZ@$83+fHD>-&)Y|~OQBrZdKr9$najl75j)@9i8b|tYF_TvQC3&!0QgBz;L|MTHj+JTbXH^jt44H+x^1k*# z6S>P#^a|%DH)STaC!tycGQhhY~tq#qV<&1$|or+!WhQ{RG zurLNfm#D9?cJ$;M7d5vd9PKX#yD9J8(1~6{yh-~78#iQu{hR*Jm%4FzZ@(pkaEex; zE2KJNDsQ4lgb$pEx5w$7%8}cK@LOr^b((G0DErxde;H}OWpg1iwWItQlPy2L;#=Fe zB=-w)!!60PPkmDu#w*X0IS((MvWFoe?=<@H3s*q-lwUo}ruR=rl<3f5Nq?C6Zr?k{ zeWyCjji5XuEV;EJa~RQp;V~mOx)uA*R(zD@i&I3~ts~bpV&UKQnyifX+BIS|*gCcJ zpq$cm-Qt9UXX8vbB>`31taF<|$w~2JPfquDMpu|b-CnFPCKlq-**vnUiA$aK+xXxx z9`bDbyMATymN2%yXdKV`!E%(WXNx`8M8nS z!;cTMRxdBNMDAy8KP_5$()_l~+yNi$b=s@Z(RhVmqNM5lBH>+r#iX`d8;H#HjY%N} zIF{;=2<}G%he|fec0UQ~eFGo!S|fBucd!+&=JANpVh-g;IylgvayWp!C8n2-0nB&3apFP-y?G!Fx0A_aG@ zzP-97TX=+EjPrX_I6fkoj@uTY$QR6P)QX?IStWzF-+ry4R=-&pA&#Gwow=4mrsJ4@;wyJ@7)*kF$7_4#-;u=xle`(k(HvpDJxtfD!6mzZND=3-fm85#2*aJRT(x9;k=h> z?3N%`peu4{H&jmz;{J5MQ(q>#+*#$QPaiu$`+Fowe%XQwQowSizI}?FfnNKoK_mh6 zL}dK8l&9<=L;|`HRGshYr}$+z{8TXHAH?s?$*%)d;I?$pPf{<}71`>->UE%gOK6T{ zT@w|^@zW>6uRkovMU^G31SY@yvU=v%9|y5+@gtY~M7jB~Jbkqc#rPtK*Sy)O)Qjy# z^8y|@h5+i*ZY4_0X@U-eUrDPxzb}8ScvsGORLi!nGDJrixFXiJsC$rBQJ@N} zV5M}Cx~FqyYtT^4r|fzT&U2$J7vlFhOm7JdX@k)+6o{7pcbVuANPdB>RO{bas*f_T z5&ijI<4>ZV=yC({2*}aFc0J}oQt%4FcqQ^>7zyd?$3S}XWx=G?O6QnEND1>=mxPl z9U=x2xoaWcSwcViyqY|^EKAFgm>p4|CqxxwT|=;a?>qw4mGlr-`tfsNp_){j_XiH5f`8h7)51!nHl<>5@~ zzB!-}A=}~+Nr+*qX3J~E`<`Rw?lOXPWbYU+_@GEs#JN5c2ic^Ru`PzOM8-2Y^~9`D zD9OzB0%0FTTUJraE8fVW)zvyYO~`}9WG1HYNi}HTn>6r_yN@_w2DbX!z`h26fj<<6 z|1t3U9xQm(xn-Dv&Hrm)UxO>*{JEU5-Do=s`X~g8gusN7V-?M9O44$T6=iYU_)f>v?ToY*FK}Qy zt~d|^L

1cLqdc=ns%m>9s>l-@+?O_F!r9*~|lUWt(l1Q2#l?*hw#z7KhacLnr|W zB3798Xb{ww&tffX%S^5%FC)>4i1uzp>T`7Kq<8)dUUhyQ8XDnRozY?6C zjbD@HJupgO;zIqP6P@)6Q!zgAdB>q;|JzO%79Ahs*L{!6J(&voPP}g5O!A?r^YiWX z8E3u1CM(1h{gRgaG8oN))2WfwTfHxWu{0&zv~G`0F)L`0KJ#|>p;eo%=VxQN)%S#< z?N~+Bfh~H3#6!@Zkqp0H8$32cnqDEyM!_ON@Qz`r>(13TugLp&oD@}2Q6VuV7l|5o z`Tncp=)CK1XGEWgPHaA6I*b?Cx_3o8 z=f6Kt5$SecG$q4`k!-#ghkOvemEw7q;Ia#udpp|ri|M2XPmBqH5a=NWZt&{2$2g$t zA6>iY;RzHW{6hiPr+>E&+~os$5dyxJKmq~|*sl8-y?nsm57Pr+~W#>CpY8r*(f`ep#s@6h!}SKw_gdo%8yPG{1i%i_v=)f zP4$$?X8+J$pN!wV;H`QYyzsXQ7g2X>zh?3mbqsBI+mp%+;sqxP^Kf*PJ*o6jc(X@u z`RgV9s|AO`eMIRl?Pa9q__Sw%cGe4XBSASvA->BLhuB{4Tp5m;8tiVx<-S=IIk-5D z|2DhNAR9MJuq0TInJFJ!jHW;3KVkm@OEB9yIq(UZYlyqIyrgyTzNb`dRy>hb4k$^F z0ur3N!Y8Dlu!q;q7C>PG9;%UD>@;qIcZKs>*2yX_A*Xwj6EaR`8H9>{QN9p^-# z(jOB3t8~CaKPaojwRL>?N7B4 z6TNs%$+bs9d&BaLRaR*g z;hszLp0exQkJ%jR2ikKsL#a_}O5SH=bg%DG8_7x%`8}P(pc!j}2EO9TSzK^-jI8;h zE3x75&c^dcX4+FLq5GfwE2#HgJj2K}C1?21`}U281iiUxrU>z4wuu_ky>@N(g?hVe z^j8#q(1IW5$_<p>%c%#YVV}&z0RGT(vz;UC13r?;FY^-F{^oX&l_}Xzneh z>;iEUCi`*-YAbzn6Z|T1N$9H3Yp}JT_X-nVj=38)71sV ztll!1L2L2tox34RQ9Whsj5+(r@vF5`A=vL94d_c0r&d2zU*X~s#F~*zk)6^+4Iju_ zvEU;2XO4WJp)2bX%=viUp_eu;WedUrsc`5S78%`F*Dn<6#oMu~KuUp?7(0z6W5ZhXj# zg?u(TpI+axd#=qv?5vS3bxx#kswL|fm@AmCrD)q1s>=1G<8pO9f(WXO4Jph|w)Y`+ zmo0~+=68F=f?R}?Jw8DhxM%o{#DgjJ=8tn7?wy#h8WZb$37t~KQ z{Aj9Q`pb9Uoe3LnG-0*15>Mq)G4wDyeMw)&Y)5R{+1n(`A(&l{+&uCIfu-p+AGV*t zndb<8hx!vUtC->S!)(KQT;oFfYn}aQvEnE6GC|za9TFZZAs#|VONuQHNz)>+cSWPr zoIGq3v=o8~*FWMMIO`BzNc?|%y=7dMTd+5L(=8<}-AZ>i(jC&BqBPRo-3?OGNT+m5 zcT0D7*L&aW*WYut`y4;a*SV(Fe`c*UYc7jqvbtu1AMjmC4y((t5mmCmU9h5(EOp%( z@>&@J5+9lqP!>C@UQb7?#}bQ{zGujJcF)5O78QXsy)U>DobyjCktHiI!AG{givvS3 z)cvYdv=Gu0cKwslzXJ?m+` z{`0zKT4K_KKSsuf`eP>t7iV8_q_S8@~bYVOArmIhCk-+jpffFX8Vkkm!rTd43zK~Ufsl>T; zp~>6XPdqESk?JGu=-9>`|{wSFe zGN`MIAbu+`P)au^bxA=8rE5tpkPC@Q%o{Cls2E zjwP|6?RE$~HaYUDbq z#pe)nm(bCDdvmNY9j0_aE+)b-!(xX4V!mu=ry`zj$`8TjZ|`hY8ce;&)u5+_b8J^M zP}0|08B%o~y+JV+2aK`*dxv;!@{;Un|JXoePtTJH*g`8A)>eav^j+ z|G#pv^cP(!=j05DF#2!G-bmzlsCB&+Y4XM(|ew6(Y zXXrqczVvQvoXIvoZ%MZQB!pnSL2HoA0^3_OTeX76^Ts3Kvqu}A7&Kf9xb2MHU2i=+ zG&YDmLisCJqZrGvN>9;{eaXAj>Rb6&Vl6+lR+l@2Eluh?yD z_{i-JrszAh|48z|x-M%Zx*=YH@8|s;wg%#u>!8oVO<;zp*SY++I)c@k+2m-}3*&U! z>TrA6h1Z!Y+O3bR(Xf%Zqi#+2S;tOkb+6y+QU!b%hrigYMexl360F4?8~TQAynRnx zfaB0`TpJ-9+yUnrp1kCIjWLm0-{nU5Yk_sCdSt{*VA#>?)R=G;fmQcC4zN4PvJ#Xb zJU_n{Mbsj>JrRt;J0~`WuUmtLz2Phv=lHSd$YD5sX)6`1Bb%(=FUN~kXJr}d1K z$1CvE$w+2xr8hFMLs>sO6zQsOD!)0=Bwx-C!m5PzsN$f(uITUc*tS13k46smJg%rOP67Z}GRGFPLnLS4`l~;I>Wz!=iT7g2ax@y0U(A~x8^vLn9O z0CzOKQOP07IZNG~3VVw0={=~?dS|s5)X5lu%aBEh+|I|X*Gw_No(y{%!7!A$Ck_u# z)T5sJm6byV?CA1F(5-~T`0z1Gx1uN=qy_8sXlM1rsV6fBTvLGJnC%Kq@07AV9uM-e z5q}T_IPO6MW*`AC^d|&B_C4af>>>Vmy%UV{8v?k1x2|n|S(tYd9*@LG1#9Dl2vG@X zDzZ*Il0oU%UWFw3KXVmCT=rq+z4RtyYfx*{B|m22u-Y`TY*URiTq-3n_aBA(JT=pL zZ~|z|EgB6BMp(>*u%*JO$$J5n)yK?Sdv&5ZwEE-cpA+PbwyoFu#EPaLG#vOMXL%~G zMNHE~u$O7P7Gj4czwiKhXWm*&n36Uh)n5*W>e~Tb7mvFH&L~PtqitO2xdQ0 zI3LqhRld91)SaL+>m^>a`syd5F-ECxViV@CcZAZ@iu8(CCf^nd>y-;jlV`@|g&a^Y z^rb{g5#tYDFIM0`m!A!U8cfmn`wryVP-TvvS{TtMD&mJAdWCD_yrYcTRB$g3h+XT* zI&9ln)q-=^G#6N~NfE>LB72|cK`@3<{BcfZsz$A?*nY;+QLqttCI!49c`)BVX3v(? z-Y~t=$u1{&S*_kwqZo#}H4Qm;g_{fce!pmQLPs^VJmkm*+^j0Om9nr5cMj{TLs+3g z1-uJWhR~z7E9Zx!u~ogAlJ#nDjP+|P@45@XiqsW7_4dbVt3JdTKjT%R^cMX|-tQNo ztgR?x#d-WEl$c0jDpwZCl}shN5!VpdBaCl)-yT!y|hfs)&M-oZ23 zclpLqOi5X&=R&m9%=4KRW2UO`l}RB~h=#96i)c;ykR;8QP97`l*XBw*k=~zgqD(Gs zJ|^fCwP<+$aFa7+AMAHt%_%fPzvR5Q-L+aCwYsWK1ihVN`OtB zrmRYm-S=|9Tn4;a=5<^oDKwM)L!JlOEA+;mqLJ*?PM+piL$oYQ!hntL>Ypt%AI%+_ z6}hH&nwf3IEVTWeEE1%@9j%6aT8qg(7Pi>qd8m>^hD7e!MhQ$Bx0#hFzKO+&Czxm+ z-ojE7q3yES5x6#0y0sd(^-B_^hQi?w=k_1{QZnGo%}Ta-St=S+Ft@&ke+hAyE`8yG zqphic($zfEVNbVUP>QwCULi`_Bm*`1DsgWH8rL-LEqW$nOh%c=S+6*XLafjcSncjU zgfx7-YZ@yr*o@FMg#SQ=)Vkkz$mm<{K*5QAnM{1%qlo}{srE!7K?{yxtPzWXh#gz) z$-4!bz55USH$IOjoP_$|>8M26=Js%0`neJ}?Jg*0>;#mX7CCcH1f0x*mN8XdsLkbG zd40rYnDWk;>2f{t(gnnZ9hk51IXizQR>I}AjP{_{bJ~y&YV+BG>ty4&O1?gAITBa) zjJmr)>nKEGPe4Qr_w=d=D>Gz4#Y7#a*uM1xd`#>h zX+9+P6*Ui5xwYu5`5`$hv~bfKD2S8v8DRv*0|D<>G0IXg`2(Zjd2v`jhqf&`D{Z=% zyoGNlPlR2I6vTI>Gcw<7BS2f?vE@wNycV%5+60%=CaaL_8r|;Bo~_Db#)ehnu2J=J zq-4w&pBrd|$iG~&$&Q4*Fvuwheu`_F7A4^ycqz)N_W#yga@_|i%Fg@$D5u(S&%%Fz zin4^-e~L2d6X?GkxZu8kW%$4ArSKoW4_vf>{Y7p5f+gq znf?S`ayWLa(SPFQ>#Bo$o_qrV9GbckiqK8wsbsVgg1K#QG?3r8g|(N07+|E;fZ3zy zY*Ay?ygsZ}d8(E7<~Y%xF{^g){p~%>8xE+=@9?_23wVNhAq%=IGuue1aB)r%t@e5y z`fcG6m=E_n9IV5_#Y*pc2M@@}AzDRp-iyZWBp6Zl30?`+zsrDN(Z=+tC>4CG#i&oE z2$2cTi_2K;&FlppjzbqjeiRi>$$UVA5q&q{-MR_?UN0#BP{O%HGS6pM;0H{F_Xy8y z7^EHP#p-KINAhYD;LUnPY2UCayMQ+BLxo!Hx*mqxmwN9pI`Osdj=X`Rdtgep{f_=^ zx?oFkVFNnhxQRp=U}QXdLqg0OkR(jaa+<`-a62+ z80N}GM}TQRF-)<11RONe9Z|Jj8C*(PwazHmfRPF%nC7QE@%@LKGE#I3POzxx?uK9l z-qWwy=DWpw=dpeWMguF4v@H`Taef0z&*tfKltQ;TGZ~6PKYJ?U3}dGk2))qQ5*HUu z8`^NKun?&e|pMwBl1ReP@Kes4wQ2lb*O4` z^i83{4J_tl8=QyveExw@Z?)&KruFAcO$Bws00Hn^70-5Xd)BEjUQ5%QXT{dPF`hjo zd~_%+m1mIf2bl+95jp)~gssQNV)m@8{-hqt4fz@vOF=8mmZJS} z{>W5UqT=GBD2~&!zNitw-7p``4OquWYCBv{8ZNu+2_N3kHxamso$H+l{R_l(N=J#N zS|?d&b?Q3?Z(A*=Z%e!$FK)nOJjtgqC!L63ph<*RKUiEr(peo2H z@|jxN3T~=-5iv1|JT8!Jc72{aq~AC#h?Vt|8~JEWoW)ycFE$UseNVrl&^rs5uyhwdps-n;B@$?4r7gT&*!~V)`g+6k%ZxwhnFgqx0J-uk(+kc%})U`k%}2A`$jR!rMA3)}y*s`b9hcFf&i%75ZY^8GM8IzJe%VQ2yN53b`2oJ4 zdUE95&r9|gyAMiQ50z6New_`I)G9(*k*Eb*_9{bZ1W?aM1lJ6u7wr(Vyid!2J;qgqRhi|3=K1yx--e77PFY->In;I*{%aP+(z;s#o=`gUXez zu_A;U!QYPDMUBb4o;a)bHJSoEI~o+0?94oM%U7-WLrq;Wi{RXZ3-Kda_7R4F9d^c# zm8&7wKjjfZOwz`NZ$P5$07d)DKE3}XCHyhu&=HstVt}uepHHHJcd#HX-e=GNVE5$< z{YOE;NBkEBwg0VP;`VO^)qrn5OBaiz(!Y_$r$z@=7Q`QzX~eTqC;9n$)`QrW0@(`z z*@Ngmox3d811~~0{WovL+yj4vd~zB6`$x!$+qh>*F9J_K{56NYdC6g+{}wm~_`Ld` zO9L9KdH5-*9F5rPGNc1{;}DGucm|fssFIi1F1i38f%01&?W>f-&Zy zTToxQUYc7jf78xdBde0fke30|^IJ62*YDg{;{v|`(^pJNXo0?z z)$+pPx^9%wQRZ0bbl>Quu_Ln-mUEw%bz@13o7y{S)3vkUYdE=SfB4?FHK@x#T5y6W zwxobbqxvW|UwAjKTg?{cCGec0UX^FDmroS#j)T1Bg*H}juc+?)JW=nrF@@0=sh5L2 zHZ~{qQ-xchH{)5ojp&P+nQNy^l{`6)s-RywO@APPym&;)lwvLnuFvtiA8S60>=y6h zWpkd1z2tE==}ZOSHE@|*KGQ@-#e@)iTw|LxYn44Q>>Ep>RlC;`G41wg&_v$I+scQJNoS`Ne7@lVAMbWHq5Ir4!F9^NB$*<`s+SYRjqp0)B1g^c#W|#SH zqxG1eCtToL#)cbo$$LXGXO=TNdBNAXTIxuqnlPEX0GJe{MZtAu+TaY`(X2TAN+nCy z@@FY3$clT^Qt3INnh>SWSnqIZTR&@^f@@&(;T1`%rp(}aY`ZjckM0QIMZd~fYTctm zIV4Hlto^nDCyIWNqq3vOLvVrMe`>vRQ9Ou(G><5hKsmM%qk9?Khlu{f+cC!xwepI# zwWjHecn^D@!!5WDi|~`}3I$W0H>*Q{{}pS zzj$)kGw$st*Gw}bk9F=5%G6a#6m6O)-nIF5#{%OM<*t2cHA2E(0wN5 zpkB*Pgl%rQF}wFPg%j&ojURZMAbUf4^>Dl-p}Lf4%(QojN->&l*}3R(ZZ*w4lncul z>1c(F$m9&K7Jh#yS8ljvVu>+?{b`JFbeUhu%ykeTz*vf?l>)MS$N6l!S#f0`;Gy5H zScH)eTVlOdm$6yy`^Ag_-vkL|2zO{42!nH;{+cKTUoiNO2T7nrkpuuGiZI~gW)K(6 zXK2725X3?BpF}b6NC?8+@;{#Urvb-M{&UtEkO%-AH8+LEKMs@HnS@Eq^-H)*$*Y>| z8D_;QAFmT6_6yZbrZ2z7%+2P-sDK|u*m9zBKV%$HpRux~P+LVaX5-hPoKX;^Vnpg0 zTwc^Wcx1E1(3M*w<6hB@-_@qwbA}5bbbb}Z){eHs*pRqnWIB>COzP^GEb{tDevYYP zayCJE`fe3m6wKwxRKIkMYG;BR?Ja-1;#Vbl59k!QPcFtKdLhOjMT3Bf{v~A%y_oBd z!C3#83zV`pZ+@q&v;*9;^hgj#;IjSOwu|5;Wd;8`WhDWAr!3ewP|Au#yszp)mCTWk zfSnfjY)*9JhcXyiE=N&arT(U-5so$csEB1{2Fptvyu9I{SWoROS+_iL#%yT=AF8o8 zJDLB?B@9|l_soyXctQfmz4@`QMFLt0tEZ|mYWYIRP}K26NnG@JJC9&!Dx&7jpewbL z%SvjryD6jqUowbf2%9@SbHtpaPsS-Gr`=A}8Xiy>E+ra$5owHOTN>Y8(u>VeLzB|C zZxs*OEhFGYCYMpAb>|2mf5foZu2mD&RQD%hZ3Qx;)H9@ZR|^=tQpabLv6XX#?moX? z3X4+>VyGrlZ(VIHQ;oXO|Jr#N-1v%wC!X8GVY)MXTS4VAhAaMN zmcMR;LpMzCPdMCJzN^bFApME6lJtZAQgi3PLrWT~)rxG#^yZ4p8)~IE8kU^SUk$I^ zfr-`Q{#@T-x0hs3@~aTG@Mz2v`jBz@F}CDEr7wn&@M4)ol6wVc-u3JM;M z$zY6R`0V^d??jQ12qfNyh#?GbULsuUza*et%^wjo86ch5OH|NLpW zLoHdO2)pf&Fc5wHo3J07MgtFYKQEI07JS{smlRhyKt#! zBc){Ax(R&homwCnBOyt}NJECJ6k$yI;#_d~7mOixtAa)M$#;%mL)J;8=%Wa&Ub5S3 zW3N4PdzG1{*Wr-g<5e^v-t^#DYNQg-v* zg#@jhH|!Mnn6u3z50 z2I8Z>U2INBa3nv}^4OD^-~`PXJy+R7w61=qFD%0Ce7Jb(`GH_CP6LMS#&xr1Q-w`O zac0js@eg?;wb$-?3kF*op^W|C?;_APQeEQe%cE9X&&#~E?7sI?h7H<-+ojGj1y9p+ zaW3hlH-a~+zb5=vSi(Pen)L<^Q%N-Fhi19Vu`Dw7T9N4^r1adjGP|xPADki`x|%q4 zH`C7zOt!1H!nj4Jg!;+dvra=Y=jYpTc-ZCq3dL|frONA*j`%nB(f!9%mkPEJ63RlV z)Zg<55cr)yh#3n+%)jhyhF>ta`@h?UbkL-|lYrHKQdYsp-~JGD1M$Me^MB<6yn~#L z1+^_*Y;kYJA6ahI%UQ8Y+zNw)>sM6owuhZ8rJGV`{}lhpNdF&%dJN%Ep--xBKYDCtFA^#AcH1|R{SRNJt`U4g$&77 z_wJyMzZmDOQe~lY_tUU*e>{^J-I++<2)ol?PsN_>e-kuR6cOyX!}Bgre^X8COlA9n zR0i!<&DvX&eM(*SYlB5YT`Ehr)>%e2(W}5I{&6~d0Ut-Z3*#`sy>6Q}th5$ircB5) z3AP+l%%%tPO@km0`V^NMs^LS_r)$#aM!kV{illz0OY!%9(tDSFbe(mJVwrV#!$q>4 zFsXjEbF@_pU>a9Fu*6neiA>0jFr#u#uH&O7SAni8ZHpL^wijK;Ee{>SOS%Qe%mD5=98UYHo z|6RBv3g-C72zE^+<}r==vrV2TJL1L6KFbDzvPZJY}u_BhoeXTwlw?hD3@zxW8Upx8~inNqP zYVGX9KyEVQ1z$VT;fT*hrk#KYL+SZo;+-M4?HfzD6=Hr3gVs*t8;B5-CyKVBmXm!1 z1j?hXsLDRSL+Re!Vrxu=tq67f1+(SijGfkuIDv|fm&{(8-v@qfHHX=Rlp*q{mLU4? zRiZ11e$XdZQ$$`#66t_Y2p{oqOe)vhMQtgXD@;1Qr*EycJiHg+j!H>$iW>50=k_d2 z*L-wNLiKm7OfOIXt3AUfjY>n`ExRS%#n)xTSfuS?kNKF`GC_SoupmO?*h^(-DWS0x zU9M{IDU`$R^t-6l6uno#R8tR3?1*K^+|eMuqEJL}8!;75C#`!VAT?Pdj7y4*lgqWK7)n=EX#EVGg+z7n7zTi0*kCNw?;*eMRh8k^KN?+346Iz%+aqT z3?{<`*0XqHZ4Brq~ z%@v#0!*z+}p(PPhKijoG62v$GbRk&-iK_&SNT8$Lhs6;5=afsX??!AO2;S=O&ZFPk z`AI0fJK;o>>F^DPK>8yC-&4 zez?`Pd7n5`%=h0phbYi1&P`zk0sn&~6YCX|+O)cO0=Aue9|qW@C>jzqxXxl(Zcm z^#(_*un|4UZWS0U1tDh6HVi-?c=7_GKlct`N{_@Zdk3+9BWAYi3u0nF5G#cN0PE#K zG_`D;hb9mZ+;huX^*h;h9$=^R zsbnOEFS&h@)au6HBty}~aG0CcdYj8nfBG(td~g1T*pHJ@Z+l-!H{K#i@bRY$#U2~M zt|ToQw@(Ec!FI=8brPFDwX=TPj(?GaV{-tFLBnFsB- z2hXD?wemH>jEOeMEper5ieQoubk*83%r%r9$0*8GZRXoB`sHKC+CqjwKbVAQC})uWuZY##jmZn-qUVNEqV$pd8Y1)#zI@BDcK|C0HF z|HypfxMw+ep#168@K65i*oOf~0Pog8^rzb(xgSYDZu_qDZ@1-u4nNz0?KQ;kz_YAHRE?=M!!r+6kNTCK6xTU@Q%ff8qvE?hZsQf9zV+*pO?7LA~G*L0fkXMnXhdriH;YGT7{NEgZtnbYh zCRNZ%J~WEo4y>A~53n01ZpyLz+DA>5RciOn+k@UC2=Ud5dDWiWol~Z55*s#VqzeW; zWw1=;WDj<@+Yg0A)LUMU_gs2UbM1S(C6wIN%a(j~TiiD?xKj6S z7IXC@{aVEK<+0k&O-EEQERL96Lmsbr9nIaDL0G0=Mu*R zXFY|Rt3%X3>c4yTJ1M>5hdYsod}}X-Gh?d)-o0*rYbg7=feH3$(Zcvd%6y+w_047A z!%XIpO7vSY{XuW!oXR`ORkKy5dL0$}nq&P|ivY5ehw=~5*CbSD5nrd1m7+|zz>aE} zvZ>t^7A4Fp9X5n`#UBfUoJx!1sbtd|&Q=+Gv{ZC{MCJ!KxZFlH4fazWdyRTdU$#Jt z?I+r~i;!i>5qrTy7+puqCpzmnY_YIaq6@Cs@^Wt%s_2u;V^n{3TJ!jDnF%+ZhPx|E zsi?BO^2Rq%>(jZ$N?>Zep32e(J5q%1A)WQNYSm4J1>I@(J>}|M?z2?6Po|Nkld_y!fKNW~x7Ijse@|W<+$PgP%t75BF2FLW~^PXq5p688( zCqne>e_W6k+GH#A)O@udG?m^n7P^b9*x@P0ZMoF80)>TRaUI<|%ElVkAvN|~t93-S z@Ug6>vW_%IHuBZ$bYEiuua=_M>R;<;b;u9^GPKA-0}i-e?0)%Y?Z(GZ-5e&^+Vkzt z8-0}uJ>|_CQ*0lp<5g`NQ@@e5vP?(Zla(#6B2t^_OR)7I(`&C0$3^SdD?l&${Ru1pwns7$uvF;(8(2zme*??w69Aw`NUfadG|jq5 zwMc_B0>sk=$n*a`wz+v3^Lg&{U&zaE@IraouUGwjY*Uhpdsb2f;>d6f0{|X=z0iN8 zG_=mn{=p$(_)yZOTRzgBf)JOv-l%P(=D>% zeQ@gXh|H3aW@vXJfr&5kB`Fz4jzcJJvxy1#$cGZHmo~xkbpWeF`DB(-f8r|kS|fRw zGJEFgC=N|BwgBJjI1=&(iNEM%H+&oVoS6oGSq6zTxT=QVde$>|yKb}Il%I`)3})B% zEZi*El&hjorGYnB3q7Hzt5c0TDx(Kt&xb!B_^k5AJ~yUJ-x<_!_mRt3(+6d3=dZpo zgDNlv6m4@wVA`CL$YD#;g{A591hJTQG0w@GQInT&#+Jvif1Ta%(PPWosI`47Y9ujP zEHg#-<15Rt9PmzuqxC1|`$7lt4N7`()^e=2XH;3=RGfa8nx|;e6yqDrv!Rh`Jvb{E zog0KGT=IQqj&6k^nN+li9dle4rXClpJk>BviEsS!!8OuJzTZ1V?rhOD*EkEnl%eg{ z!f{XZ_7no?k8=#_CftU=$$q%Q)mMp~V^(XG!=?DgOUIlJ3g?Gkt+>rR(GB~oJy(=v zlw*REw2prIj^-cZ zpCau8Rcp-I)wTrCZ{3TsZZLuiW_0r9p~ATGh<9^^lJmUvVe7#=*9XH`T6vr#h(F)T zxiOM=mc|GgIhVjF4%;U=fs$zGbVKIr?UPes3tN<_NIx&d9NMjuZ27?5K5 zYJRcw1N%NYqeo4833=7Io~e@|{^|&gkMj7@X8TxG*-C5@MbZWDqNuVkRNyRR!+`rQ zm_Dtj2zaKPT!OCk_Nf_n_h}TE)sOF{Q;8l%o$_^!BbT34Ah5b@G-^#7F&dl`Rh@m;IIW%^TbdeF>Go_~IY)fQXzglcZa_J(I~vx2~!JuxBBGRoP| z5D;}uow?0C_xhQ&FqEpwlv=l4tvGA@{7o=)Ju-vLMDy7M^3xLb&aSXLcy;sm*A3RB zpvk9u)k2Pmo8r@a<`W08zOIu1mW)MNH~L~G@G(&oo6Zf|{*j`IBtCLt`NzBWi?HHW z)U!0C!lZ+6iPzj1k%LvE^0iXxy0WqDC~(Ota$=uqvSM!@IuWbinuZVhWmg-%lrSmX|ni!AFF-JDh~VPAywYz5TR-RiT4 z%!oxY=LG|=vX{!{_(r|d*bIua!xDh)_6U+2{+Q?N(*qw#jt2*~@(w*Q1zDWTToDL= zKIFW96Sg!nd=lCaPK5Vflv>nKy*M<7bh=oB4G*Oou|z#rZcg2bu+$8q1p22ZANtnS zDr$GP_Z`OiCiyL*^GY$Z8m7#26vn%dU@VWrRAriSfuS`&-DJhhwVSi{Y~^V8U0Ah4 z@{e23@2BFaiAbb4${;lv^&i8o@+(ht51wIIoP1bc&NV6DN&d|rn7W0z5`=d<*(jhMDX*ZS^?oZ~94`Ck}sb|WD( zuPY7%TPTBb^a93uClB8R;|7S4N+xGfvF=XuRy%!dLY&&CmS*gmRz%fCEtcb59WQI*!!ov~`RuDe6LMOOTR8YC z(|HfPJK?Q!>Dvp+1mdBY@;PX<@XEwW>psR)Bd&QJc%~Ubu*mlF_6D@*W3iey)5w|( zMO6^}>{~fewft;=!ybz6c!GBN6jbAbnS&1-4sG@yza*$H>&y!EYY<6QxY@EF0sG!h z;MG3n`KmD%3EyIysADb9{-R}W!Jp;jq~@GJA~J5wq+Fd)srQLdS9FraiEiO}JC`j* zQGMqfEx+gKT=ag9T!D|Q6B?|)MJ-Yj4U_1C$6JnC%-%FqF@mZrp>EdNhUy)PMtC=+9^Z&wr$PLFzw#l~)0rzU+i2kA2@O3aq)?d^`mg znyX4WY~r{biW|JdbS^ndS10Q61rc>S;BB`cG$f5JzgSc)W;#*4!M;^#9R+h2W1(H@ z#_3e3TvGWN9W?w7?_rGT_L}g@z0j*sMj|}lL*kIVZA0uk<~PBvS@w7M^{uqReaN@V z+1CcHdzxK|T{2|wp-YuGIqtE8KWZ|nLZdE*`-+vM*)GN2bJK7se6U;uOf*D$QX4!k z^RpoDmlJV;XQ2*zo=0RrJ7eZ_%!%hai7X}BZ(`CA@uT%d4X;V;M2GT-q24!-jSdBT z!Q7@}e!X_lg<*E*_O5YrYVBd(t5O0=uzt3UFlXm%(YRXuVsQWN6YVirR`!WltoLH& zd#I^-ud>Al)lX>4vMH?&75Ar==TOqPvu~ zet3Vfq7c>!;>DYuqWQ*`>Z)WkV>~6L6_9?N^_F3EvKp!O`ilDQ3Pa*)uVX`(XW{PW zm#E-NAK9!%DgFAihLA@mq|c;qt#362-qMwz_EK`8B)r||Lv9m+_tU(PfmODy6s+2z zSY6G7gB*yzax>tyR3YUdv9@J?ea|yNRB8f7pme;o+vs=b&S7X(+>f%kn~M`@ZYOtf z85#?Se$wtz_Y0nGA|1Wa`*H0>;o#H^5ZMzll@V$fKi17+tv9&f+YvqL1-FW{lFhIf z@i!#Zis9K#>zS2)U4o!*TcZ4HYoAmWk88eA)JB_P@XZPT4dN#&)9>&4c7Aw$CC9^L zm@U+W{^kGbxS*c#ZI&-6h%39`0a?K11foBK7!dnN{Q`-9{HeRD=64X!ECYks;+pQQ zz6Alqnzz9LzlPO~Ezxq+UEGHtQKRWVlQsAQlJl>#p6D9B-eeHq#0b=e&m`IJEvLR@ z@-T5n)T$<=W2Dp}G8Gb_V)3U+_ny-_^18myGOm-Cj_LDlLxkn4C)R6tHQA>1W3mq< z@KyKUeqwSX{Q?4F{{{gkJlwNtB2blOb@dOFR5~L741pSh=s!@RawGG?1?PX|0=(|K z1NLf8(#{hJ{2GLWqoX@2{#x~HIOhKb`oz3>rbaM9~wgtm7Jsv#(iCbFGk%rK30TEnP| z(qFTn@JH@$!#`fqOB-huPD5@iSyHvv(F*SKgVWpfi%sgM*?I6l?2g$j2m~O z3Nr55*dN9f2fC;WI0m+t<|hDf^QkmYWx>JcCjl#?4<;)S=~M-e=XjfO-&9oMq^#Q# zbB?%Jie9cLmsV8U^+->M%qE9fXo2D2%8}N+sn;B92vqigjCV^&v=>2#8WmP?WN=}# zCqYiAZ}jOz=d*!EaL4sygJ?@pb0YQvNa9I^|1k~Z&oQ4=kMBUfsWAI@VNl%#^i8!q z$~~Q(>pwyD;P?t)1S~B;^rwfxR3B+xJp4y_@&9wdzNdSG1u8G-_Mq0wyEv_cp*ROL zI~?1n5LH&_Hs33s_2>kd{jxIndW&^ElSPNpUSqQ!_N`_oZTMa^vFf8n?c9E2mt%`1 zg2*O3v6}=`%WWpHaGyVrYG8srdqpR_G)W#3?zEWOxOpg_Woc~ z|7_uu&TmGvB)@PtM75zXg@U!Kulw4|e8nya^+Mea#I`$vQEt;9Io%#e* z49m|1Ehx>wx}enZ-C4=$jAu1(Mu>0x?BX}1!u&j6!+~)xk1(3^%Geico0Cr-*((2p z{o@Ih;$6d#2!BC>o-Io1PmP@dF^b+?z3H;Mc#!9~yI%o-O;0cMpI8gHX?}^dKaTR8 zs&UV1&VaGzI*$hcoaj`p#k`U-Q~1=q{`rwl0E?||bxb-?6cL%}gWDqOT~i-Lj`7@Q z1M$oUs!*M;*k6U?;thugGHBXF$Jr>Zrg>$SaH_*qjAq;lEqnT`@wnoPpf@cWiU~Ch zI_6@>fHG<&g8ij#xqX4G)2Dy02WPb3GTyR+>K6Ky?In$sdKq`ECDkmyX$zTU8ACb` zd==)C)`+ingu%QEEH{q${7WRG?Bn`6Iiy}Y8OHrwX+D-AW-gM{4{Y&>;+AdVv>_;;|^oF!5?gMPgB{AmgR0CB0y00#sB4G*F}gB{@X$n?Sm^?&7p z{rv0$2Ml)k!sVEZwf#CNsgX)SYc3WcPh_PjMPUVqWetg$Mnpwv?Ag9@G3YUuYmJ!p zOU-qY&#pwLdV`O(X`-*xjzSZ2|?>!wU!q-4j<|JGM`rt?Pk=(X?B~-V0IeH;7dKtw1h7%Hi1g!W# z^ry~X&yOr1oy&s$t#hpq&~kP_?%Vi?pani7naSF}Uf^BKmxioI6;-+E;df4 z{{3L^IyZR)>9Kn*a5P30((ryJ5JJlBL~FGSi8IfnSQ#~RpY+aUsCSM=5rH0`a&?fL zqq_!NLNI?a6rZ7Oh_)z@v0=ov$6LwaWPe<*TQA6Kb}R0eH1FY? zQo$dw0`DKKY%|U$@OAfW|7O{pp<+`~=H>e5tlzX7-`vp}Vj^u}klrqG?f!GoqJg!}rLexCl4c z`gR=5hHR+;2y9e6?4Dw&q2mwU5rqeyrCNe2?Qfy(F_ZOAvWM`ye*kQsjzl#^1dU=a zjTi&mz8{rV$AUBAV6~a3_71Y;1FGm+$E&ap0CyE|Q8#>axW%Vd>1CLTitAxyrz9T; z1KiW9{6wvnzeq@O@FO%=_NTKSknkIP7mB9Zil{Qk*$4(cSurYX?4c+Pt8Dt}Smdpb z8*nQ!hpLs?tf7V-gXJ0_d?;}>JTZ=Imvc)JYsmwVJZy_e8q{v-74aL?*- zfP0)%i*Nrds~|M!|A%LPF3x~Q)|X`k_;-la1K%kB6JoQRz!1|>Ba>Nhrw)BMWa{9a z*wQ65dH`Sd)Lb}%e=P{9eZZ@B2OW&}AYPE-=1e9GO;t!(U)wL%;~#p?J}F-OeO_(Q zOGShCmn1{OeAoktQw)8UOzuxnstLY9OJ%Dtkf!@7Fn<{u{>b(sBmEyTI{ub1su(CE zonpE*%OkeCR|6|?p6okJFr@C(daXJ3u9gH)`N4db^RKtZcpe`>WUK6=# zWMhBpTVwBv)GCm0-x!eo9~S;O(cI|)ct-_fOZbOye!tna0Rd}A{s#%0%k`3*s@5B2 zCp*=Oj_k6~qjJwVn_q}j+7DR+22hM*Q_KVN@*H{E?rt9zDVHhi;Yd(EQxsEZRy1Wq zh1RodyS{G_`2y`}Jg}z@lIkn|UyB;{7dL7B;U?hCne!wN=L0^H{9`iM-dBKBAl!lI zKZqLs5Dn7pDE$xJCV%Tj3EaA07_ZMKTqgN0iJ}EQ#s@OphfCub#!kqw)g$}+MWgz( z*yFsxxR`SJv~as`bc=ioWtMTP+IAm8vtLLHT-k-8YzlW&;cuqNIPYrd&1~d)0>ZVx zu8C};8hA_G1hZvP*h5#S#(@fZaDn}$?tBD)5taPkqPlSY7IhTphMP}{tF$zx$scz= zBQxsc-aurRh#Q-4`D|@adLF%Qox7j#wEfjic6PuwP*b&8HWD%uP%&-Hw`FY8cy(jf zjZC>*`*gwr$9z3X-3N|%X5)g#5;U>l`aG1F?NvaZTxA(K?28EObZS~`4gpEbh4t4| z%=h9VmH)cP1r*gaAQyqSNSuKGO>b9_-iIZB=ncHO{3ohel|Xu5`KEK3!}|~HPMflP z#fYW4mM}-Vp-{Pj){#mG{T6bVGsnAo(`aUo`$_#Nl%uW0+$AtHq-tMzla)vn9s7Gj zyOeJ0+bG-8CPMnVJq^_G3Sv9*38L7L-fK(T?pmCb^HQ(d`i4o>JYY5=7Mlo!{7X2Q+Gqja9;-i_3S9aarF@W58}`(XtFJiM z9`lR?qrdo7Vp`S+61CO%f57^mfK2ts|KcL$|GLQai#*EX#%~t|^FaT_MNhzLNdWrb z@(+c-{8o4fxb$v50bcWunXg>x`1Uk=U~u;@SMg!rmoO@QJgk5>v%!`#g{4TaW`j5*69DpXapBGMO!Y7rt( zAbuZ=2_G#u#4|h+9NGucTk#C$FFWL?ycdbv{*ZX>x5N`0pdB)|{p7=j<~82|&4fM4 zhdiCvUwx-gf6`MnR#Dku8?)idqIAf^5Gz&stSEv$=`->_P6_{OYJnG1EB)8hZpc7W zOMy&10pxNq2=Ny%2D1hUzB~DE!QGI53l6yn0^`s|{B%wBRFd$)44J6$xtpQkd=WyT zPP}KvAvqLO0fSAU^>h3BkAef#?5rQE33=+|`LAw*FS;rIFS_Xh8-eeC>lRiG{g<23oKW7?r-6y!!_S38z;8e&ECf(I1I}1)?3qWq0U*<%0d|o9sC-*CI?nATmw6 ze{@ot28un+Bs^%ml+fQUN3Ik*>3QmYw&6XWACv^v9+W1l!VH0 zIkpQq*@TFq;eA1B1*a?c`Ce^f$>Ab>I6SW?w0Z1LyN*vBx|XB;SBqFg1|U%v)&Ix; zD}O2sY{mnd9Wwum!oYvmAKm^{I1}k_AshWJ>KYv2d@U0LJcva z<4<}Noji7(ewJw)-#zsP&6=tySFN!9sGqas4FDJKM1#yu)b&9MJM}>QCHO*lfkgdL z{9jQ$fnNdv=QD8P+ym$Htp)QN*m{fEdF|YmwYf}=z7~!gW&4u=|F>nfHC<7zIQC%O z0e${!qI?ESBSlCt-X&NJ*B6pq)-0IOiqm*MuA96>5fqSZPWyRMRfY-2taIKYrhC-Y zM`w$oHYD2Z@@cV0NBQwb1~sH1fFw4^{%f=let}5(Pl!CLfc>bVe<4D0h54J_moIv= z{ib)-zj`CLg7h{D-$EFde=_u;PJQ}0N@3G;os5HMJ>fF+agQ|KP~Ae*XE#GwVNCwp zYo&)Q+Ybw(VP2!)f@YvND>}R==-pYypx6*@l8n)J-x8+_uu@e%@p_YQTz_0Bkr?Dppt(2u|=)ftXBd$ zLu(#wKi8@kNogAM&~9<;wQ0qvk6aUN*T5vRLNJAxI|^}{(K_=3YVweo<3ea zNF#K5H$Q7A6hap_O&jjhA!17o=g6yvh^*a{b*w8W0eO^Y)YIm{?#iHytX;V5co_Z~ z9wd)fVOz&h^9N3HtSv4XC3$sm)y+5019mVu*ha?S12PEGrWwlLq>r(ZIxTIlxoy?^ z!TStN28y48_>kjJp$2JZ4q)6dy7E88i;UT59DH)lkdd_Cg0v2R)T%-R{yN=}G@)1Z z?HxK}L(UUA9)A>XVUcH%Ftu0^N|fz`MV-4Dja&hy>!Ck?ciIDMaJ0vO$%j<_44fm+ zGfS{(zZq(p6BMvXno{58k9ZN8(LM_)t3e;bFn!*9-G;xh^PF6L<_8R^3s9y7hHO$3wJ!3Bbf2~X7Kn%UfS81gOd3X z{-U?*TYF>^%GFZ*Ow68Rh%k(vp07KjNlu){pEAK1`5AqFobeugvV&yn#_K1S(hH|N z(n@L`*Fd?RZISJyeZ8};Ecf#$VLj?XTsj>7D7>?@a(s;DGb{(U>9!QV#bv#1dyS2f zk3_Hh0*wzx-f_o#r4s@_dh zVR8s5iDK2){pzVNHq9?9xkE4`$4}>wNTo-#D?q849%ZCij(V!Sm}G%zTnQh76D8}O zAFg(~;FnFAlE;V0gRlISL&d2Z8Opyj?e6`cLS!>10GgIH0DeR>bt>GRgc}{M6~K_K8ryVHHMQq^udN zAoEU>It5{T{0&?4x)q9LBxd-Qud&9O=UYD}GxUq(w0+$oQ&w7*3z86H?3&YZ>9i7K zkZ|h6h<{7lA74U+#DBf0g#+kCZJ;iu9{oRQ+h6t-zy+usi2hK~3?><*;#SjdDz^Qr z;te4Hur4sDsmSC6tx{6`!7g6z^2^myWP#73bB0KLhUtT+_|;j_RGa5eWl(GY^{;hu z?8=zo$*Xr0bqIuf^?ZT#euM}!Ky74t003K{2q5}H4t>~HFLFryCdc!?a?}n20Lvd# zE>;(|4Ji}w-0r?NDP(azbhF3ET zPSA=$`0)dFY~v6Ud2?H_6RCUKv{%b9NeKQ@LE{M#BG&JCpZM)_}g5C5xoDbRy&E%InRG{Wbqesw@0q3Aq|D={OO zsHSBL`G>X9^b|Hi$k;O-6hvy&-)F+4b@V?9dz)Z$n$zK`$JQ)v+)C{i!97Z<@UAV| z+>+Qpge^&7*UQ};a_ZI+4R^^^Jv|bky11@(@Aax=`HdO_Ak*3?#GM7zqL_( zIR2G*a~u@CQUw_y9X6$vIT}j#Zp-_gRAk8`Y0a8bUkPe;$M)!^T28!WBE*wD_PwW_ zQ*Zhqgv5A&b*PmVK|%1UkUzK~0wl*f?EkS~{BuPC+)W1t50T$I2WWpEH=z9m{ZqK${!(A|_6hQ5jHUzaPR@KZ zH)ql7sfHah+C+%BgaJ8cX|oUeU!KlE!Yf(A0f3+1zR>T(f+0Ks9TXU|e!F1Ma`qxT za9GJ`;IKYh-jn$d=GjN&u7db(x{7e6`c}FOEf{{cO4iP;`xv_XhRkTz5lYvAi`idd z52H4z7hfyh|9X(|H=jXIb_@n)K|(5_GV}52qA7VUwc`-VlKMy3hF#6w;Jc1o)$hGy~hAemy96020HONh<-ra`P zS4|@78w7S^&TLng8z(m~)IJ~K$jukOr%&sHHUI3QrOrR(a62cyo+(|0Da5@aS*P`b z+YkB7i&z#8BnS5KUmNnWFB4qwzZ1N53OLjDf&Hy1ofrUM7RY5f@Sl?vIUqOr9fmlB z7pGqn{7swvf3-QJ1BIz%d4t7S7~ZJ5^qI@qn4SP8Q|Fr7)GuS0fl|~_xtyPPCb+jw zjS!XZKkeCR^fO&FFrk%@l$c%!JHY)qx~d6qy)&Posxlt=Rx~d!6oNRbD`p}%kdtr7VSG#b5W>zU^YNr0Q3_Rxu>$3}4W$nbjZaqgZ3ju&vEb(*ki_#ue{GS- zy&xsj~kXgN`-Rea)X@WGjUNf`Z9}-=AKde!cKJQx%=$FevZFXU4NEfJi%RWte4A!}r zw}e@DeT(N_QW3I>Vx(sT@f=7eQ+wSajzq^-h`c!Z9qDB@Sqc4*{l-6JL;@~G`Jh)$ z|0|;((Z4cIvw~zyJ=hWVyip5au1k_qVx=4PyzzEDcuINpjH5NoC6jc8d&G9oR_;&g zX|Nndt(RpbK3m=u)Ulj)_KEGFD_0ev;--^s)psDgQWcKtu@?#NTkmXL6MI7b&?(OV zLL)Z*uiX&&7c}_)M8l5=h(`LqXef!o0HlB}1ESyKJb?E};e`wJ|H8!+c(9)LQ3e?2 zu>>WW&am%CJCx;F92W3DR+Ez-se^+=%vpp107KIY{o$0FNYyW9{H=EI^8}jl00_1J zyHEgNo)v~UmBJmr@JaLzv50vTR+^+d61mtD0Et{i82|cd-y$cLTCy&2om)hjrLfb$ z16&yqG&0o&EC6_H;f4NCi}OkGMJ@W@)H+C{@T&rH{%;T;2g*oM1SzzdQt-Mt@Qtm@8iFGt6M;6v4wSc&)K!2(R7&FJjsj@rQ$7p z!n(>P5|kX2^bp~a1$_r5Y?gDr(d()Mu5r7QGEMibOa#m(_y>#G-UZ;{BSWc~$9U@v%Q}AcTR7j*x`#FKakVY=_ne{Xx=oB2)DFn+6<#cH`hl z2{`t8PLN+oRC#K943M7B0=ajr=PkaPJEx=5+S8yF)%8yIl|Du)TYp_#l8#FIKNi(vc0sHCVsrMLAZqS`%@pBLgl3N?hX#Hp8!*FHBFrNbs}wKo8mnoSE@g4$@IX}<1q3j3D^Td zovp+~#t&Ub{nIwY1?u5gebRbap^?0$TfN#?g(let>4@uGWD6kHn|s}v6iii%uy8H~ ziRN-OvHXlUQXIBnv@~4ioP)FPP(Fhb1_JJR#QTK^PEl0Qf-+-znlI&`Olwk9hSYev zq++P>UA<5nzWz+H>GpyuPnvtLK=yNw@3ERdLoGWU%PeCq-p-QpLb6VReLD-AX9lw} zT?EZp{sXK@T`er>BSttw%B1vq2C;)hFaw91SDh$*6alAdmhktt9JEk#gd@|c4G%LJ zPs|XlnHAWY$N(&5H~3~ezJ5sd<`o*9eEjQySnj)EQNz%y6!{ANvoKp8;+E*upCK+h z1tnVsyalGU?clDFBXp}GeANViD@p&b0g5`DsqyvPAhEI%x{TyF8q{<4B}{qS667J_ zrJK5X6;r0VIEQ)iH>|z-*bY6oILXB^<}0UWjPWkHr=im(sp_o)yq#6jdu=&l?YCcC zm2D)_d5#^w_!>GTVR07_s6k+a7krWcCtT-!#i}CFWy-^kVWT`)v6T;7(-Jhab0j_ z_69Y>EeXMbh(kZ+n=Hy{=;OvNh z2|Um?CWa9z1-$>e@YG3~5`|Q!h4q1tw?ZCv4qj=;ExMKcK0-~A%l2n&Yh_rx-5E|j zP4xs9Y1P#}e|VW5<)47)O!W3BBycL4e!RK8QDnkU|4`{pTP3iH~;Y-32L6 ztAqcNg01a=H>equR8D@Ol%EJNqnGS`+!)xV(st(%y z=ow45;?(||wU~*Pmg;;3E?0NR#qvSoT2iWLh#Yp$sZyLFq8jSCr!Bv|!sEBp$8w)3 zLURM|m|7QtzZ2$GKw=Zzz&m9znA0nYoWBbcm0OD~ee(cEA-sQq9a|q+syWF2DW1(a zN{~91^%nxQhd99->wQVq({xu|$Vm0hW&gBubaCUDV*3MkpE%497hGSKOwr$4V(L(k z4IM)QjN7(LV-W#YWR~=p=N$+wxu+UK!h^#+zt8|{KXX;YxC@F`_p@U`5fkwz0>BrT z5JB`uRtLC(MuL*e;|xj(!w@miigt2m{s1 zUxe5#qUHH(gIqQQ1@9YwjxQ@tFUE!9dz`i}6-x_pbQSDB50dpNdO@V0arn|i5NLn| z5(WzNf47%j4ZY---%d37!{T0ap8&JenevB!veeJpza|3JmqhT}mSFeEzloq7510r- z)JaK7qOQeAu?@3o^;M;Ul&UR5Nxi&Io6V)hW~CU|B~0m9-zn+_JMRW*(w#9E2KwL&ea4^4l#W1FvbqU$O?I&M+X)b@QazWG<&7kqo)bMLjIzy|38qTD3z!jABG!5QDS$SR5oU+^Q`SuQj&1kKs8J<2(5f@v-+`K?41fYE=Ga7ooHI^@o4okf_v0ceHAhS zcgOxSJ+{gsGpR7unhz@Fa@=4U`TO*`+K83_;v0dc(v=A9QWnmqFaG4JF)PH3CjR4N zKe}B|iY!uC@=&yXWsc&l5e!e^1h8%D3{z*#swvw%nDs0_1io6{%6#QvkjVt*cqtG3 z+}TbE5l1B$CrRL&UY@r+J**@Z&x!ysz#lyjYPOvFqa#Yy8?Sp)qkYP}4#tqYU*GzX z>s@Vc{W+R3S$EWRTim8<^$n|+Z>SV##=X*2`GkvZsmeH^38FAV4&dWYFoUS>5mn=C z7Ay}7wvykRUMKf7TO!CX{lGTu*3S}L%tg+bnRm#D%$!oN9_Z|^&>C+Hv=gF$JfjCQ z)+Hcv)h9t*GqzGw{H`?XS~y>SRi~YlSw{O4awd2q>pAAwzGlCMsc5*hKbm{_*@}fG zQ)CIThF49IFOb?ovH!gfKovuqa;5wj4AMdT2fdThgm@#)4D+{~Sd}%*^cg0eWJ2-g z(no>#l2&PcwiUzXU(j!&erd42-fnSYVQ03neE@rB|Dd^ve>$Ak0arM;l^y>1jy|q- zu!#TO@~En*-iCprggU1%0~B{JejxzzAOSD*dm?~Lcv5?bn8W`~1pSNuCITN-0N~lr z^nT?F1XOl#d%P3WK5yeqauz#FItux?-tDT^PXD;ocTQ~*pT{pBHK3Vc3O>e){X{X& z-hPOSw0y;nEQ&5F(aa>NlDRr?xyt-WmOadZ0QWNm?aHPa&5#jMXHUSx(k5?(eowg+ zawo1FhimO?tD1^Y!L4Rk0nMq6+mR$XIP;tLPREJ94qWx;e0JfHZPqBQz(;UrbadKA zD6tyG{F1yF=2I9mr~J+A_VJpgyR++w> zGK-U!SL-};oOP%282FK^NY}f9)b%uPpk0_ruFba7mzG%+sf{#&s}eLV1pb*^VV$?(h62sOhjry|~> zIn+#SE95n6NTasmEuupbb>vgz}qMc7#GR z7Ud=KGBdAB1RSk{#EO$Wo`Sa5yql-DHks;fE`vW&sG@~O5Q2r*GDh)lQtd8d;H?Sz zHS-yo%3TFDolsvtrQw{Xq946ADcrf;znt$MYd<#mJk(gNCZHA4dzA~T^fUNQd426U zy!qMmS$T)%7_B#FLFPh4z|aC=g@z7JywUSR;WJqtEbp#FOx(K&WXJ_jHdgP#Q3W#_MdZkH7u(zNt78=2Syb zTnBG|tS@&RBO0AZ8B3cAcawnWN{1|A;riKJH1Lb=V+j%jT}w3!KY zCH5bm=qeGE`4rsHg{4_xNsMusJ!%kK>%QsYfpfn5@X=@U&Q?JK&pP`<(wDhjsjZMK zi|=}+L>)GCRTabxdVv}UR%ZA<%hXX4tRDR=0T$(HP=QQnMhfq0$eFG=5ez4ly_;c? zW(rZ^Y`#*S5%vkdduT?$(xr)L)ew6nV=Zjq*x^R(4f{YvKpD*(Y-)N!0rHXxnGSBNQKP_i);RUh@M_)U&1#7A1PFYH_i z8gL)HB{y6{B{R-^1KQ`l+RJ>A$!2)KwEcWm=*r)y|B8|V>{4w6_B)fQMl6kCcPH_q zZT3Qgo|4fb5#)KAln{NM9!w`(8~0lhrO2LFwF9~s=)t8;8=vQxpeB=xaiwoXtW z9KK`^UarRx(T3z1P*0l50l|gXi6!*tgJ*YQ%(YK#CH_& zgHFXaY7Ha4?N1=FX#rx{69zhPj<&4z)MI_yTtZVcoT{kwr@mt*w?2TKY%8>{sn&a{ zBWsc4u)*Q>Q#*^dL$-@aZTor6;QN`I?Fr6)g`grP0RKfj%oh8q&!;e}~pL zks&eLexk<8WOlO}iAG0L5^lVUf`{2eTWw7REX?vS(SwK`^g_&#{ew)o5{_r!)&Uk%S|h#W_Aa zm3SL<>B@}SF)^LTQ`=Oh6fcoCHWKoQLnx}Cva<_rp5toLKk~mvB8#w&(6Z3NimY>q_bO>I1`N8xzN@I1gy%$M%K5u`;Vu43y z&*k$>ID*$wI7XZM5anP+#x)`sjbbXY{Pf115kuw3Bh}vEC{yW`M8`8ktmh zX5E0fb}VizyexXu#4`=9hXltxKl!WNR~}gJNGyCceqhIj zHdMs3;xoT4dfzboaDpi(6t`FH{L6?6MKi15MvsMZs$cGnrUKG`z^=AV|ghcjGs94Fr626G{#nFG_e^f6IQ*qQ4DxvN)`v( zOog7wwWd;y^I>P`YmbTaP|m09FKpj^ihxA@5JXNK*w&X7rKbb>&Zs2Y}%k+ zJSOLoDbQ{BRDcuvnQ2gPJA4G?6a+Qbs`F~MMP(1FfJ zU%G35B48zoQ15GUKVs|BzR9Emli`Re6*CS97gZoG0zgPW^v9+R>#LEM-bu@!`EY_2 z^m_vb=D&~TO#tt%Po{u4E&(};1DS#7cccMaPr#F=z=IHEzah=~@2bEX9eABqd<(UW z-Wd6s+gRdEZvze;?8yei84mt`9C!PDpN{I)=!>l1{*-kx1(>@NME3v5-GK;*0Bztb z1kvyEfyq5-f#j=1`mcPGDgVlcb_be?)QvV7_&N7m?y63uC&ywPwlW)3J~2`Nt^PYc0hai#kJ&bpam`5EUUUXqESk zBQnlqwvQ{XJGU4YVc}gyyH4L$Y@1oXDkxy4_@+?$QA!Hy7W4H3`Z@Vr6|R|0v#BK# zDVA@;*|<;^*^b(4sZR|w=e=(hO;@4xE>>v zIGe3B=LI2h=jNW{Tm(lUY8=PaJLaYmV5wBYQLUUV8SQkX#FSpJfuv#zhUf3hg*ffN zIayswXn)AjsF%9v_HRk^Y#gybD)B@Qa(`ATnvjJkGl#a1+iOLuuAAtyh=noV*pR`|4B>69j(}(|}*j5Tc5$%UGxB~R;>wP7eLb! zkX9MFwK6=YVq3E_XPhpawJu426{?;xCOpgO{FpaoW(3RK`x4{F0W(3E^%zZElbVpk zTqmtn7^nIW*lgLl@U;-Eb>BN_w1kxF^vDZZtq6H?M6+&)pNOcaoMyNZ`?jyq9VNlH zPuU83&Q?8J$o&aWytM67c}(W!MihWvSb=nBzLMX8X@<+j!aU|LB%%i_P|fY^Lz+If zJ=wdd&tbSHgd1*lOKYlR1Yv7NHSvl8xN)raW7_`KpeNu5CNZnD1qn?q-38y{crv@)$=b>jCCNS zs5IPJUNtLNGzM5oxo7qE&6rK}QPYkzpO+A2z*sZgbDbt(8J+JCwilvOamNd{`>Av8 z`P{!tiN|MH*N%(q@t%PVJD!?2+Y&}@$|BalN=psZm!}Q3FZxvrd>wGWE@207pSeV z)pDl;i$%$aL2+&IP6N)#Pt=c)F^b&`F!92$zf_OdhOBpNw&@=@K5=qYy$(Pva|U}_ z)t`YF-e>0wOS;Ov7BAws)!si51U!loBhSquwezRmPY`>6to`QVuQ77_1;5Ha@tb)9 z9z$yrlKv+~g25vJEfKVdQwM1;%?0+ZoL)M0k`4eH9oASS#nBtqzS?s z(y4M|$anbE`!3dN3@%7a4MvxJ^R#oW<6(ci^R0X8hEG&vSHaUrjT4_s%ll@*zzh0L z?Z;+RTrdBu6iF-Kb2>(Ba@0{?UW=B-tHU8t;mZ`ot`XHoZ8P(ndP2ftOs*oOM9p$Pb$8zDe)B()wP;E=OFNr%m~KlY?mB!ns;QaZ?hfC*WH=X zs2tyu)aYvM{LCq++hXM`@S`xe+2O?~exAY#CG7*#yJ_8B$W69!{N*Eoz)e2pKF zb;T6Iit}J0cr90+{st8E(u!a)iCo{k5f;ZLIK`x2pRQ6=_&ZNwDtQSUB}PZ2K!y2+ zw)G0Ar4;xqb%(enLb;Y7HF|pdwChj9;hH-|^R1sjZReqNfsm3AQ0=Pk&_Ac6Q=h~V zBfhJyXO6!9dLVbo_7UOx+D?KF4X;f`b}iwA?!FD3`M$OcPF5-0PEKum@|C6n{LOqU zjmeJl!I`7Frlu43W8-F;=2&8Q!TX)h%EyljtNVR6LOjBIn!N`aV?yg>+QVws0Ga^E z!`ERLaU~2hq#BS5zU(;ndXQxDy5Dph;f`Q*UjH;Gp`Lq z6!`YRL+-{R5YgbTo(%~rv|wflU~Z@~qYjRlJO-#yy-OkA`YdP{G*QY-%OR~loCPc$ zC#bZK4cMat|LVf=Z!sa*x+jEgOML1t5%)UjIdWWWXpS)ZIyy(9O$k}s$=@k;R!HOx z;eO+BFsVDhoImwJHM=|-JiEXY+B2-zkOhvbv4`Dx+|8uV*0m5OBl9RYXvV<(WE#+u zh6uow7=_I9O{k9!xRvLnJWoN#zCv81j<%1}-fRoyiB?Zc4PQoR z!W}Qkhq{nuM0S5ZJ#Qwe<3A;9_^VQi@{3$be?S0>I)za$iJclD8eP;16HL9xeZ`#6 za))HhO#=A^>SJ?H2Yyoeq}e{e$GQAf1#DlhEU6hx)}RTJF7x1Ad#u!C5??e7lCsb? z?7+d-OY`_*9L~)Vm!(w(88(r|pd)0b;p%iq1HleWE89#e3HvcjSwfFcNCk{Nt0M1A z_eh!#JruLrlKXREUm)?R+x%>mtXC#(S`prP8BrHfo(B_t(}Hc}-s)e-Eg&Ihg8w+P zwtNt3Pa9RoMld>`QTukm4Zp7Vdx6OV;sUD*pdQ+-yFtIo7ZLcxEy&Lqs2!A-t(6k3(`-)jO|FE zHRykT!shQDWrOS6zI!GG$8TIwG`F;~jo;Tf3F&_x!K35}&6{7tjMCj#50*Qu7b;_XjCqbHNVCA1z%whIlxUtU zu3=2rIAdV4!<=?{jJ=2%m zJ!*2)B;=^yPr?V|e%+JN#)QX&C+=((mj9Epvi#L_O^b8*LW(-oj zv`UYkH+x>@gKVDr*O`;tvQc$^y+%P3zt!k|_vP!?J`tUo_0?iQdiiRl8PwdJGIYZN6*G`ffQ#Lxh#lBH{f3R*>?1IpOk|# z;cYtwBDLqND;!f`r0{fm{97wVMS%2DZ9!r3|78KFVQ)joDV z-}DjpHb0@YOmLU`6=$}y)4Ps1<(s(IW@{;Z`|$B>+_=$@`pT^dUMFWvTFV;`={v++ zv)2RU5+2H*-vPh9U%UCrmUwf*+aFosVnrCtuzR-g#FuA(e&>37;3~<097l{=8}juE zwq(Db^gFO?hQBi3Y|>3^7gt`5<(yXi+!l|kW*$o}SsU=0#m+z2IZLKh=2mrbVd<@{ z4I_lav`7FB@>@CS@CVh4&q6g1IMV67bIfrWKcZVgJf22eZV;`n4XJdsy)B9_{x zB&lUW9}u#?2SyLMy-Yg--&i8Yy3QB zDL`=@xFN{QzDDVA-JPpF=~mg}^WgWcUaMR&zYnSrxi6<%x{oc1Q)N~L0G30&SKn!o z1J^D7RvTVmN(;CZn9bYKhDh!M^NstHH{a)o^7TRHZ4=asiWv_)3c7TIXo!%G1zPnu z)f7sI&(j8mB70o5NXGO_4_8$uyQM|E@H7D7Ib7DsyYPtX`+}2#5^o&K^JugTOL&f1 z5!uBw65*rG@;V;DdS&fnuWLVi>@q_43hMr0Wh|uX0n5zVrYFlaopUkDjbzoRpKcaJ z&ZCsB9}^pmJm`Kjh$HN#Y|H&9&H0XGZ%SB6sFH55#3ToDe_^2e|KDX7GWtu|<@;yZ zwE+n#yEuSLO%NBvmA{r<1}|mTZx;$SApb49(tAN=7Z=?&*!*F?%>Lavz|&1`tS!V% z5&jyi?n2I(cm7@pb9pVni1KUG_SYeft=IzN#e+$+rtz7R8tCn-9PTbHHkKHD{zXF; zt3mLx8|qRR^j5?k@_sg^%YLkl`?I4kz&o7lGXk;R(4w06VP{`n2kW-yc)J2}Ur8MN z(1_uB+l8}%vp}r5|Ef4#^;)##%xGxJAOA8(Yi9lGW6pEbn2c^`cg7ve!|nV@XB$ic zlH14j;X*HVmcW!?NBWU@S`9O_Y2b6Y)n=ov;hA|zME=`iMWmg9d35Od3CgR%%)&Ub z+w&a~NY3G6yfgZSUv{v%LKJ1Yj|%cUC9sYN@DKDOzJ@RAD25gFDhRq`NiOQK-&0z6 zft9sJ^@I;^u5qIO`tk%uSj0yvMjK3Uyr29XyzVwmT!5iugk#)2?WksNxeH#LM@sU< z3l2>6uCpF`Y&Y=9sU;g8W0i_AA9K=^SK?PG*|`WFnz#>*c)5D0Znm07DjMC_Gm-l< z)_v^}7*`$0;yHp3W4j~k98ppvG;QsnQ12WmhGA{r8qQryNqTal5IybvfJBhIEZmXQ z+&HOZtklFw&OsrwDc+>CPm?AYF;sHLEF`rXe1yz^`x?M7< zH%r(`WE$$DHrwpUT`7{sO}uZUj?tL@Pm0P6UnOFN zM0+s|_8R)m3TzHuIYn}GrwCXN>x|L3fgP$9r!pQiC%?B$9l8COB{kz!8Z1U5hxs1n zm$I>W7j*GrYQv9jqIZM{7oy$b1_omTx&mMpNZmTq0dKaA5s0lH)G2-;Q__UG;P4*(XX{XmDD2bh$Uknw_7pJBBsjqP5|lLlaKdg`8kWYi{AqKUwQ?xQJoM z8+@H2ZQtza**9=eRg=CHU|UCsCV;t?>Dn17birHzypICD$KTM=;8gvit*(Rg=e~jS zl#?4zZ3}uZ{rhwa`ZShrQY%|Ng9QLm-1#Jky1hs6H1T>Oi_v!p3lnk@(VtV{c`Uas z+e!_1=5opoezA(*tX&`C?U+E%e`J*tFH{@!E$kzqMm&PAl}d~gWL>AadP|B8?%WKc z*R%D6hNax7eTvkZYGaWchs&(=a5^qc)raa3_EkB+u-;r;yh#uIE8q4jVmLsdF6n7~ z&^b+nlW761$3?YR*1CI=Ea#sdiQTcz~E zyJG)>sSoTeL2*+Se%47GoRT(dZX9O*_u^yllo_nT=(fVwNG?_bOD0A1M+Nus;O7#U zE2O}^em8Lq2Ic&P6@kgXX>GXABHz3Z7uJY%p?nq<3l~;~1fGRDpN$?ZajvLHpTcDf ziEoNbh0{gVt~VzeYy(3LcGd%iJ4CK;Bca1&K6Aq-g!g)Xu zvwj2kQX8=B0?{93m&=pkOWC#h-?Hlm@UkCpp$aU!Jn@0AmWVC~&}X0SqLG*_W`-Fn z2DG1Nq)1a&%Y8WIYOed*1^*%0>gfT=-9TEoTtXUt@5^vOhf#Z2$pmh%b!#Kmh;!mH zjt}5nXb*WDR-{MRH>@vT$x#}6HLn~up-I-rwk*Y-(ka1(@Ey4B2a?WdkF>B*#-BdV zjU3Nbs^t4|sC4RL4tD#Tdc2G91*OV?rRq5r7ri~ED_^L^T~9)nWwE^2e2-Pz?t#P!}< z>pO}yH~mA_rEFTP9eF5JQUOH_Xg#bS^sl$i72J2sMv0CEL&}>sH%l&WGt35K+`(*< zg{B2_?YtstKAE1zH_VJ+*pv<53qP#w#&7@Vht;nQ%$OFmkef^kgsLrR6rSvWP5IKI9zw{im($cdiztVYGGVMsOPO%;L1yRRWRp z6xyoa#h|?(1-c*r&-ZEwbl)eqIwS{YV}xTy(=tU43rn zf5}G9^;14PWSu{#jTfE8@;C5dzKR$6VSmh}jwd_flM(+`FbkHk}^Pb z$b_61V@mJp63c)j-1@~-?D~GoKOPow%G>}k{BEwNBYx*ZmNug=XCu^j8|Q~JFf6$x@^7OygaOx{O_P`5Sl?C()WE)?5}8eml-wI67fQf+kg zZ_QH#j~~!@#tj1Di48__BBYFSV8ifI(o<^uM@AT-DC(K>&pj&k^TG4>>5^UN6YD5u zNzL3hS75M=(U)(SJI(3vei{rEU6?o(i(?A?f@HTt)3}GyxZ>JdjJLY$GC5TSBc7k; zD5E|2To(~QS8hq)t1NJw<3-5?sgDpZ3d5@XIh(SO+qCs~lj&A^UPm73-5^C4?mdwK zf37^N@F8T`67Op-L#EJA7E&fU-xn0wdU{!Xf} zn|5@r;3^L+yF_972>bwcvQ(p{SM5?C#hi5G?Fu|&*uUjoOMGUOhE)b^y&lU3A` zfkQyM?%|XZTh$__v~XBkX_oAcMI_iH*$n&ct`|8JPA@dgvaWkSK~@>lNv`lQ zUc7+)gb+D5Yie9{GX~1jNnl`-nkf#&*oJ%!U#q}jUOyDl^@bfvw;*;NSsSZUJ2e9cU2W(%Pk?dw?GUuU%Y`8=83(kf}f znn~=QyxY}MiCjeb{LoZc2WSl-S@_@KMcq7)RFL(0+QiCrzJc_WlRK6z#mlOT!@BP~ zhr>Dz`W_ZvBOF3Fm}2iKoe>0qaz&mtned)@pYoDRv@J-;TxAt2Znau?kP<^cE*M7` zAGgJ-@3XBImvZQY$R?I*Ns+q37;yKIEMMgR>+7xKs(haJ;X`+KN=SDrDM&~+0@B^x zNOy-)(w&lmbT`s1ty0pR2cC2A=j-{1@2`K%zq51AUNbxQ-n+9=tUuMmi1c#&vPbje z`S+RZixrX3d8v20N;wE$5Me9mUn^F{mlFMQC9g#Cv96qz>Ec*9;Tls6oFatt1=#-0QhF z{V>6k8p_j|o;%r~HF)RqSo3DDZ~LD}NPW>wmiK5cQB|QtwkzmvM@(L)shefH4JcyG zdA*C<-ZOaGr$B|#y7<9UlvfmfIQ0#C6Hj>dQ>0d;m* zgtUGhV>N)fhGzb&FWh8C!80+<7HWbY4X;(P;4MfDaf8ZS=HpHB8DD>O6K%JJw|FOX z(!00&g86;hxl}8IRopKAXL59uW%95dj@$!LCQdo@ZGC8mY7)$sWQ|xw;ffNo_2WW% zP83~m+$}>T!oFI>B!z}fb$dE)%?UGuEe@;ZECjbX!>Uq0Y*YEZ`<&V6vA=DYWIyRz z4;GbU7!BiVcesSzIt{T35M-Te+Rz zB}mY#0wV9{oE?S7r0?6(kG0W$tdfV~ZO3mMFjx%#T+->H0Jc?r+fa{8u&)WJVqGdIV zAwayj1fJF`(6s(zImLNcP9MEx9{~D~eE@EabV&E+*K(S6i~>jimC0avOb)0JpxHyI z{OE-HLCbG)jBSCI(*Rv)+^nD;z6v8xqk^kV1~tZbcJ9U`BjjW^Y|cilqx8fd+pCO= z?9XXMNk8k~;L(|hrJHN|$ZTJe`!(nc0O4gAwx}RYjnhKTHlK1Wh0E%bJp}vU$dgv}m(*>d*#2)rEF3xy-Y#YZWZ;ck9Ko+ZCz~HF z^$s2GP3$asKKFT+YQ9X#G-r>0s3fqx#dm1euo~%mr0%dC^dbF|PvHrIb*rObdjq61 zQuscLyrS_5y;{^x7Ay`kil#%o8=2?W9-y9GXpXC$#)2mWbC96vmDYW-O>Z#O`=t=~ z5}UrQ#ng`x%$hEp$)pas=lw9va9lV#`81X$;F%? zJw(Xd-=IW{7D=7g1@SxF9QvZ-&oL(V6@&{ZM(E8sSnEqEbP3yP>iKl^qv@U6 zn)p|tb>3U}7Fcz)8f))cj2l_?uOe)^*5uI%>?_{RfBNqEk!wh~=%rwim*`fm8=`JQ z^;XS|unUzOiEknLCA89e!(>ciC^YEVDadKcxco>{(>YtvLzL zCi3&7BlX1)Rpssx22Q1@*jrLKHiUU}P1f_QQ3K7whQ_UM2^3Wc;|>RipYN%M4S=ajoR-|1-g#u_ri+$%dug61`|#_WS5NMcz1nfIQDUMZA_ zY!FnumCvfDcgR`VIrdWIh0lr|ozbTOW;JLpUe-6EGtEYbdQ}Jb$V=$qQqxq1D$jyK zU0e+CuTX#c5bF4USI#HIpisxB2HoHWYf10>S7%kUOt6-PAOEQZ{~lj|5PVL_vtT8&O(m>1OED`S9(CqZ@^IxjZUU`>9kl^=}z^ES*s-pfG0d$8F1 z(G=bMw)h=6_`Qs!h27W$ZfLhwG=g`7H#l-QeC8f3U%}c(%Kq87!{WiKk6La#c=ZOv z&U-4PUtV?9h5JVv6%2i_jq}rg+8BuS+s61?aElTfouLeUcQ4Xnv8^4BBtBya*o=2(C57FZO)(%if;B8|Vi zV0k$ZK8=rOecPdQ$Kb`CkUA^}M*2eVpRKDcACS`i&7VMf5Yn*UNH-1P0ZpJ<3@neA zT!@cAE3lS|od47UY8ayjnvHh9p!JHbrcTZoTGZNU4MAOYG>_nvuA=Qd(cBBq%MCRB zL*|6a7hVI>P3z0tHHOq(mg#I*rOnVP*_WRbs=}S$;s^wZDfXjh$cKihDloZ5t6^yu zT3-k+#s?YD8?fYXEVd=1Viw!jQ?kj5JEQp8T>;Fy8qF}LWv}k2;(#10)BPd-@OtTI z>H$m6Udn@`6}BF1f@y3de%Tt}-EdoWXDCDc7E+jS5zCT-B{o{3%Hl48(Du$KrD zFPKdIuqgB>I-h^W`Q+uo7et}K7z=A1@k2&w%*KyJ?Xi<+;%IT-*6mTW6TfbJPMA9P zRF(K*B#)*7CtBhg7Q!HIu=To9V1LI`eS{814z=LURvm{wchQ_W<3NK`6CGYtHbA&( zVm0h?ti@nAyqVIlmZ z%@s!318E1j73 zn|ta`VSj##_&QO=tA-X#@Q@3Hi2whPkGrs`0K0NJqsXj_cF2FPT(6;f*ji_%)&hmjMcvkkkVNNP~mwg0=) z#C-pN67VQAGe9Uuz?CLN&#wT#AVK-ZFaMOg+fKNTzf!iTf+ zOe~0FVSNzzVBoUei8FU6p1{J7%H*kX|Xn@d1D_DJ+h(ti_lGnS4{}}4n`cwUKn0?OSKku6!2^n z4Vh>W*D;_b$mtmRSoY16$;UYKM*@pYLdOde-%>xcj=J?DN0BrqA0V!LmA>TZ~C za6UFMj^rOMN;b_)hXH{bqNao z;Hz9=q$GA}CVQJiS0zIMtHbOB&l#*hiD=}{>UAEd(^IO$SEX*VSkd%2VG&-fU;kGmY=w=qG80f zCX{&+H@VjHOM#Z}+t88Pv0KPOEye8Fu%HM8h@mB_)odcQlrot$Bzh$5O#hn361iFI znFz&K4li#jV|l8^2fqVb<2I$t-O7-TRq;|HY^m+Ssm*dJ{1uQxu+Z&bjEI3-~+Ls#0(oNPrmfEUK3kuuMwDiRUFFGXATkSO zTRGe=4}7tFe8|<$Tbr5lQLb;uJEs!T%|F0@f;&&mmEq$SSybbl*-u>&f2~~A^x9Ug z&NI$LW`ERY)B+3%oAIu$*-AX)bSWlR742EnL<)BGj@6&oF;#|*Q+*Pxs$QM)Qp6(p zPb8rh@z;6HSoaHg5cj?L@#-j>y=3iOnE~tfk3=rd?}hNwRzR5q4wdYUB%OzIUg ztz^;bUbTdya0f`+9H$XT(8WO>yHEL?OfwiI>Ud46>nCqcZQv^IjI`^?cQ$Z_u*Llu;NA)WEv~>6+=4b=A!_Deb(eoDe+U%hLI^hCgHwjw-#u{^GG!EqH~`j#f~8P!?HY7_yixXq*u^23yd{)r?*v6&iV_)-_R4~OYO4~_l=WZoFyiy7p}bA zSi32{3Tqd(Wims#k(BWyHX|k&by+>6fT|N>pN^w(U-+>&bZmdx=Wv=g-t8M=p0A`; znFJ99e;V$4b+nNpGWQc3K9zpU4Re41pAIYHWv;M9%Is+3(s3F3oSR`$&nsLT6gLW| z7L0h>b>XG4Y%YJCBKAN?y+L$zdS!m(48+kuk!mNHP5ipD@^v#v1tkhDG757|Hw9Gg zmG29{@>B9~(eS(+S9@dcNk3aT8?iTiKjkBxd?y&}P5PnUe30I|4EVO6B>bu> zc+pk7?T~IxtZEz3H;5cSF081o%P(3~ErCspztzoPfFuS}$I~oS-HHEmq`_HM23n|8 zhc4;!{mke`Q^bhcz7}dYnyU4T?Ts_n5dz!%Gsc6u0%GU}0fyCfatH&h^CbvM1?k(9 zJQlWQE5?>2lE@s*6CxVR)tOkn^>eiiX>i6oYX4`(ba=>^Tz_WFo3q~;GlUNSu+=?; z6LK;DvJ_qv6v{;)e;u1-t)=v#FS&sysH1ma8Ncl@w!_RLiHS#Ged4AITP1b?&9dQy zD6!UT6TSc;ny^t*NC74BU8%=uVC__rnM0C;3~K}T@CIVrhIYi50S9yNJ#jl;5?|=q zhbsmxSwqE=cQ4ZR+%&lPR7MdPr9uF8RjgO{gVN_lsS7VSnlxZ8^T= zQIQpXdPzdOb6MTgc`TYSjb9_XA*)`0q_wom&SA2kEJ>k@$cWd9s>Cnn9SnpH4z3KnDwa>llI#I)c_B#T~x^4WSkL=J6sfxi^CBNwGF{{Zn>{N-(F9HvwL?;a(~t2z zY+zaBOqV`8VD6YJ>80J2c4g>YBPVrH67@QH{zZU$9Bi`>#sH9#W+FrsP4XGkwCj9p zidVVh_4`gr)kEFS*{YL^wjxy&Ep6zkQ8({a940RdEgID>AYwQ;Fuo_bcX9=}>2uSw z2h9uXY!ioRba=>fop_P+3KHK52YCFXIP5?r`QdNzrD26W)NBoF#eHmI-iUd?!5%8x z=v8TqIvs;5ifzueQ5x0|{4yazID-LOl+ZW9J$;yZlP482+e-7ha~erPy^;VT0-sp% z;Shw4&EVQd?c|i&r5{uImgP390XkZ{@LbPMbEZxTTYwDRQ6*(j`95cSp}Fb|r=;H! zNEeZREc9g?ek*Q?c$*?rpE@))u0tT%lH~!Jp=WH5u>^Cb$XjyE5@8+4s4rVvrWQlN zC(ufVdFxdB>^6nNB{G`{<{O2EObyBknb-I3e%0X3#GCOGZ4}y6z*I~gjVh8xP7ST@ z3omP5&zRs+UL<@vc0L}o36(pDQp$?%MNikBj4X1?iEup!fa4b|atn%hbsZvxPiFeAdWFBsc4QdeLohiXekL>m)+j!a9GG+9$MwGXzE zHOqXyoU&0EXW3!P7`%?9ivO6RWTjJZbiuq&yNN)w!MGGMxI7E7E*&~ZvNDy~9b=_J z1S5x7gbz7+6-kT2JcJ2|aT%~0O?mh613i+7D8Bjl3vY<0+Zj(hO_Ilu9TgQVSS_5z zG;w%xA$zoEP^oxI@RrumifvQ_^Tp2+zE#$i?V)h11S%Q&{D6v_tHJGhqoOH6f%^i#hwtlKkPDkm-N~panGoZ?t)5CMApq=K&~3o8`=-oy)mKsJANeX zg!IRgE20;rxC7`Miqa)|Ch0Wr4Fa5=XfflCUFU@P8pj(Bue7jGUJRzHf1a?SfaU8P z&_c=H?q|UWJL5s8bi|4WXH43Te^#oM;IE0h*i!O@yKG+}EB&r7Q%k!(N?@z=c)nS<7uMaqDdnZ!^W z$f4L4)J^IX1-2k$+k3T zZ?4(h-dIa~7r&4e>eeXnMuu-xk|X1nWSk!P&KVNcN?7)4B3PrYYPckcvf%aQ3xnlq zi{v+lAKH~|GfSVjQ+poBTf^c&;w-cp3+jJxGg0z9Ro{+o*%ZgVv?-o`TV}l2n-z;L z=2gP-9>~`EeAhJ=63+kjLk>Q{*lW>{CD!3|k|&}L)Jo<|LnH1zPoxL7!m+rY@<4~S zM1vaboGUJ=>RdtEbhnvwo}q^pBY%t6Kl*^$vFUw2a6tK8JNKZt!inw!SA=AKLc{+1 z=7r!1EGgvPixRYECf*RL=SjnPMJcyR*@G`nkAoblxVRUGR2uKfN^m#{MvxLP_aNc= z*LGSzS?HU&bz@%&e$;##?ptF_JxF+J(Ar$jSVUxRI33()OKuWd;qz$|a`a%*A~rNr zeg}2VXktvNgx@(t`lZ%t9Diy2MRgkqGigVdAI1bJ-5~9Y7{BWBk#a7nv@IigAMH^w z*9^f_w@*T)t)Qbw>^xI>g)%!q(?Y0eF(+;2BSZ~B-{lN#lC`EgBFHfCl9mIxriNdJE^XWCJwS%I%__LLYJYk+JuE%5b`>fbCF-AEM+xC-l|m$jn_N9Kb);XyH8^43UnLG$G%lU$8<) z%H6KmhGwbwkaf{#0d)u&-)S>WUdA|>@ZJ_R+M(r(`lK!ug+#Aru2`X???x!n}fcNR@ez zbIxf)B4Mb-4Ixjq@gbgmvb>3>d)VmyZG0B{))6P$J2c%vVO|ZNBCoU*QcJUX%Xn-& zT7VQ}8X$orLdGrJ%FsgR&oXhHILhX67P=mgHY<&A&lU6|pAybId2Q3ut#-R8Jk zGRh8RljN1p3ZvJqi4+5qsKardXY0!a1=yXEYe0Qzd}!t#DkbDe!oq-nGM+)r>~KXfSCNQY5@^Tk=Zqah zWgt~cMToZ>R_Jg;?BIFi_oo-02T)x0C33}!XYt{Hj1=prj`N4%ijC#jPeZD?Xwe)`7LvMt=H{9>>ECf?~S zo~Z+Q&1VwYpXVHfuVSy_vr>i7%_!bgZZ`C{J@2mX3Q1f>rBlBaJu@(J`LwrMAmV7U z9@=;#pXTWvGi2Grc;T+AAM}MT54Y+K%7j}85v3Hp_#4t%6{Y~5)6KQAd|qGus3iUI zswT>>{EGJ1oY=GnkWg*g2EP0q6qtgrbV$Tz*eZ)s*sIE?v%dWSJ*|>?P&dUzo!MePXa{XqCfhZ(_z20S~6@M>uDzX)%R3;mDHPi&e8Esq}C_SDva8U57tnwQc^pU3>_BI59DV%rjTMk#zvIXYbmFHy5K%gqa%27j znR?lKh}=%voY*A^axaBOMJ~r`m@D{q+@Z95>ggM5m|WV&3f5QB)^B=<6AU2S@(k5F z=B!RQ3tr~eY)nIu7(0Xy9yHBN3p2dmo80>ZfNVldKcpw&0)!e(L6Ny|&u3*!)&>7q zV~`ru!{~o;(203`%3UCmy0^%mcB!(9r?rr`bN`dp_VnpkhbY5|P0>>khMDw=K;?jd zYV4&a5)s{4=QS*;7;#=+6CV{{I|zyFYG!a7h1g`gxDH?SR1##VzT1&lAld1`mvmQB zLAw8jVMoJd+WegVNFt!j!Eci==*r-!gOMHcoh^5^eN^v}nbMxH8KsMiJ72!8TbC!scc_`B(GnDzu80t}tC0soT7H4H_ZH zO*yaBQYJ{`HE;AK@|04-3EFL$v$!4zeT`-xj<4-JB8-)(Rx_rk8=IHo+i30We0Sj@ z`hHK(Z6PV{JvN2P=nI=*p~PM(d-KF#V<)Fo04J8PKfsM&$+{i_E~A_^%A(NKW4RK{ z+z4&dx6p?VtI{lPOcN6m7pgNxrWkV0J~G`>Y_1;S?~Iv_Qrd5p&g` zx*U*gkeg95Hj5c5j$uLWG}@6II8 zZZru6PaI-xco;WVK)5viutQC$zsg?oixva(=;VW$0x|IzG>P)K>X~SMwZ1|unt7Wm zI{1#pDc)6~E^ca^sd{}h9=%S8Vi}RLcU!2h8HE7;+(g)~iLICf?^k-K!{-QPqN3Cy ztl=;hqOqfL+?|oX#x-K_LHivGRzHyLacczf7+|F9v@`P`y5JZE`55PiFi%#PK7J)qimA`$%K8 z$LUMvyF}de)-;t9vE;epdA#Ris*Y4R>345vdZEdX6kymbVESyd@P#{8&K4aCaOg-= zb?fI%^tioe*#x%7+^Sq-W;54RGL&KcJ(U-tA_P7O@V5VK@>p-Lj|Mff+qZFXbeo*f zi|z8ttpN;W*PC8$lGp?xs*3Z3D>nEZ7y*1ysYQtw2j<~ABE5>kf*1`E!O4#CJ2apG zv?hb)aXx`e2D&_~%OC$-my!8@=M!SkQ#S4Xb~B($#fCKp?~el8;hB zt(l3b3fHT*d81%+Z`x{I52)gjzVR`tckI3^s2=Y}X?cMXrQe#>w`#m*l7c8cuN1i$ zIh~!#mv>FVG2A^MMdxvSn4&Oos9TYiW)s(g3oIK0fvl~C;2tdD}cXmpt zn-Sp?j}!T*sd7)f_HKVzdht3W6)s_FE;l}1!MMu6qF>Eci{JcQ&FWfs`b;DD(0!P~!p9=QFzU2|narXenPl`QJkbauVt1 zu}SkE?|L;pap$hwXG1zD>8#G*j#BCgB55~&f7(k**MmizqbV4h5BKS66e$Xp6w=`+ z@5K$=_{T|k#``TA<;p_`RgMs`5n@*Iw&O27(FBV4Z)R2f0x#kVt*b^;edZO}%TN{zT2y$y96|~ukDQE# z%Iu25<|Glm8i{JI&Bb+0ibAkE9dlJQ!V-r7BN?(ksBMtpl<4|E@`~)gKmD{zo_eR8p%{y%di>;vu@yg$aDt1Vhh-gffe^atLlvex?9pcir2 zCbjm(*!ptp@P-U6(aUJIdriLD7@~(>LfXB@3Ti ze^0y`jrUUz>#||nBdPYJ%%a+6M^4f|#Jt9(ouxTmx5(wmIuGl%V^v&;<`%X@A%<{F zG=I#|;L^vaV_s8y$~ zo(m(rK+*%oc@T{`;kFcy2GZqxLbbiyl0tT9n}a6k5Blz0`3jp(!?$T=hDGLM!x_fHtZDsh%{e~G=vz;osg2mVhv!aA1Esae*4$My8(%b!4}57P zU6W6KmA^HS|K_@a&|7nJtGS~pBPKyt;Zn@2R*xYy6q#n~Jpwj_m~-UXEq-t%@4mQ4 zhWJ~)X17DhozpA^{FZPcU5^Tfj3cZ}n#OM@FLFYA1-}bNy)7hdki-H7@Te&BDbCpE`_`PlBP$YtscY-v3zjrRC0~Z@BIG(jjR)ai%%6>t<@bg|g|uf3n%G9Iu>P>V zgxEnMoGsPo2Qu>>QCRnvY_&0`&WqHX_6(VL!oF@Bvm1jJggvXHWZ5c;Q1}|Md~}1j zsaD6hsz(rg!a<)ra3}h_@3lzDr``8BXv_)F_B227pp*|jHGW09y-umL+SKzttayH9dxmAtP>@Nddra=B!cMfb@7#2ZT=ne4r`}hBIob>N>I{Xm4 zeSZdTkO1KcRv&oThGP1aPUH090I47VVEL=-XB76vgBHpE)B-wfMg;lgu@^ zN5~Y|Anu8_lFefR9J}Tj@MrAr7He2^R>{ql?+Q+8#_JSJwqb3k|3De$9ucUPcH}Oi z=9fbCI6s9o$#hX-Q|@+rLDehDY6w%Fr5ICo*ZUOqx*WoW?K#WQPZu!YerE&#s6>8{ zzf5(*0iBC^0XseU$kdz%z#vm^U;%(Fg$g^H>>!(EbcQt(SfL;>D|&SS^Hl#E9u&d? zdx6F^wXM2l)3KU+RT#g})(U}wofap%pBKXs;XkU5*Yt^YQ52T1i#|*=`VOTpm;0Mr3Q0tOA_yB;{vy*$pw|PL zZvM<`|4$44oq7)lTRRauMKg~K9Ym`@w7-hS3E8(fyx}xNm-Mp~u$f*+NdI!);)Cs8=HC zsdzHag)$nHoV|kAczO_&kq)BJ(7tAn{{MXo#`ihXzwc%;m-O zN2Z@_XHf3@M$Co`cNxKBPs525^Tl)3HRfL#WHi#WzrQOA2)OW{%$4!Id6xEFLID{! zFwc-lK6G8B9BkFs_GV*Ozl<|$ zLHyVAmi`ZpzyD7y_&|Ci&^~B8=A?+SJrbb4$1wyQaJ=B14Yuy2?_VdE2}!}A$6X$Q z9s{|~1mwDY2uc9pD@aT5^}k$4^spk0*8Qgz{QG`g(6y0n43c1T$XESYcl9Jo(ec${ zV6_uKXn+-nXkht^Z92e!2hd+1fi?lTZVkjX0{;&n(Ad)*4JscWTFmN&(%dt!^eWho^FH%EJFbv0W57W0 z*r0Pv-|#uXuuueG$Usg>`#m<*SJ2o2MPE9LHpyR!Pxgs*cLV^@lAhB=#{z;62qz&9 z+@uV)b#f(K3&V20Tx>S=U8ME*5@lTUpI~P=>CJy29pcwKzIhS46S86$hWU|zf-9)E z0Ef}qEiF}3W9cq9rzCcq&J{o6eUpOqv=B1&I_+A9#>aDOxDwUm)loYS$fDubh$jFd zVI&dESF>s6o}y<(sLBW9FQtupFrzQx;subt#^>G^>q(Qb-Jl%V#PSkP8t)Y=;}r}~ z^$w0V$YBOo1PHFgFfEPP36_=&nz1{&6&;q~Cc89f3|pqw%jzC9Q+ey6=`g)fqtm85 zhd#i~*Sn!Pk{3{={ni~4tlg+}=U#dlx=r7{SyvxXcDv}}5s7J=;NVwY0PQ^QgHWYp zMHxvg_3AWSu+T29eCz8wJvg4>!*HLc2-6L(x0yPNSd95+9j_L)r_lYCzpmE_7NB-7 zu{M!NF~qA{TNz+`=dOpBv-kUnCl+zE)=5t2&ON(_QD`ZeMhcgVHZ>`Pn5O#X zWxzt=O%mmN*ugaJHh@yLJ=D2)x0<`m*A1hhn@WMmk#bCOABl+(cYOr&j2uT3Xrg}R zV4Ytkm`j#xPUR7zZxP|vm=0VP8U0V^-ilstxT%8@?omQX1HcDX$b7sGpF2?q*t47H~|-em%vA11w|&uXcg zbK|X5mGTyW^jU@JIsS8b>)Z6tbe-FM!_fVTowTA0PqLk5zjbpK6PhjfF~5Qz(CbvZ zDG}RxyQyM37WHw#p%0kE5x_sh*%%LHPxmG;G z+C?o^W*CZbmb(&}V`YOcc3+eT3c{GjebrHA!O@P|{69(huacS=lwM!Jj$%GaU~7aY z_@ba%ZtRZXR~md7j`Xh&gP@0e_2?TFU-Wm*C>96h3|=U9__|OXHt5m?s@+NrmRoU- z&*Byzya3m;*pjMbBrSLMr2?V0Bo0!Y`{B%5L$i19FJPV*&jgE~ z`Fj|pbON=h7wo$`^xCO z&-PiN#aQwkSa!f?#a4N!eOxeXDD8TZg@`{JpizI&O|~C3a5e31${@rcuvnW+RIaQ* zA4{=+GIP)`QVlxj9v8=}l2?-r?w=>1SI1jm7UPJaS-{Y{r!x{iZr^?K)L8`2C-o|D zMc{bk5XO1)J;s#$PR{jaZ`m?c&wr=C3b{Rudm8kHTxg90>y?Fq4GYkA>mtI3sbm zQoB;&mn?iJj3Rq5ygMt>GN7odU6?l*(v6)Ui{*gz$k*rM08Wo#BVnA@3c0z)%+)NzV`?ctNsJh;&MKU@gDdNz5T@ymsY z`7r-_up|7z_OnMW1ls1q%=YSqqlGOlAW{ zKA3#>r^!U1YdF75K0kUe83AN6xi8qLAkF`|6Z>~oe)nJ$#D5rt2{Nkl+VYoCPKE!o z+wixR4`3}{uK!aD21tv=FD?DP|MQsp-yb7UU}#makDy_KpnU^ From 7773cd6011191c999b0e17c6267bfc5f63fd9f9e Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 23:11:52 -0800 Subject: [PATCH 075/256] Wireshark test trace for native encryption -- generates a binpac error --- testing/btest/Traces/rdp/RDP-004.pcap | Bin 0 -> 142910 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/btest/Traces/rdp/RDP-004.pcap diff --git a/testing/btest/Traces/rdp/RDP-004.pcap b/testing/btest/Traces/rdp/RDP-004.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a26dd5637f82d2d4ad3d74b79c84814644c6ea53 GIT binary patch literal 142910 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 literal 0 HcmV?d00001 From a63d7307c856dc6af15381e5cb7bf378e2450e97 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 23:13:40 -0800 Subject: [PATCH 076/256] FreeRDP test trace showing SSL encryption -- RDP analyzer does not currently handle this and SSL analyzer does not identify it either --- .../btest/Traces/rdp/nla_win7_win2k8r2.pcap | Bin 0 -> 134982 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap diff --git a/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap b/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3a6a2999eba4fa36f1655a95464494db44c8bede GIT binary patch literal 134982 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 e_S;kcZG8CMef3`TrFsiUL3u2o@ Date: Mon, 16 Feb 2015 12:11:59 -0800 Subject: [PATCH 077/256] Creating the installation directory for plugins at install time. --- src/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 13c6e45006..f13a4a6ebf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -408,6 +408,9 @@ add_dependencies(bro bif_loader_plugins) # Install *.bif.bro. install(DIRECTORY ${CMAKE_BINARY_DIR}/scripts/base/bif DESTINATION ${BRO_SCRIPT_INSTALL_PATH}/base) +# Create plugin directory at install time. +install(DIRECTORY DESTINATION ${BRO_PLUGIN_INSTALL_PATH}) + # Make clean removes the bif directory. set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/scripts/base/bif) From ff16f6215ad6f3cf8208b4e35756b75410a38403 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 12:49:54 -0800 Subject: [PATCH 078/256] Removing setting installation plugin path from bro-path-dev.sh . Also, adding to existing BRO_PLUGIN_PATH rather than replacing. Addresses #1312 --- CMakeLists.txt | 4 ++-- aux/bro-aux | 2 +- cmake | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0ff6c09d4..04ac197f74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,12 +31,12 @@ configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.sh "export BROPATH=`${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n" - "export BRO_PLUGIN_PATH=\"${CMAKE_CURRENT_BINARY_DIR}/src:${BRO_PLUGIN_INSTALL_PATH}\"\n" + "export BRO_PLUGIN_PATH=\"${CMAKE_CURRENT_BINARY_DIR}/src\":${BRO_PLUGIN_PATH}\n" "export PATH=\"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n") file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.csh "setenv BROPATH `${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n" - "setenv BRO_PLUGIN_PATH \"${CMAKE_CURRENT_BINARY_DIR}/src:${BRO_PLUGIN_INSTALL_PATH}\"\n" + "setenv BRO_PLUGIN_PATH \"${CMAKE_CURRENT_BINARY_DIR}/src\":${BRO_PLUGIN_PATH}\n" "setenv PATH \"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n") file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1) diff --git a/aux/bro-aux b/aux/bro-aux index 3714d3594c..c011f3a724 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 3714d3594ce0d2b8a757c04e6e7d901d6b559915 +Subproject commit c011f3a7243a8a1dc8be7eff2f45799be7ee85f4 diff --git a/cmake b/cmake index 1316c07f70..0147a2e05b 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 1316c07f7059647b6c4a496ea36e4b83bb5d8f0f +Subproject commit 0147a2e05b613a044ac30374874acdb8bc216feb From d36422fde156caf7d4f2cddf3883d1812f3fb7e7 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 13:37:59 -0800 Subject: [PATCH 079/256] Explicitly removing some old scripts on install. Some scripts have moved into plugins, but may cause confusion if they stick around from old installations. Explicitl removing them on install. We had this problem before in other cases, and it should be ok to help people upgrading a bit here, even though hardcoding these isn't great. --- src/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f13a4a6ebf..6d24172b97 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -414,3 +414,12 @@ install(DIRECTORY DESTINATION ${BRO_PLUGIN_INSTALL_PATH}) # Make clean removes the bif directory. set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/scripts/base/bif) +# Remove some stale files and scripts that previous Bro versions put in +# place, yet make confuse us now. This makes upgrading easier. +install(CODE " + file(REMOVE_RECURSE + ${BRO_SCRIPT_INSTALL_PATH}/base/frameworks/logging/writers/dataseries.bro + ${BRO_SCRIPT_INSTALL_PATH}/base/frameworks/logging/writers/elasticsearch.bro + ${BRO_SCRIPT_INSTALL_PATH}/policy/tuning/logs-to-elasticsearch.bro + ) +") From ab3cdf494a216cd20d528f982af3834ff4623695 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 13:40:21 -0800 Subject: [PATCH 080/256] Updating submodules. --- aux/bro-aux | 2 +- cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aux/bro-aux b/aux/bro-aux index c011f3a724..63675de3cc 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit c011f3a7243a8a1dc8be7eff2f45799be7ee85f4 +Subproject commit 63675de3cc7bc3eb2a3645860224c372d3f7f36a diff --git a/cmake b/cmake index 0147a2e05b..9623367210 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 0147a2e05b613a044ac30374874acdb8bc216feb +Subproject commit 962336721040fdf55a6b264f8bbc84153b54d9a5 From 0f96d0625273f748793988f67756b4317c1e074e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 14:24:32 -0800 Subject: [PATCH 081/256] Making plugin names case-insensitive for some internal comparisions. Makes the plugin system a bit more tolerant against spelling inconsistencies that would be hard to catch otherwise. --- src/plugin/Manager.cc | 22 ++++++++++++---------- src/util.cc | 7 +++++++ src/util.h | 3 +++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index ab0b85676b..b891a0faab 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -79,18 +79,19 @@ void Manager::SearchDynamicPlugins(const std::string& dir) std::string name; std::getline(in, name); strstrip(name); + string lower_name = strtolower(name); if ( name.empty() ) reporter->FatalError("empty plugin magic file %s", magic.c_str()); - if ( dynamic_plugins.find(name) != dynamic_plugins.end() ) + if ( dynamic_plugins.find(lower_name) != dynamic_plugins.end() ) { DBG_LOG(DBG_PLUGINS, "Found already known plugin %s in %s, ignoring", name.c_str(), dir.c_str()); return; } // Record it, so that we can later activate it. - dynamic_plugins.insert(std::make_pair(name, dir)); + dynamic_plugins.insert(std::make_pair(lower_name, dir)); DBG_LOG(DBG_PLUGINS, "Found plugin %s in %s", name.c_str(), dir.c_str()); return; @@ -135,7 +136,7 @@ void Manager::SearchDynamicPlugins(const std::string& dir) bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found) { - dynamic_plugin_map::iterator m = dynamic_plugins.find(name); + dynamic_plugin_map::iterator m = dynamic_plugins.find(strtolower(name)); if ( m == dynamic_plugins.end() ) { @@ -230,7 +231,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_ // Make sure the name the plugin reports is consistent with // what we expect from its magic file. - if ( string(current_plugin->Name()) != name ) + if ( strtolower(current_plugin->Name()) != strtolower(name) ) reporter->FatalError("inconsistent plugin name: %s vs %s", current_plugin->Name().c_str(), name.c_str()); @@ -297,7 +298,7 @@ void Manager::UpdateInputFiles() static bool plugin_cmp(const Plugin* a, const Plugin* b) { - return a->Name() < b->Name(); + return strtolower(a->Name()) < strtolower(b->Name()); } void Manager::RegisterPlugin(Plugin *plugin) @@ -318,10 +319,11 @@ void Manager::RegisterBifFile(const char* plugin, bif_init_func c) { bif_init_func_map* bifs = BifFilesInternal(); - bif_init_func_map::iterator i = bifs->find(plugin); + std::string lower_plugin = strtolower(plugin); + bif_init_func_map::iterator i = bifs->find(lower_plugin); if ( i == bifs->end() ) - i = bifs->insert(std::make_pair(std::string(plugin), new bif_init_func_list())).first; + i = bifs->insert(std::make_pair(lower_plugin, new bif_init_func_list())).first; i->second->push_back(c); } @@ -348,7 +350,7 @@ void Manager::InitBifs() for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); i != Manager::ActivePluginsInternal()->end(); i++ ) { - bif_init_func_map::const_iterator b = bifs->find((*i)->Name()); + bif_init_func_map::const_iterator b = bifs->find(strtolower((*i)->Name())); if ( b != bifs->end() ) { @@ -397,7 +399,7 @@ Manager::inactive_plugin_list Manager::InactivePlugins() const for ( plugin_list::const_iterator j = all->begin(); j != all->end(); j++ ) { - if ( (*i).first == (*j)->Name() ) + if ( (*i).first == strtolower((*j)->Name()) ) { found = true; break; @@ -434,7 +436,7 @@ Manager::bif_init_func_map* Manager::BifFilesInternal() static bool hook_cmp(std::pair a, std::pair b) { if ( a.first == b.first ) - return a.second->Name() < a.second->Name(); + return strtolower(a.second->Name()) < strtolower(a.second->Name()); // Reverse sort. return a.first > b.first; diff --git a/src/util.cc b/src/util.cc index 60a92af45f..ac2a942ed3 100644 --- a/src/util.cc +++ b/src/util.cc @@ -541,6 +541,13 @@ bool is_printable(const char* s, int len) return true; } +std::string strtolower(const std::string& s) + { + std::string t = s; + std::transform(t.begin(), t.end(), t.begin(), ::tolower); + return t; + } + const char* fmt_bytes(const char* data, int len) { static char buf[1024]; diff --git a/src/util.h b/src/util.h index 50c33d5608..f65e0fb7d0 100644 --- a/src/util.h +++ b/src/util.h @@ -159,6 +159,9 @@ int strstr_n(const int big_len, const unsigned char* big, extern int fputs(int len, const char* s, FILE* fp); extern bool is_printable(const char* s, int len); +// Return a lower-cased version of the string. +extern std::string strtolower(const std::string& s); + extern const char* fmt_bytes(const char* data, int len); // Note: returns a pointer into a shared buffer. From b6bbf90643e272814174b6eb065fdbab60e1d938 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 14:32:08 -0800 Subject: [PATCH 082/256] Updating plugin tests. The init-plugin scripts now expects a destination directory. Normally that would be a new subdirectory, but for the tests to keep working we can also put it right into the current directory. --- testing/btest/Baseline/plugins.api-version-mismatch/output | 2 +- testing/btest/plugins/api-version-mismatch.sh | 2 +- testing/btest/plugins/bifs-and-scripts-install.sh | 4 ++-- testing/btest/plugins/bifs-and-scripts.sh | 2 +- testing/btest/plugins/file.bro | 2 +- testing/btest/plugins/hooks.bro | 2 +- testing/btest/plugins/init-plugin.bro | 2 +- testing/btest/plugins/pktdumper.bro | 2 +- testing/btest/plugins/pktsrc.bro | 2 +- testing/btest/plugins/protocol.bro | 2 +- testing/btest/plugins/reader.bro | 2 +- testing/btest/plugins/writer.bro | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/testing/btest/Baseline/plugins.api-version-mismatch/output b/testing/btest/Baseline/plugins.api-version-mismatch/output index 1e4dae5e65..04f3cdd3a2 100644 --- a/testing/btest/Baseline/plugins.api-version-mismatch/output +++ b/testing/btest/Baseline/plugins.api-version-mismatch/output @@ -1 +1 @@ -fatal error in /home/robin/bro/master/scripts/base/init-bare.bro, line 1: plugin's API version does not match Bro (expected 2, got 42 in /home/robin/bro/master/testing/btest/.tmp/plugins.api-version-mismatch//lib/XXX) +fatal error in /home/robin/bro/plugins/scripts/base/init-bare.bro, line 1: plugin's API version does not match Bro (expected 2, got 42 in /home/robin/bro/plugins/testing/btest/.tmp/plugins.api-version-mismatch/build//lib/XXX) diff --git a/testing/btest/plugins/api-version-mismatch.sh b/testing/btest/plugins/api-version-mismatch.sh index cfb4269946..2483582359 100644 --- a/testing/btest/plugins/api-version-mismatch.sh +++ b/testing/btest/plugins/api-version-mismatch.sh @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: bash %INPUT # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC-FAIL: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >tmp 2>&1 diff --git a/testing/btest/plugins/bifs-and-scripts-install.sh b/testing/btest/plugins/bifs-and-scripts-install.sh index 627eb0f2c5..60c754f8ff 100644 --- a/testing/btest/plugins/bifs-and-scripts-install.sh +++ b/testing/btest/plugins/bifs-and-scripts-install.sh @@ -1,10 +1,10 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: bash %INPUT # @TEST-EXEC: ./configure --bro-dist=${DIST} --install-root=`pwd`/test-install # @TEST-EXEC: make # @TEST-EXEC: make install # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd`/test-install bro -NN Demo::Foo >>output -# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro demo/foo -r $TRACES/empty.trace >>output +# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd`/test-install bro demo/foo -r $TRACES/empty.trace >>output # @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff output mkdir -p scripts/demo/foo/base/ diff --git a/testing/btest/plugins/bifs-and-scripts.sh b/testing/btest/plugins/bifs-and-scripts.sh index cf49642766..25f2dbeb5e 100644 --- a/testing/btest/plugins/bifs-and-scripts.sh +++ b/testing/btest/plugins/bifs-and-scripts.sh @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: bash %INPUT # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/file.bro b/testing/btest/plugins/file.bro index 7d25cab538..29724aa8a4 100644 --- a/testing/btest/plugins/file.bro +++ b/testing/btest/plugins/file.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/file-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/hooks.bro b/testing/btest/plugins/hooks.bro index 786e6ccc88..c1dec2f4c3 100644 --- a/testing/btest/plugins/hooks.bro +++ b/testing/btest/plugins/hooks.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Hooks +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Hooks # @TEST-EXEC: cp -r %DIR/hooks-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -r $TRACES/http/get.trace %INPUT 2>&1 | $SCRIPTS/diff-remove-abspath | sort | uniq >output diff --git a/testing/btest/plugins/init-plugin.bro b/testing/btest/plugins/init-plugin.bro index 2fffa88f2c..a4ebf7b00c 100644 --- a/testing/btest/plugins/init-plugin.bro +++ b/testing/btest/plugins/init-plugin.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output # @TEST-EXEC: echo === >>output diff --git a/testing/btest/plugins/pktdumper.bro b/testing/btest/plugins/pktdumper.bro index 29b69acadd..d9bd91a5a6 100644 --- a/testing/btest/plugins/pktdumper.bro +++ b/testing/btest/plugins/pktdumper.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/pktdumper-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/pktsrc.bro b/testing/btest/plugins/pktsrc.bro index 349e361664..a13596e245 100644 --- a/testing/btest/plugins/pktsrc.bro +++ b/testing/btest/plugins/pktsrc.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/pktsrc-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/protocol.bro b/testing/btest/plugins/protocol.bro index 671edb6cf1..8a6c2a6399 100644 --- a/testing/btest/plugins/protocol.bro +++ b/testing/btest/plugins/protocol.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/protocol-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/reader.bro b/testing/btest/plugins/reader.bro index 5065678c2e..ec9b6cf046 100644 --- a/testing/btest/plugins/reader.bro +++ b/testing/btest/plugins/reader.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/reader-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output diff --git a/testing/btest/plugins/writer.bro b/testing/btest/plugins/writer.bro index f2e74ad667..8cecff6843 100644 --- a/testing/btest/plugins/writer.bro +++ b/testing/btest/plugins/writer.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin -u . Demo Foo # @TEST-EXEC: cp -r %DIR/writer-plugin/* . # @TEST-EXEC: ./configure --bro-dist=${DIST} && make # @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output From bdb2707a08a5772d9de7371dc1050f0d5db4bb56 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 16 Feb 2015 20:05:30 -0800 Subject: [PATCH 083/256] Updating submodules. --- aux/bro-aux | 2 +- aux/plugins | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aux/bro-aux b/aux/bro-aux index 63675de3cc..8c37b26823 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 63675de3cc7bc3eb2a3645860224c372d3f7f36a +Subproject commit 8c37b26823ada9c77614b2f8f781c11c8fe3d078 diff --git a/aux/plugins b/aux/plugins index ad600b5bdc..9072e28935 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit ad600b5bdcd56a2723e323c0f2c8e1708956ca4f +Subproject commit 9072e28935ba85b6938fe946d7aa23cb58ee1566 From b06d82ccedeb7e079a76c2b6f207df681f05a96a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 17 Feb 2015 10:50:57 -0600 Subject: [PATCH 084/256] broker integration: add API documentation (broxygen/doxygen) Also changed asynchronous data store query code a bit; trying to make memory management and handling of corner cases a bit clearer (former maybe could still be better, but I need to lookup queries by memory address to associate response cookies to them, and so wrapping pointers kind of just gets in the way). --- scripts/base/frameworks/comm/main.bro | 39 ++- src/Trigger.h | 2 + src/comm/Data.h | 67 ++++++ src/comm/Manager.cc | 28 ++- src/comm/Manager.h | 212 ++++++++++++++++- src/comm/Store.cc | 5 - src/comm/Store.h | 27 +++ src/comm/comm.bif | 106 +++++++++ src/comm/data.bif | 331 +++++++++++++++++++++++++- src/comm/messaging.bif | 102 +++++++- src/comm/store.bif | 222 +++++++++++++++-- src/logging/Manager.h | 18 ++ 12 files changed, 1114 insertions(+), 45 deletions(-) diff --git a/scripts/base/frameworks/comm/main.bro b/scripts/base/frameworks/comm/main.bro index 66dc1715f4..da910f20bf 100644 --- a/scripts/base/frameworks/comm/main.bro +++ b/scripts/base/frameworks/comm/main.bro @@ -1,32 +1,53 @@ +##! Various data structure definitions for use with Bro's communication system. module Comm; export { + ## A name used to identify this endpoint to peers. + ## .. bro:see:: Comm::connect Comm::listen const endpoint_name = "" &redef; + ## Change communication behavior. type EndpointFlags: record { + ## Whether to restrict message topics that can be published to peers. auto_publish: bool &default = T; + ## Whether to restrict what message topics or data store identifiers + ## the local endpoint advertises to peers (e.g. subscribing to + ## events or making a master data store available). auto_advertise: bool &default = T; }; + ## Fine-grained tuning of communication behavior for a particular message. type SendFlags: record { + ## Send the message to the local endpoint. self: bool &default = F; + ## Send the message to peer endpoints that advertise interest in + ## the topic associated with the message. peers: bool &default = T; + ## Send the message to peer endpoints even if they don't advertise + ## interest in the topic associated with the message. unsolicited: bool &default = F; }; + ## Opaque communication data. type Data: record { d: opaque of Comm::Data &optional; }; + ## Opaque communication data. type DataVector: vector of Comm::Data; + ## Opaque event communication data. type EventArgs: record { - name: string &optional; # nil for invalid event/args. + ## The name of the event. Not set if invalid event or arguments. + name: string &optional; + ## The arguments to the event. args: DataVector; }; + ## Opaque communication data used as a convenient way to wrap key-value + ## pairs that comprise table entries. type Comm::TableItem : record { key: Comm::Data; val: Comm::Data; @@ -37,30 +58,44 @@ module Store; export { + ## Whether a data store query could be completed or not. type QueryStatus: enum { SUCCESS, FAILURE, }; + ## A expiry time for a key-value pair inserted in to a data store. type ExpiryTime: record { + ## Absolute point in time at which to expire the entry. absolute: time &optional; + ## A point in time relative to the last modification time at which + ## to expire the entry. New modifications will delay the expiration. since_last_modification: interval &optional; }; + ## The result of a data store query. type QueryResult: record { + ## Whether the query completed or not. status: Store::QueryStatus; + ## The result of the query. Certain queries may use a particular + ## data type (e.g. querying store size always returns a count, but + ## a lookup may return various data types). result: Comm::Data; }; + ## Options to tune the SQLite storage backend. type SQLiteOptions: record { + ## File system path of the database. path: string &default = "store.sqlite"; }; + ## Options to tune the RocksDB storage backend. type RocksDBOptions: record { + ## File system path of the database. path: string &default = "store.rocksdb"; - use_merge_operator: bool &default = F; }; + ## Options to tune the particular storage backends. type BackendOptions: record { sqlite: SQLiteOptions &default = SQLiteOptions(); rocksdb: RocksDBOptions &default = RocksDBOptions(); diff --git a/src/Trigger.h b/src/Trigger.h index 7662901dc5..3af9ddf1b0 100644 --- a/src/Trigger.h +++ b/src/Trigger.h @@ -55,6 +55,8 @@ public: // may not immediately delete it as other references may still exist. void Disable(); + bool Disabled() const { return disabled; } + virtual void Describe(ODesc* d) const { d->Add(""); } // Overidden from Notifier. We queue the trigger and evaluate it diff --git a/src/comm/Data.h b/src/comm/Data.h index ed3c16f677..ef7b15110d 100644 --- a/src/comm/Data.h +++ b/src/comm/Data.h @@ -15,18 +15,53 @@ extern OpaqueType* opaque_of_table_iterator; extern OpaqueType* opaque_of_vector_iterator; extern OpaqueType* opaque_of_record_iterator; +/** + * Convert a broker port protocol to a bro port protocol. + */ TransportProto to_bro_port_proto(broker::port::protocol tp); +/** + * Create a Comm::Data value from a Bro value. + * @param v the Bro value to convert to a Broker data value. + * @return a Comm::Data value, where the optional field is set if the conversion + * was possible, else it is unset. + */ RecordVal* make_data_val(Val* v); +/** + * Create a Comm::Data value from a Broker data value. + * @param d the Broker value to wrap in an opaque type. + * @return a Comm::Data value that wraps the Broker value. + */ RecordVal* make_data_val(broker::data d); +/** + * Get the type of Broker data that Comm::Data wraps. + * @param v a Comm::Data value. + * @param frame used to get location info upon error. + * @return a Comm::DataType value. + */ EnumVal* get_data_type(RecordVal* v, Frame* frame); +/** + * Convert a Bro value to a Broker data value. + * @param v a Bro value. + * @return a Broker data value if the Bro value could be converted to one. + */ broker::util::optional val_to_data(Val* v); +/** + * Convert a Broker data value to a Bro value. + * @param d a Broker data value. + * @param type the expected type of the value to return. + * @return a pointer to a new Bro value or a nullptr if the conversion was not + * possible. + */ Val* data_to_val(broker::data d, BroType* type); +/** + * A Bro value which wraps a Broker data value. + */ class DataVal : public OpaqueVal { public: @@ -51,6 +86,9 @@ protected: {} }; +/** + * Visitor for retrieving type names a Broker data value. + */ struct type_name_getter { using result_type = const char*; @@ -100,8 +138,25 @@ struct type_name_getter { { return "record"; } }; +/** + * Retrieve Broker data value associated with a Comm::Data Bro value. + * @param v a Comm::Data value. + * @param f used to get location information on error. + * @return a reference to the wrapped Broker data value. A runtime interpreter + * exception is thrown if the the optional opaque value of \a v is not set. + */ broker::data& opaque_field_to_data(RecordVal* v, Frame* f); +/** + * Retrieve variant data from a Broker data value. + * @tparam T a type that the variant may contain. + * @param d a Broker data value to get variant data out of. + * @param tag a Bro tag which corresponds to T (just used for error reporting). + * @param f used to get location information on error. + * @return a refrence to the requested type in the variant Broker data. + * A runtime interpret exception is thrown if trying to access a type which + * is not currently stored in the Broker data. + */ template T& require_data_type(broker::data& d, TypeTag tag, Frame* f) { @@ -116,12 +171,24 @@ T& require_data_type(broker::data& d, TypeTag tag, Frame* f) return *ptr; } +/** + * @see require_data_type() and opaque_field_to_data(). + */ template inline T& require_data_type(RecordVal* v, TypeTag tag, Frame* f) { return require_data_type(opaque_field_to_data(v, f), tag, f); } +/** + * Convert a Comm::Data Bro value to a Bro value of a given type. + * @tparam a type that a Broker data variant may contain. + * @param v a Comm::Data value. + * @param tag a Bro type to convert to. + * @param f used to get location information on error. + * A runtime interpret exception is thrown if trying to access a type which + * is not currently stored in the Broker data. + */ template inline Val* refine(RecordVal* v, TypeTag tag, Frame* f) { diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 92b2c167dd..65a7bddbf6 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -41,7 +41,7 @@ static int require_field(RecordType* rt, const char* name) return rval; } -static int GetEndpointFlags(Val* broker_endpoint_flags) +static int endpoint_flags_to_int(Val* broker_endpoint_flags) { int rval = 0; auto r = broker_endpoint_flags->AsRecordVal(); @@ -111,7 +111,7 @@ bool comm::Manager::Enable(Val* broker_endpoint_flags) name = fmt("bro@.%ld", static_cast(getpid())); } - int flags = GetEndpointFlags(broker_endpoint_flags); + int flags = endpoint_flags_to_int(broker_endpoint_flags); endpoint = unique_ptr(new broker::endpoint(name, flags)); iosource_mgr->Register(this, true); return true; @@ -122,7 +122,7 @@ bool comm::Manager::SetEndpointFlags(Val* broker_endpoint_flags) if ( ! Enabled() ) return false; - int flags = GetEndpointFlags(broker_endpoint_flags); + int flags = endpoint_flags_to_int(broker_endpoint_flags); endpoint->set_flags(flags); return true; } @@ -179,7 +179,8 @@ bool comm::Manager::Print(string topic, string msg, Val* flags) if ( ! Enabled() ) return false; - endpoint->send(move(topic), broker::message{move(msg)}, GetFlags(flags)); + endpoint->send(move(topic), broker::message{move(msg)}, + send_flags_to_int(flags)); return true; } @@ -243,7 +244,7 @@ bool comm::Manager::Event(std::string topic, RecordVal* args, Val* flags) msg.emplace_back(data_val->data); } - endpoint->send(move(topic), move(msg), GetFlags(flags)); + endpoint->send(move(topic), move(msg), send_flags_to_int(flags)); return true; } @@ -275,7 +276,7 @@ bool comm::Manager::AutoEvent(string topic, Val* event, Val* flags) return false; } - handler->AutoRemote(move(topic), GetFlags(flags)); + handler->AutoRemote(move(topic), send_flags_to_int(flags)); return true; } @@ -484,7 +485,7 @@ bool comm::Manager::UnadvertiseTopic(broker::topic t) return true; } -int comm::Manager::GetFlags(Val* flags) +int comm::Manager::send_flags_to_int(Val* flags) { auto r = flags->AsRecordVal(); int rval = 0; @@ -869,6 +870,14 @@ void comm::Manager::Process() auto query = *it; + if ( query->Disabled() ) + { + // Trigger timer must have timed the query out already. + delete query; + pending_queries.erase(it); + continue; + } + switch ( response.reply.stat ) { case broker::store::result::status::timeout: // Fine, trigger's timeout takes care of things. @@ -885,6 +894,7 @@ void comm::Manager::Process() break; } + delete query; pending_queries.erase(it); } } @@ -1006,8 +1016,6 @@ bool comm::Manager::CloseStore(const broker::store::identifier& id, bool comm::Manager::TrackStoreQuery(StoreQueryCallback* cb) { - if ( ! Enabled() ) - return false; - + assert(Enabled()); return pending_queries.insert(cb).second; } diff --git a/src/comm/Manager.h b/src/comm/Manager.h index e8a8d5e5b1..bd1236bf34 100644 --- a/src/comm/Manager.h +++ b/src/comm/Manager.h @@ -14,73 +14,275 @@ namespace comm { -// TODO: documentation - -// Manages various forms of communication between peer Bro processes -// or possibly between different parts of a single Bro process. +/** + * Manages various forms of communication between peer Bro processes + * or other external applications via use of the Broker messaging library. + */ class Manager : public iosource::IOSource { friend class StoreHandleVal; public: + /** + * Destructor. Any still-pending data store queries are aborted. + */ ~Manager(); + /** + * Enable use of communication. + * @param flags used to tune the local Broker endpoint's behavior. + * See the Comm::EndpointFlags record type. + * @return true if communication is successfully initialized. + */ bool Enable(Val* flags); + /** + * Changes endpoint flags originally supplied to comm::Manager::Enable(). + * @param flags the new behavior flags to use. + * @return true if flags were changed. + */ bool SetEndpointFlags(Val* flags); + /** + * @return true if comm::Manager::Enable() has previously been called and + * it succeeded. + */ bool Enabled() { return endpoint != nullptr; } + /** + * Listen for remote connections. + * @param port the TCP port to listen on. + * @param addr an address string on which to accept connections, e.g. + * "127.0.0.1". A nullptr refers to @p INADDR_ANY. + * @param reuse_addr equivalent to behavior of SO_REUSEADDR. + * @return true if the local endpoint is now listening for connections. + */ bool Listen(uint16_t port, const char* addr = nullptr, bool reuse_addr = true); + /** + * Initiate a remote connection. + * @param addr an address to connect to, e.g. "localhost" or "127.0.0.1". + * @param port the TCP port on which the remote side is listening. + * @param retry_interval an interval at which to retry establishing the + * connection with the remote peer. + * @return true if it's possible to try connecting with the peer and + * it's a new peer. The actual connection may not be established until a + * later point in time. + */ bool Connect(std::string addr, uint16_t port, std::chrono::duration retry_interval); + /** + * Remove a remote connection. + * @param addr the address used in comm::Manager::Connect(). + * @param port the port used in comm::Manager::Connect(). + * @return true if the arguments match a previously successful call to + * comm::Manager::Connect(). + */ bool Disconnect(const std::string& addr, uint16_t port); + /** + * Print a simple message to any interested peers. + * @param topic a topic string associated with the print message. + * Peers advertise interest by registering a subscription to some prefix + * of this topic name. + * @param msg the string to send to peers. + * @param flags tune the behavior of how the message is send. + * See the Comm::SendFlags record type. + * @return true if the message is sent successfully. + */ bool Print(std::string topic, std::string msg, Val* flags); + /** + * Send an event to any interested peers. + * @param topic a topic string associated with the print message. + * Peers advertise interest by registering a subscription to some prefix + * of this topic name. + * @param msg the event to send to peers, which is the name of the event + * as a string followed by all of its arguments. + * @param flags tune the behavior of how the message is send. + * See the Comm::SendFlags record type. + * @return true if the message is sent successfully. + */ bool Event(std::string topic, broker::message msg, int flags); + + /** + * Send an event to any interested peers. + * @param topic a topic string associated with the print message. + * Peers advertise interest by registering a subscription to some prefix + * of this topic name. + * @param args the event and its arguments to send to peers. See the + * Comm::EventArgs record type. + * @param flags tune the behavior of how the message is send. + * See the Comm::SendFlags record type. + * @return true if the message is sent successfully. + */ bool Event(std::string topic, RecordVal* args, Val* flags); + /** + * Send a log entry to any interested peers. The topic name used is + * implicitly "bro/log/". + * @param stream_id the stream to which the log entry belongs. + * @param columns the data which comprises the log entry. + * @param flags tune the behavior of how the message is send. + * See the Comm::SendFlags record type. + * @return true if the message is sent successfully. + */ bool Log(EnumVal* stream_id, RecordVal* columns, int flags); + /** + * Automatically send an event to any interested peers whenever it is + * locally dispatched (e.g. using "event my_event(...);" in a script). + * @param topic a topic string associated with the event message. + * Peers advertise interest by registering a subscription to some prefix + * of this topic name. + * @param event a Bro event value. + * @param flags tune the behavior of how the message is send. + * See the Comm::SendFlags record type. + * @return true if automatic event sending is now enabled. + */ bool AutoEvent(std::string topic, Val* event, Val* flags); + /** + * Stop automatically sending an event to peers upon local dispatch. + * @param topic a topic originally given to comm::Manager::AutoEvent(). + * @param event an event originally given to comm::Manager::AutoEvent(). + * @return true if automatic events will no occur for the topic/event pair. + */ bool AutoEventStop(const std::string& topic, Val* event); + /** + * Create an EventArgs record value from an event and its arguments. + * @param args the event and its arguments. The event is always the first + * elements in the list. + * @return an EventArgs record value. If an invalid event or arguments + * were supplied the optional "name" field will not be set. + */ RecordVal* MakeEventArgs(val_list* args); + /** + * Register interest in peer print messages that use a certain topic prefix. + * @param topic_prefix a prefix to match against remote message topics. + * e.g. an empty prefix will match everything and "a" will match "alice" + * and "amy" but not "bob". + * @return true if it's a new print subscriptions and it is now registered. + */ bool SubscribeToPrints(std::string topic_prefix); + /** + * Unregister interest in peer print messages. + * @param topic_prefix a prefix previously supplied to a successful call + * to comm::Manager::SubscribeToPrints(). + * @return true if interest in topic prefix is no longer advertised. + */ bool UnsubscribeToPrints(const std::string& topic_prefix); + /** + * Register interest in peer event messages that use a certain topic prefix. + * @param topic_prefix a prefix to match against remote message topics. + * e.g. an empty prefix will match everything and "a" will match "alice" + * and "amy" but not "bob". + * @return true if it's a new event subscription and it is now registered. + */ bool SubscribeToEvents(std::string topic_prefix); + /** + * Unregister interest in peer event messages. + * @param topic_prefix a prefix previously supplied to a successful call + * to comm::Manager::SubscribeToEvents(). + * @return true if interest in topic prefix is no longer advertised. + */ bool UnsubscribeToEvents(const std::string& topic_prefix); + /** + * Register interest in peer log messages that use a certain topic prefix. + * @param topic_prefix a prefix to match against remote message topics. + * e.g. an empty prefix will match everything and "a" will match "alice" + * and "amy" but not "bob". + * @return true if it's a new log subscription and it is now registered. + */ bool SubscribeToLogs(std::string topic_prefix); + /** + * Unregister interest in peer log messages. + * @param topic_prefix a prefix previously supplied to a successful call + * to comm::Manager::SubscribeToLogs(). + * @return true if interest in topic prefix is no longer advertised. + */ bool UnsubscribeToLogs(const std::string& topic_prefix); + /** + * Allow sending messages to peers if associated with the given topic. + * This has no effect if auto publication behavior is enabled via the flags + * supplied to comm::Manager::Enable() or comm::Manager::SetEndpointFlags(). + * @param t a topic to allow messages to be published under. + * @return true if successful. + */ bool PublishTopic(broker::topic t); + /** + * Disallow sending messages to peers if associated with the given topic. + * This has no effect if auto publication behavior is enabled via the flags + * supplied to comm::Manager::Enable() or comm::Manager::SetEndpointFlags(). + * @param t a topic to disallow messages to be published under. + * @return true if successful. + */ bool UnpublishTopic(broker::topic t); + /** + * Allow advertising interest in the given topic to peers. + * This has no effect if auto advertise behavior is enabled via the flags + * supplied to comm::Manager::Enable() or comm::Manager::SetEndpointFlags(). + * @param t a topic to allow advertising interest/subscription to peers. + * @return true if successful. + */ bool AdvertiseTopic(broker::topic t); + /** + * Disallow advertising interest in the given topic to peers. + * This has no effect if auto advertise behavior is enabled via the flags + * supplied to comm::Manager::Enable() or comm::Manager::SetEndpointFlags(). + * @param t a topic to disallow advertising interest/subscription to peers. + * @return true if successful. + */ bool UnadvertiseTopic(broker::topic t); + /** + * Register the availability of a data store. + * @param handle the data store. + * @return true if the store was valid and not already away of it. + */ bool AddStore(StoreHandleVal* handle); + /** + * Lookup a data store by it's identifier name and type. + * @param id the store's name. + * @param type the type of data store. + * @return a pointer to the store handle if it exists else nullptr. + */ StoreHandleVal* LookupStore(const broker::store::identifier& id, StoreType type); + /** + * Close and unregister a data store. Any existing references to the + * store handle will not be able to be used for any data store operations. + * @param id the stores' name. + * @param type the type of the data store. + * @return true if such a store existed and is now closed. + */ bool CloseStore(const broker::store::identifier& id, StoreType type); + /** + * Register a data store query callback. + * @param cb the callback info to use when the query completes or times out. + * @return true if now tracking a data store query. + */ bool TrackStoreQuery(StoreQueryCallback* cb); - static int GetFlags(Val* flags); + /** + * Convert Comm::SendFlags to int flags for use with broker::send(). + */ + static int send_flags_to_int(Val* flags); private: diff --git a/src/comm/Store.cc b/src/comm/Store.cc index 8c55c31785..5fcc7daa85 100644 --- a/src/comm/Store.cc +++ b/src/comm/Store.cc @@ -48,14 +48,9 @@ comm::StoreHandleVal::StoreHandleVal(broker::store::identifier id, #ifdef HAVE_ROCKSDB std::string path = backend_options->Lookup(1)->AsRecordVal() ->Lookup(0)->AsStringVal()->CheckString(); - bool use_merge_op = backend_options->Lookup(1)->AsRecordVal() - ->Lookup(1)->AsBool(); rocksdb::Options rock_op; rock_op.create_if_missing = true; - if ( use_merge_op ) - options.merge_operator.reset(new rocksdb_merge_operator); - auto rocksdb = new broker::store::rocksdb_backend; if ( rocksdb->open(path, options).ok() ) diff --git a/src/comm/Store.h b/src/comm/Store.h index b02c5b4f5b..289290eab4 100644 --- a/src/comm/Store.h +++ b/src/comm/Store.h @@ -14,12 +14,21 @@ namespace comm { extern OpaqueType* opaque_of_store_handle; +/** + * Enumerates the possible types of data stores. + */ enum StoreType { + // Just a view in to a remote store, contains no data itself. FRONTEND, MASTER, CLONE, }; +/** + * Create a Store::QueryStatus value. + * @param success whether the query status should be set to success or failure. + * @return a Store::QueryStatus value. + */ inline EnumVal* query_status(bool success) { static EnumType* store_query_status = nullptr; @@ -36,6 +45,10 @@ inline EnumVal* query_status(bool success) return new EnumVal(success ? success_val : failure_val, store_query_status); } +/** + * @return a Store::QueryResult value that has a Store::QueryStatus indicating + * a failure. + */ inline RecordVal* query_result() { auto rval = new RecordVal(BifType::Record::Store::QueryResult); @@ -44,6 +57,11 @@ inline RecordVal* query_result() return rval; } +/** + * @param data the result of the query. + * @return a Store::QueryResult value that has a Store::QueryStatus indicating + * a success. + */ inline RecordVal* query_result(RecordVal* data) { auto rval = new RecordVal(BifType::Record::Store::QueryResult); @@ -52,6 +70,9 @@ inline RecordVal* query_result(RecordVal* data) return rval; } +/** + * Used for asynchronous data store queries which use "when" statements. + */ class StoreQueryCallback { public: @@ -84,6 +105,9 @@ public: Unref(result); } + bool Disabled() const + { return trigger->Disabled(); } + const broker::store::identifier& StoreID() const { return store_id; } @@ -98,6 +122,9 @@ private: StoreType store_type; }; +/** + * An opaque handle which wraps a Broker data store. + */ class StoreHandleVal : public OpaqueVal { public: diff --git a/src/comm/comm.bif b/src/comm/comm.bif index 1d41b572f6..23e163c748 100644 --- a/src/comm/comm.bif +++ b/src/comm/comm.bif @@ -9,50 +9,133 @@ module Comm; type Comm::EndpointFlags: record; +## Enable use of communication. +## +## flags: used to tune the local Broker endpoint behavior. +## +## Returns: true if communication is successfully initialized. function Comm::enable%(flags: EndpointFlags &default = EndpointFlags()%): bool %{ return new Val(comm_mgr->Enable(flags), TYPE_BOOL); %} +## Changes endpoint flags originally supplied to :bro:see:`Comm::enable`. +## +## flags: the new endpoint behavior flags to use. +## +## Returns: true of flags were changed. function Comm::set_endpoint_flags%(flags: EndpointFlags &default = EndpointFlags()%): bool %{ return new Val(comm_mgr->SetEndpointFlags(flags), TYPE_BOOL); %} +## Allow sending messages to peers if associated with the given topic. +## This has no effect if auto publication behavior is enabled via the flags +## supplied to :bro:see:`Comm::enable` or :bro:see:`Comm::set_endpoint_flags`. +## +## topic: a topic to allow messages to be published under. +## +## Returns: true if successful. function Comm::publish_topic%(topic: string%): bool %{ return new Val(comm_mgr->PublishTopic(topic->CheckString()), TYPE_BOOL); %} +## Disallow sending messages to peers if associated with the given topic. +## This has no effect if auto publication behavior is enabled via the flags +## supplied to :bro:see:`Comm::enable` or :bro:see:`Comm::set_endpoint_flags`. +## +## topic: a topic to disallow messages to be published under. +## +## Returns: true if successful. function Comm::unpublish_topic%(topic: string%): bool %{ return new Val(comm_mgr->UnpublishTopic(topic->CheckString()), TYPE_BOOL); %} +## Allow advertising interest in the given topic to peers. +## This has no effect if auto advertise behavior is enabled via the flags +## supplied to :bro:see:`Comm::enable` or :bro:see:`Comm::set_endpoint_flags`. +## +## topic: a topic to allow advertising interest/subscription to peers. +## +## Returns: true if successful. function Comm::advertise_topic%(topic: string%): bool %{ return new Val(comm_mgr->AdvertiseTopic(topic->CheckString()), TYPE_BOOL); %} +## Disallow advertising interest in the given topic to peers. +## This has no effect if auto advertise behavior is enabled via the flags +## supplied to :bro:see:`Comm::enable` or :bro:see:`Comm::set_endpoint_flags`. +## +## topic: a topic to disallow advertising interest/subscription to peers. +## +## Returns: true if successful. function Comm::unadvertise_topic%(topic: string%): bool %{ return new Val(comm_mgr->UnadvertiseTopic(topic->CheckString()), TYPE_BOOL); %} +## Generated when a connection has been established due to a previous call +## to :bro:see:`Comm::connect`. +## +## peer_address: the address used to connect to the peer. +## +## peer_port: the port used to connect to the peer. +## +## peer_name: the name by which the peer identified itself. event Comm::outgoing_connection_established%(peer_address: string, peer_port: port, peer_name: string%); +## Generated when a previously established connection becomes broken. +## Reconnection will automatically be attempted at a frequency given +## by the original call to :bro:see:`Comm::connect`. +## +## peer_address: the address used to connect to the peer. +## +## peer_port: the port used to connect to the peer. +## +## .. bro:see:: Comm::outgoing_connection_established event Comm::outgoing_connection_broken%(peer_address: string, peer_port: port%); +## Generated when a connection via :bro:see:`Comm::connect` has failed +## because the remote side is incompatible. +## +## peer_address: the address used to connect to the peer. +## +## peer_port: the port used to connect to the peer. event Comm::outgoing_connection_incompatible%(peer_address: string, peer_port: port%); +## Generated when a peer has established a connection with this process +## as a result of previously performing a :bro:see:`Comm::listen`. +## +## peer_name: the name by which the peer identified itself. event Comm::incoming_connection_established%(peer_name: string%); +## Generated when a peer that previously established a connection with this +## process becomes disconnected. +## +## peer_name: the name by which the peer identified itself. +## +## .. bro:see:: Comm::incoming_connection_established event Comm::incoming_connection_broken%(peer_name: string%); +## Listen for remote connections. +## +## p: the TCP port to listen on. +## +## a: an address string on which to accept connections, e.g. +## "127.0.0.1". An empty string refers to @p INADDR_ANY. +## +## reuse: equivalent to behavior of SO_REUSEADDR. +## +## Returns: true if the local endpoint is now listening for connections. +## +## .. bro:see:: Comm::incoming_connection_established function Comm::listen%(p: port, a: string &default = "", reuse: bool &default = T%): bool %{ @@ -67,6 +150,21 @@ function Comm::listen%(p: port, a: string &default = "", return new Val(rval, TYPE_BOOL); %} +## Initiate a remote connection. +## +## a: an address to connect to, e.g. "localhost" or "127.0.0.1". +## +## p: the TCP port on which the remote side is listening. +## +## retry: an interval at which to retry establishing the +## connection with the remote peer if it cannot be made initially, or +## if it ever becomes disconnected. +## +## Returns: true if it's possible to try connecting with the peer and +## it's a new peer. The actual connection may not be established +## a later point in time. +## +## .. bro:see:: Comm::outgoing_connection_established function Comm::connect%(a: string, p: port, retry: interval%): bool %{ if ( ! p->IsTCP() ) @@ -80,6 +178,14 @@ function Comm::connect%(a: string, p: port, retry: interval%): bool return new Val(rval, TYPE_BOOL); %} +## Remove a remote connection. +## +## a: the address used in previous successful call to :bro:see:`Comm::connect`. +## +## p: the port used in previous successful call to :bro:see:`Comm::connect`. +## +## Returns: true if the arguments match a previously successful call to +## :bro:see:`Comm::connect`. function Comm::disconnect%(a: string, p: port%): bool %{ if ( ! p->IsTCP() ) diff --git a/src/comm/data.bif b/src/comm/data.bif index 2a78a9229a..7120046920 100644 --- a/src/comm/data.bif +++ b/src/comm/data.bif @@ -7,6 +7,8 @@ module Comm; +## Enumerates the possible types that :bro:see:`Comm::Data` may be in terms of +## Bro data types. enum DataType %{ BOOL, INT, @@ -29,36 +31,78 @@ type Comm::Data: record; type Comm::TableItem: record; +## Convert any Bro value in to communication data. +## +## d: any Bro value to attempt to convert (not all types are supported). +## +## Returns: the converted communication data which may not set its only +## opaque field of the the conversion was not possible (the Bro data +## type does not support being converted to communicaiton data). function Comm::data%(d: any%): Comm::Data %{ return comm::make_data_val(d); %} +## Retrieve the type of data associated with communication data. +## +## d: the communication data. +## +## Returns: the data type associated with the communication data. function Comm::data_type%(d: Comm::Data%): Comm::DataType %{ return comm::get_data_type(d->AsRecordVal(), frame); %} +## Convert communication data with a type of :bro:see:`Comm::BOOL` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_bool%(d: Comm::Data%): bool %{ return comm::refine(d->AsRecordVal(), TYPE_BOOL, frame); %} +## Convert communication data with a type of :bro:see:`Comm::INT` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_int%(d: Comm::Data%): int %{ return comm::refine(d->AsRecordVal(), TYPE_INT, frame); %} +## Convert communication data with a type of :bro:see:`Comm::COUNT` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_count%(d: Comm::Data%): count %{ return comm::refine(d->AsRecordVal(), TYPE_COUNT, frame); %} +## Convert communication data with a type of :bro:see:`Comm::DOUBLE` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_double%(d: Comm::Data%): double %{ return comm::refine(d->AsRecordVal(), TYPE_DOUBLE, frame); %} +## Convert communication data with a type of :bro:see:`Comm::STRING` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_string%(d: Comm::Data%): string %{ return new StringVal(comm::require_data_type(d->AsRecordVal(), @@ -66,6 +110,12 @@ function Comm::refine_to_string%(d: Comm::Data%): string frame)); %} +## Convert communication data with a type of :bro:see:`Comm::ADDR` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_addr%(d: Comm::Data%): addr %{ auto& a = comm::require_data_type(d->AsRecordVal(), @@ -74,6 +124,12 @@ function Comm::refine_to_addr%(d: Comm::Data%): addr return new AddrVal(IPAddr(*bits)); %} +## Convert communication data with a type of :bro:see:`Comm::SUBNET` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_subnet%(d: Comm::Data%): subnet %{ auto& a = comm::require_data_type(d->AsRecordVal(), @@ -82,6 +138,12 @@ function Comm::refine_to_subnet%(d: Comm::Data%): subnet return new SubNetVal(IPPrefix(IPAddr(*bits), a.length())); %} +## Convert communication data with a type of :bro:see:`Comm::PORT` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_port%(d: Comm::Data%): port %{ auto& a = comm::require_data_type(d->AsRecordVal(), @@ -89,6 +151,12 @@ function Comm::refine_to_port%(d: Comm::Data%): port return new PortVal(a.number(), comm::to_bro_port_proto(a.type())); %} +## Convert communication data with a type of :bro:see:`Comm::TIME` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_time%(d: Comm::Data%): time %{ auto v = comm::require_data_type(d->AsRecordVal(), @@ -96,6 +164,12 @@ function Comm::refine_to_time%(d: Comm::Data%): time return new Val(v, TYPE_TIME); %} +## Convert communication data with a type of :bro:see:`Comm::INTERVAL` to +## an actual Bro value. +## +## d: the communication data to convert. +## +## Returns: the value retrieved from the communication data. function Comm::refine_to_interval%(d: Comm::Data%): interval %{ auto v = comm::require_data_type(d->AsRecordVal(), @@ -103,6 +177,13 @@ function Comm::refine_to_interval%(d: Comm::Data%): interval return new Val(v, TYPE_INTERVAL); %} +## Convert communication data with a type of :bro:see:`Comm::ENUM` to +## the name of the enum value. :bro:see:`lookup_ID` may be used to convert +## the name to the actual enum value. +## +## d: the communication data to convert. +## +## Returns: the enum name retrieved from the communication data. function Comm::refine_to_enum_name%(d: Comm::Data%): string %{ auto& v = comm::require_data_type(d->AsRecordVal(), @@ -110,11 +191,17 @@ function Comm::refine_to_enum_name%(d: Comm::Data%): string return new StringVal(v); %} +## Create communication data of type "set". function Comm::set_create%(%): Comm::Data %{ return comm::make_data_val(broker::set()); %} +## Remove all elements within a set. +## +## s: the set to clear. +## +## Returns: always true. function Comm::set_clear%(s: Comm::Data%): bool %{ auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, @@ -123,6 +210,11 @@ function Comm::set_clear%(s: Comm::Data%): bool return new Val(true, TYPE_BOOL); %} +## Get the number of elements within a set. +## +## s: the set to query. +## +## Returns: the number of elements in the set. function Comm::set_size%(s: Comm::Data%): count %{ auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, @@ -130,6 +222,13 @@ function Comm::set_size%(s: Comm::Data%): count return new Val(static_cast(v.size()), TYPE_COUNT); %} +## Check if a set contains a particular element. +## +## s: the set to query. +## +## key: the element to check for existence. +## +## Returns: true if the key exists in the set. function Comm::set_contains%(s: Comm::Data, key: Comm::Data%): bool %{ auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, @@ -138,6 +237,13 @@ function Comm::set_contains%(s: Comm::Data, key: Comm::Data%): bool return new Val(v.find(k) != v.end(), TYPE_BOOL); %} +### Insert an element into a set. +## +## s: the set to modify. +## +## key: the element to insert. +## +## Returns: true if the key was inserted, or false if it already existed. function Comm::set_insert%(s: Comm::Data, key: Comm::Data%): bool %{ auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, @@ -146,6 +252,13 @@ function Comm::set_insert%(s: Comm::Data, key: Comm::Data%): bool return new Val(v.insert(k).second, TYPE_BOOL); %} +## Remove an element from a set. +## +## s: the set to modify. +## +## key: the element to remove. +## +## Returns: true if the element existed in the set and is now removed. function Comm::set_remove%(s: Comm::Data, key: Comm::Data%): bool %{ auto& v = comm::require_data_type(s->AsRecordVal(), TYPE_TABLE, @@ -154,17 +267,36 @@ function Comm::set_remove%(s: Comm::Data, key: Comm::Data%): bool return new Val(v.erase(k) > 0, TYPE_BOOL); %} +## Create an iterator for a set. Note that this makes a copy of the set +## internally to ensure the iterator is always valid. +## +## s: the set to iterate over. +## +## Returns: an iterator. function Comm::set_iterator%(s: Comm::Data%): opaque of Comm::SetIterator %{ return new comm::SetIterator(s->AsRecordVal(), TYPE_TABLE, frame); %} +## Check if there are no more elements to iterate over. +## +## it: an iterator. +## +## Returns: true if there are no more elements to iterator over, i.e. +## the iterator is one-past-the-final-element. function Comm::set_iterator_last%(it: opaque of Comm::SetIterator%): bool %{ auto set_it = static_cast(it); return new Val(set_it->it == set_it->dat.end(), TYPE_BOOL); %} +## Advance an iterator. +## +## it: an iterator. +## +## Returns: true if the iterator, after advancing, still references an element +## in the collection. False if the iterator, after advancing, is +## one-past-the-final-element. function Comm::set_iterator_next%(it: opaque of Comm::SetIterator%): bool %{ auto set_it = static_cast(it); @@ -176,6 +308,11 @@ function Comm::set_iterator_next%(it: opaque of Comm::SetIterator%): bool return new Val(set_it->it != set_it->dat.end(), TYPE_BOOL); %} +## Retrieve the data at an iterator's current position. +## +## it: an iterator. +## +## Returns: element in the collection that the iterator currently references. function Comm::set_iterator_value%(it: opaque of Comm::SetIterator%): Comm::Data %{ auto set_it = static_cast(it); @@ -193,11 +330,17 @@ function Comm::set_iterator_value%(it: opaque of Comm::SetIterator%): Comm::Data return rval; %} +## Create communication data of type "table". function Comm::table_create%(%): Comm::Data %{ return comm::make_data_val(broker::table()); %} +## Remove all elements within a table. +## +## t: the table to clear. +## +## Returns: always true. function Comm::table_clear%(t: Comm::Data%): bool %{ auto& v = comm::require_data_type(t->AsRecordVal(), @@ -206,6 +349,11 @@ function Comm::table_clear%(t: Comm::Data%): bool return new Val(true, TYPE_BOOL); %} +## Get the number of elements within a table. +## +## t: the table to query. +## +## Returns: the number of elements in the table. function Comm::table_size%(t: Comm::Data%): count %{ auto& v = comm::require_data_type(t->AsRecordVal(), @@ -213,6 +361,13 @@ function Comm::table_size%(t: Comm::Data%): count return new Val(static_cast(v.size()), TYPE_COUNT); %} +## Check if a table contains a particular key. +## +## t: the table to query. +## +## key: the key to check for existence. +## +## Returns: true if the key exists in the set. function Comm::table_contains%(t: Comm::Data, key: Comm::Data%): bool %{ auto& v = comm::require_data_type(t->AsRecordVal(), @@ -221,6 +376,16 @@ function Comm::table_contains%(t: Comm::Data, key: Comm::Data%): bool return new Val(v.find(k) != v.end(), TYPE_BOOL); %} +## Insert a key-value pair into a table. +## +## t: the table to modify. +## +## key: the key at which to insert the value. +## +## val: the value to insert. +## +## Returns: true if the key-value pair was inserted, or false if the key +## already existed in the table. function Comm::table_insert%(t: Comm::Data, key: Comm::Data, val: Comm::Data%): Comm::Data %{ auto& table = comm::require_data_type(t->AsRecordVal(), @@ -242,6 +407,14 @@ function Comm::table_insert%(t: Comm::Data, key: Comm::Data, val: Comm::Data%): } %} +## Remove a key-value pair from a table. +## +## t: the table to modify. +## +## key: the key to remove from the table. +## +## Returns: the value associated with the key. If the key did not exist, then +## the optional field of the returned record is not set. function Comm::table_remove%(t: Comm::Data, key: Comm::Data%): Comm::Data %{ auto& table = comm::require_data_type(t->AsRecordVal(), @@ -259,6 +432,14 @@ function Comm::table_remove%(t: Comm::Data, key: Comm::Data%): Comm::Data } %} +## Retrieve a value from a table. +## +## t: the table to query. +## +## key: the key to lookup. +## +## Returns: the value associated with the key. If the key did not exist, then +## the optional field of the returned record is not set. function Comm::table_lookup%(t: Comm::Data, key: Comm::Data%): Comm::Data %{ auto& table = comm::require_data_type(t->AsRecordVal(), @@ -272,17 +453,36 @@ function Comm::table_lookup%(t: Comm::Data, key: Comm::Data%): Comm::Data return comm::make_data_val(it->second); %} +## Create an iterator for a table. Note that this makes a copy of the table +## internally to ensure the iterator is always valid. +## +## t: the table to iterate over. +## +## Returns: an iterator. function Comm::table_iterator%(t: Comm::Data%): opaque of Comm::TableIterator %{ return new comm::TableIterator(t->AsRecordVal(), TYPE_TABLE, frame); %} +## Check if there are no more elements to iterate over. +## +## it: an iterator. +## +## Returns: true if there are no more elements to iterator over, i.e. +## the iterator is one-past-the-final-element. function Comm::table_iterator_last%(it: opaque of Comm::TableIterator%): bool %{ auto ti = static_cast(it); return new Val(ti->it == ti->dat.end(), TYPE_BOOL); %} +## Advance an iterator. +## +## it: an iterator. +## +## Returns: true if the iterator, after advancing, still references an element +## in the collection. False if the iterator, after advancing, is +## one-past-the-final-element. function Comm::table_iterator_next%(it: opaque of Comm::TableIterator%): bool %{ auto ti = static_cast(it); @@ -294,6 +494,11 @@ function Comm::table_iterator_next%(it: opaque of Comm::TableIterator%): bool return new Val(ti->it != ti->dat.end(), TYPE_BOOL); %} +## Retrieve the data at an iterator's current position. +## +## it: an iterator. +## +## Returns: element in the collection that the iterator currently references. function Comm::table_iterator_value%(it: opaque of Comm::TableIterator%): Comm::TableItem %{ auto ti = static_cast(it); @@ -316,11 +521,17 @@ function Comm::table_iterator_value%(it: opaque of Comm::TableIterator%): Comm:: return rval; %} +## Create communication data of type "vector". function Comm::vector_create%(%): Comm::Data %{ return comm::make_data_val(broker::vector()); %} +## Remove all elements within a vector. +## +## v: the vector to clear. +## +## Returns: always true. function Comm::vector_clear%(v: Comm::Data%): bool %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -329,6 +540,11 @@ function Comm::vector_clear%(v: Comm::Data%): bool return new Val(true, TYPE_BOOL); %} +## Get the number of elements within a vector. +## +## v: the vector to query. +## +## Returns: the number of elements in the vector. function Comm::vector_size%(v: Comm::Data%): count %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -336,6 +552,17 @@ function Comm::vector_size%(v: Comm::Data%): count return new Val(static_cast(vec.size()), TYPE_COUNT); %} +## Insert an element into a vector at a particular position, possibly displacing +## existing elements (insertion always grows the size of the vector by one). +## +## v: the vector to modify. +## +## d: the element to insert. +## +## idx: the index at which to insert the data. If it is greater than the +## current size of the vector, the element is inserted at the end. +## +## Returns: always true. function Comm::vector_insert%(v: Comm::Data, d: Comm::Data, idx: count%): bool %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -346,6 +573,16 @@ function Comm::vector_insert%(v: Comm::Data, d: Comm::Data, idx: count%): bool return new Val(true, TYPE_BOOL); %} +## Replace an element in a vector at a particular position. +## +## v: the vector to modify. +## +## d: the element to insert. +## +## idx: the index to replace. +## +## Returns: the value that was just evicted. If the index was larger than any +## valid index, the optional field of the returned record is not set. function Comm::vector_replace%(v: Comm::Data, d: Comm::Data, idx: count%): Comm::Data %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -360,6 +597,14 @@ function Comm::vector_replace%(v: Comm::Data, d: Comm::Data, idx: count%): Comm: return rval; %} +## Remove an element from a vector at a particular position. +## +## v: the vector to modify. +## +## idx: the index to remove. +## +## Returns: the value that was just evicted. If the index was larger than any +## valid index, the optional field of the returned record is not set. function Comm::vector_remove%(v: Comm::Data, idx: count%): Comm::Data %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -373,6 +618,14 @@ function Comm::vector_remove%(v: Comm::Data, idx: count%): Comm::Data return rval; %} +## Lookup an element in a vector at a particular position. +## +## v: the vector to query. +## +## idx: the index to lookup. +## +## Returns: the value at the index. If the index was larger than any +## valid index, the optional field of the returned record is not set. function Comm::vector_lookup%(v: Comm::Data, idx: count%): Comm::Data %{ auto& vec = comm::require_data_type(v->AsRecordVal(), @@ -384,17 +637,36 @@ function Comm::vector_lookup%(v: Comm::Data, idx: count%): Comm::Data return comm::make_data_val(vec[idx]); %} +## Create an iterator for a vector. Note that this makes a copy of the vector +## internally to ensure the iterator is always valid. +## +## v: the vector to iterate over. +## +## Returns: an iterator. function Comm::vector_iterator%(v: Comm::Data%): opaque of Comm::VectorIterator %{ return new comm::VectorIterator(v->AsRecordVal(), TYPE_VECTOR, frame); %} +## Check if there are no more elements to iterate over. +## +## it: an iterator. +## +## Returns: true if there are no more elements to iterator over, i.e. +## the iterator is one-past-the-final-element. function Comm::vector_iterator_last%(it: opaque of Comm::VectorIterator%): bool %{ auto vi = static_cast(it); return new Val(vi->it == vi->dat.end(), TYPE_BOOL); %} +## Advance an iterator. +## +## it: an iterator. +## +## Returns: true if the iterator, after advancing, still references an element +## in the collection. False if the iterator, after advancing, is +## one-past-the-final-element. function Comm::vector_iterator_next%(it: opaque of Comm::VectorIterator%): bool %{ auto vi = static_cast(it); @@ -406,6 +678,11 @@ function Comm::vector_iterator_next%(it: opaque of Comm::VectorIterator%): bool return new Val(vi->it != vi->dat.end(), TYPE_BOOL); %} +## Retrieve the data at an iterator's current position. +## +## it: an iterator. +## +## Returns: element in the collection that the iterator currently references. function Comm::vector_iterator_value%(it: opaque of Comm::VectorIterator%): Comm::Data %{ auto vi = static_cast(it); @@ -414,7 +691,7 @@ function Comm::vector_iterator_value%(it: opaque of Comm::VectorIterator%): Comm if ( vi->it == vi->dat.end() ) { reporter->PushLocation(frame->GetCall()->GetLocationInfo()); - reporter->Warning("attempt to retrieve value of invalid table iterator"); + reporter->Warning("attempt to retrieve value of invalid vector iterator"); reporter->PopLocation(); return rval; } @@ -423,11 +700,21 @@ function Comm::vector_iterator_value%(it: opaque of Comm::VectorIterator%): Comm return rval; %} +## Create communication data of type "record". +## +## sz: the number of fields in the record. +## +## Returns: record data, with all fields uninitialized. function Comm::record_create%(sz: count%): Comm::Data %{ return comm::make_data_val(broker::record(std::vector(sz))); %} +## Get the number of fields within a record. +## +## r: the record to query. +## +## Returns: the number of fields in the record. function Comm::record_size%(r: Comm::Data%): count %{ auto& v = comm::require_data_type(r->AsRecordVal(), @@ -435,6 +722,15 @@ function Comm::record_size%(r: Comm::Data%): count return new Val(static_cast(v.fields.size()), TYPE_COUNT); %} +## Replace a field in a record at a particular position. +## +## t: the table to modify. +## +## d: the new field value to assign. +## +## idx: the index to replace. +## +## Returns: false if the index was larger than any valid index, else true. function Comm::record_assign%(r: Comm::Data, d: Comm::Data, idx: count%): bool %{ auto& v = comm::require_data_type(r->AsRecordVal(), @@ -448,6 +744,15 @@ function Comm::record_assign%(r: Comm::Data, d: Comm::Data, idx: count%): bool return new Val(true, TYPE_BOOL); %} +## Lookup a field in a record at a particular position. +## +## r: the record to query. +## +## idx: the index to lookup. +## +## Returns: the value at the index. The optional field of the returned record +## may not be set if the field of the record has no value or if the +## the index was not valid. function Comm::record_lookup%(r: Comm::Data, idx: count%): Comm::Data %{ auto& v = comm::require_data_type(r->AsRecordVal(), @@ -462,17 +767,36 @@ function Comm::record_lookup%(r: Comm::Data, idx: count%): Comm::Data return comm::make_data_val(*v.fields[idx]); %} +## Create an iterator for a record. Note that this makes a copy of the record +## internally to ensure the iterator is always valid. +## +## r: the record to iterate over. +## +## Returns: an iterator. function Comm::record_iterator%(r: Comm::Data%): opaque of Comm::RecordIterator %{ return new comm::RecordIterator(r->AsRecordVal(), TYPE_RECORD, frame); %} +## Check if there are no more elements to iterate over. +## +## it: an iterator. +## +## Returns: true if there are no more elements to iterator over, i.e. +## the iterator is one-past-the-final-element. function Comm::record_iterator_last%(it: opaque of Comm::RecordIterator%): bool %{ auto ri = static_cast(it); return new Val(ri->it == ri->dat.fields.end(), TYPE_BOOL); %} +## Advance an iterator. +## +## it: an iterator. +## +## Returns: true if the iterator, after advancing, still references an element +## in the collection. False if the iterator, after advancing, is +## one-past-the-final-element. function Comm::record_iterator_next%(it: opaque of Comm::RecordIterator%): bool %{ auto ri = static_cast(it); @@ -484,6 +808,11 @@ function Comm::record_iterator_next%(it: opaque of Comm::RecordIterator%): bool return new Val(ri->it != ri->dat.fields.end(), TYPE_BOOL); %} +## Retrieve the data at an iterator's current position. +## +## it: an iterator. +## +## Returns: element in the collection that the iterator currently references. function Comm::record_iterator_value%(it: opaque of Comm::RecordIterator%): Comm::Data %{ auto ri = static_cast(it); diff --git a/src/comm/messaging.bif b/src/comm/messaging.bif index 26f9497449..fb65c981b2 100644 --- a/src/comm/messaging.bif +++ b/src/comm/messaging.bif @@ -14,6 +14,15 @@ type Comm::EventArgs: record; event Comm::print_handler%(msg: string%); +## Print a simple message to any interested peers. +## +## topic: a topic associated with the printed message. +## +## msg: the print message to send to peers. +## +## flags: tune the behavior of how the message is sent. +## +## Returns: true if the message is sent. function Comm::print%(topic: string, msg: string, flags: SendFlags &default = SendFlags()%): bool %{ @@ -22,24 +31,53 @@ function Comm::print%(topic: string, msg: string, return new Val(rval, TYPE_BOOL); %} +## Register interest in all peer print messages that use a certain topic prefix. +## +## topic_prefix: a prefix to match against remote message topics. +## e.g. an empty prefix matches everything and "a" matches +## "alice" and "amy" but not "bob". +## +## Returns: true if it's a new print subscription and it is now registered. function Comm::subscribe_to_prints%(topic_prefix: string%): bool %{ auto rval = comm_mgr->SubscribeToPrints(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} +## Unregister interest in all peer print messages that use a topic prefix. +## +## topic_prefix: a prefix previously supplied to a successful call to +## :bro:see:`Comm::subscribe_to_prints`. +## +## Returns: true if interest in the topic prefix is no longer advertised. function Comm::unsubscribe_to_prints%(topic_prefix: string%): bool %{ auto rval = comm_mgr->UnsubscribeToPrints(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} +## Create a data structure that may be used to send a remote event via +## :bro:see:`Comm::event`. +## +## args: an event, followed by a list of argument values that may be used +## to call it. +## +## Returns: opaque communication data that may be used to send a remote event. function Comm::event_args%(...%): Comm::EventArgs %{ auto rval = comm_mgr->MakeEventArgs(@ARGS@); return rval; %} +## Send an event to any interested peers. +## +## topic: a topic associated with the event message. +## +## args: event arguments as made by :bro:see:`Comm::event_args`. +## +## flags: tune the behavior of how the message is sent. +## +## Returns: true if the message is sent. function Comm::event%(topic: string, args: Comm::EventArgs, flags: SendFlags &default = SendFlags()%): bool %{ @@ -48,6 +86,18 @@ function Comm::event%(topic: string, args: Comm::EventArgs, return new Val(rval, TYPE_BOOL); %} +## Automatically send an event to any interested peers whenever it is +## locally dispatched (e.g. using "event my_event(...);" in a script). +## +## topic: a topic string associated with the event message. +## Peers advertise interest by registering a subscription to some prefix +## of this topic name. +## +## ev: a Bro event value. +## +## flags: tune the behavior of how the message is send. +## +## Returns: true if automatic event sending is now enabled. function Comm::auto_event%(topic: string, ev: any, flags: SendFlags &default = SendFlags()%): bool %{ @@ -55,51 +105,101 @@ function Comm::auto_event%(topic: string, ev: any, return new Val(rval, TYPE_BOOL); %} +## Stop automatically sending an event to peers upon local dispatch. +## +## topic: a topic originally given to :bro:see:`Comm::auto_event`. +## +## ev: an event originally given to :bro:see:`Comm::auto_event`. +## +## Returns: true if automatic events will no occur for the topic/event pair. function Comm::auto_event_stop%(topic: string, ev: any%): bool %{ auto rval = comm_mgr->AutoEventStop(topic->CheckString(), ev); return new Val(rval, TYPE_BOOL); %} +## Register interest in all peer event messages that use a certain topic prefix. +## +## topic_prefix: a prefix to match against remote message topics. +## e.g. an empty prefix matches everything and "a" matches +## "alice" and "amy" but not "bob". +## +## Returns: true if it's a new event subscription and it is now registered. function Comm::subscribe_to_events%(topic_prefix: string%): bool %{ auto rval = comm_mgr->SubscribeToEvents(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} +## Unregister interest in all peer event messages that use a topic prefix. +## +## topic_prefix: a prefix previously supplied to a successful call to +## :bro:see:`Comm::subscribe_to_events`. +## +## Returns: true if interest in the topic prefix is no longer advertised. function Comm::unsubscribe_to_events%(topic_prefix: string%): bool %{ auto rval = comm_mgr->UnsubscribeToEvents(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} +## Enable remote logs for a given log stream. +## +## id: the log stream to enable remote logs for. +## +## flags: tune the behavior of how log entry messages are sent. +## +## Returns: true if remote logs are enabled for the stream. function Comm::enable_remote_logs%(id: Log::ID, flags: SendFlags &default = SendFlags()%): bool %{ auto rval = log_mgr->EnableRemoteLogs(id->AsEnumVal(), - comm::Manager::GetFlags(flags)); + comm::Manager::send_flags_to_int(flags)); return new Val(rval, TYPE_BOOL); %} +## Disable remote logs for a given log stream. +## +## id: the log stream to disable remote logs for. +## +## Returns: true if remote logs are disabled for the stream. function Comm::disable_remote_logs%(id: Log::ID%): bool %{ auto rval = log_mgr->DisableRemoteLogs(id->AsEnumVal()); return new Val(rval, TYPE_BOOL); %} +## Returns: true if remote logs are enabled for the given stream. function Comm::remote_logs_enabled%(id: Log::ID%): bool %{ auto rval = log_mgr->RemoteLogsAreEnabled(id->AsEnumVal()); return new Val(rval, TYPE_BOOL); %} +## Register interest in all peer log messages that use a certain topic prefix. +## Logs are implicitly sent with topic "bro/log/" and the +## receiving side processes them through the logging framework as usual. +## +## topic_prefix: a prefix to match against remote message topics. +## e.g. an empty prefix matches everything and "a" matches +## "alice" and "amy" but not "bob". +## +## Returns: true if it's a new log subscription and it is now registered. function Comm::subscribe_to_logs%(topic_prefix: string%): bool %{ auto rval = comm_mgr->SubscribeToLogs(topic_prefix->CheckString()); return new Val(rval, TYPE_BOOL); %} +## Unregister interest in all peer log messages that use a topic prefix. +## Logs are implicitly sent with topic "bro/log/" and the +## receiving side processes them through the logging framework as usual. +## +## topic_prefix: a prefix previously supplied to a successful call to +## :bro:see:`Comm::subscribe_to_logs`. +## +## Returns: true if interest in the topic prefix is no longer advertised. function Comm::unsubscribe_to_logs%(topic_prefix: string%): bool %{ auto rval = comm_mgr->UnsubscribeToLogs(topic_prefix->CheckString()); diff --git a/src/comm/store.bif b/src/comm/store.bif index 18e63282e8..6a27c05dcb 100644 --- a/src/comm/store.bif +++ b/src/comm/store.bif @@ -16,12 +16,22 @@ type Store::QueryResult: record; type Store::BackendOptions: record; +## Enumerates the possible storage backends. enum BackendType %{ MEMORY, SQLITE, ROCKSDB, %} +## Create a master data store which contains key-value pairs. +## +## id: a unique name for the data store. +## +## b: the storage backend to use. +## +## options: tunes how some storage backends operate. +## +## Returns: a handle to the data store. function Store::create_master%(id: string, b: BackendType &default = MEMORY, options: BackendOptions &default = BackendOptions()%): opaque of Store::Handle %{ @@ -42,6 +52,28 @@ function Store::create_master%(id: string, b: BackendType &default = MEMORY, return rval; %} +## Create a clone of a master data store which may live with a remote peer. +## A clone automatically synchronizes to the master by automatically receiving +## modifications and applying them locally. Direct modifications are not +## possible, they must be sent through the master store, which then +## automatically broadcasts the changes out to clones. But queries may be made +## directly against the local cloned copy, which may be resolved quicker than +## reaching out to a remote master store. +## +## id: the unique name which identifies the master data store. +## +## b: the storage backend to use. +## +## options: tunes how some storage backends operate. +## +## resync: the interval at which to re-attempt synchronizing with the master +## store should the connection be lost. If the clone has not yet +## synchronized for the first time, updates and queries queue up until +## the synchronization completes. After, if the connection to the +## master store is lost, queries continue to use the clone's version, +## but updates will be lost until the master is once again available. +## +## Returns: a handle to the data store. function Store::create_clone%(id: string, b: BackendType &default = MEMORY, options: BackendOptions &default = BackendOptions(), resync: interval &default = 1sec%): opaque of Store::Handle @@ -64,6 +96,12 @@ function Store::create_clone%(id: string, b: BackendType &default = MEMORY, return rval; %} +## Create a frontend interface to an existing master data store that allows +## querying and updating its contents. +## +## id: the unique name which identifies the master data store. +## +## Returns: a handle to the data store. function Store::create_frontend%(id: string%): opaque of Store::Handle %{ auto id_str = id->CheckString(); @@ -81,6 +119,12 @@ function Store::create_frontend%(id: string%): opaque of Store::Handle return rval; %} +## Close a data store. +## +## h: a data store handle. +## +## Returns: true if store was valid and is now closed. The handle can no +## longer be used for data store operations. function Store::close_by_handle%(h: opaque of Store::Handle%): bool %{ auto handle = static_cast(h); @@ -96,6 +140,17 @@ function Store::close_by_handle%(h: opaque of Store::Handle%): bool # non-blocking update API # ########################### +## Insert a key-value pair in to the store. +## +## h: the handle of the store to modify. +## +## k: the key to insert. +## +## v: the value to insert. +## +## e: the expiration time of the key-value pair. +## +## Returns: false if the store handle was not valid. function Store::insert%(h: opaque of Store::Handle, k: Comm::Data, v: Comm::Data, e: Store::ExpiryTime &default = Store::ExpiryTime()%): bool @@ -134,6 +189,13 @@ function Store::insert%(h: opaque of Store::Handle, return new Val(true, TYPE_BOOL); %} +## Remove a key-value pair from the store. +## +## h: the handle of the store to modify. +## +## k: the key to remove. +## +## Returns: false if the store handle was not valid. function Store::erase%(h: opaque of Store::Handle, k: Comm::Data%): bool %{ auto handle = static_cast(h); @@ -146,6 +208,11 @@ function Store::erase%(h: opaque of Store::Handle, k: Comm::Data%): bool return new Val(true, TYPE_BOOL); %} +## Remove all key-value pairs from the store. +## +## h: the handle of the store to modify. +## +## Returns: false if the store handle was not valid. function Store::clear%(h: opaque of Store::Handle%): bool %{ auto handle = static_cast(h); @@ -157,6 +224,16 @@ function Store::clear%(h: opaque of Store::Handle%): bool return new Val(true, TYPE_BOOL); %} +## Increment an integer value in a data store. +## +## h: the handle of the store to modify. +## +## k: the key whose associated value is to be modified. +## +## by: the amount to increment the value by. A non-existent key will first +## create it with an implicit value of zero before incrementing. +## +## Returns: false if the store handle was not valid. function Store::increment%(h: opaque of Store::Handle, k: Comm::Data, by: int &default = +1%): bool %{ @@ -170,6 +247,16 @@ function Store::increment%(h: opaque of Store::Handle, return new Val(true, TYPE_BOOL); %} +## Decrement an integer value in a data store. +## +## h: the handle of the store to modify. +## +## k: the key whose associated value is to be modified. +## +## by: the amount to decrement the value by. A non-existent key will first +## create it with an implicit value of zero before decrementing. +## +## Returns: false if the store handle was not valid. function Store::decrement%(h: opaque of Store::Handle, k: Comm::Data, by: int &default = +1%): bool %{ @@ -183,6 +270,16 @@ function Store::decrement%(h: opaque of Store::Handle, return new Val(true, TYPE_BOOL); %} +## Add an element to a set value in a data store. +## +## h: the handle of the store to modify. +## +## k: the key whose associated value is to be modified. +## +## element: the element to add to the set. A non-existent key will first +## create it with an implicit empty set value before modifying. +## +## Returns: false if the store handle was not valid. function Store::add_to_set%(h: opaque of Store::Handle, k: Comm::Data, element: Comm::Data%): bool %{ @@ -197,6 +294,16 @@ function Store::add_to_set%(h: opaque of Store::Handle, return new Val(true, TYPE_BOOL); %} +## Remove an element from a set value in a data store. +## +## h: the handle of the store to modify. +## +## k: the key whose associated value is to be modified. +## +## element: the element to remove from the set. A non-existent key will +## implicitly create an empty set value associated with the key. +## +## Returns: false if the store handle was not valid. function Store::remove_from_set%(h: opaque of Store::Handle, k: Comm::Data, element: Comm::Data%): bool %{ @@ -211,6 +318,16 @@ function Store::remove_from_set%(h: opaque of Store::Handle, return new Val(true, TYPE_BOOL); %} +## Add a new item to the head of a vector value in a data store. +## +## h: the handle of store to modify. +## +## k: the key whose associated value is to be modified. +## +## item: the element to insert in to the vector. A non-existent key will first +## create empty vector value before modifying. +## +## Returns: the handle of store to modify. function Store::push_left%(h: opaque of Store::Handle, k: Comm::Data, items: Comm::DataVector%): bool %{ @@ -234,6 +351,16 @@ function Store::push_left%(h: opaque of Store::Handle, k: Comm::Data, return new Val(true, TYPE_BOOL); %} +## Add a new item to the tail of a vector value in a data store. +## +## h: the handle of store to modify. +## +## k: the key whose associated value is to be modified. +## +## item: the element to insert in to the vector. A non-existent key will first +## create empty vector value before modifying. +## +## Returns: the handle of store to modify. function Store::push_right%(h: opaque of Store::Handle, k: Comm::Data, items: Comm::DataVector%): bool %{ @@ -297,20 +424,23 @@ static bool prepare_for_query(Val* opaque, Frame* frame, *cb = new comm::StoreQueryCallback(trigger, frame->GetCall(), (*handle)->store->id(), (*handle)->store_type); - comm_mgr->TrackStoreQuery(*cb); + comm_mgr->TrackStoreQuery(*cb); return true; } %%} +## Pop the head of a data store vector value. +## +## h: the handle of the store to query. +## +## k: the key associated with the vector to modify. +## +## Returns: the result of the query. function Store::pop_left%(h: opaque of Store::Handle, k: Comm::Data%): Store::QueryResult %{ - double timeout; - comm::StoreQueryCallback* cb; - comm::StoreHandleVal* handle; - - if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + if ( ! comm_mgr->Enabled() ) return comm::query_result(); Val* key = k->AsRecordVal()->Lookup(0); @@ -318,19 +448,29 @@ function Store::pop_left%(h: opaque of Store::Handle, if ( ! key ) return comm::query_result(); + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + handle->store->pop_left(static_cast(key)->data, std::chrono::duration(timeout), cb); return 0; %} +## Pop the tail of a data store vector value. +## +## h: the handle of the store to query. +## +## k: the key associated with the vector to modify. +## +## Returns: the result of the query. function Store::pop_right%(h: opaque of Store::Handle, k: Comm::Data%): Store::QueryResult %{ - double timeout; - comm::StoreQueryCallback* cb; - comm::StoreHandleVal* handle; - - if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + if ( ! comm_mgr->Enabled() ) return comm::query_result(); Val* key = k->AsRecordVal()->Lookup(0); @@ -338,19 +478,29 @@ function Store::pop_right%(h: opaque of Store::Handle, if ( ! key ) return comm::query_result(); + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + handle->store->pop_right(static_cast(key)->data, std::chrono::duration(timeout), cb); return 0; %} +## Lookup the value associated with a key in a data store. +## +## h: the handle of the store to query. +## +## k: the key to lookup. +## +## Returns: the result of the query. function Store::lookup%(h: opaque of Store::Handle, k: Comm::Data%): Store::QueryResult %{ - double timeout; - comm::StoreQueryCallback* cb; - comm::StoreHandleVal* handle; - - if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + if ( ! comm_mgr->Enabled() ) return comm::query_result(); Val* key = k->AsRecordVal()->Lookup(0); @@ -358,19 +508,29 @@ function Store::lookup%(h: opaque of Store::Handle, if ( ! key ) return comm::query_result(); + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + handle->store->lookup(static_cast(key)->data, std::chrono::duration(timeout), cb); return 0; %} +## Check if a data store contains a given key. +## +## h: the handle of the store to query. +## +## k: the key to check for existence. +## +## Returns: the result of the query (uses :bro:see:`Comm::BOOL`). function Store::exists%(h: opaque of Store::Handle, k: Comm::Data%): Store::QueryResult %{ - double timeout; - comm::StoreQueryCallback* cb; - comm::StoreHandleVal* handle; - - if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + if ( ! comm_mgr->Enabled() ) return comm::query_result(); Val* key = k->AsRecordVal()->Lookup(0); @@ -378,11 +538,23 @@ function Store::exists%(h: opaque of Store::Handle, if ( ! key ) return comm::query_result(); + double timeout; + comm::StoreQueryCallback* cb; + comm::StoreHandleVal* handle; + + if ( ! prepare_for_query(h, frame, &handle, &timeout, &cb) ) + return comm::query_result(); + handle->store->exists(static_cast(key)->data, std::chrono::duration(timeout), cb); return 0; %} +## Retrieve all keys in a data store. +## +## h: the handle of the store to query. +## +## Returns: the result of the query (uses :bro:see:`Comm::VECTOR`). function Store::keys%(h: opaque of Store::Handle%): Store::QueryResult %{ double timeout; @@ -396,8 +568,16 @@ function Store::keys%(h: opaque of Store::Handle%): Store::QueryResult return 0; %} +## Get the number of key-value pairs in a data store. +## +## h: the handle of the store to query. +## +## Returns: the result of the query (uses :bro:see:`Comm::COUNT`). function Store::size%(h: opaque of Store::Handle%): Store::QueryResult %{ + if ( ! comm_mgr->Enabled() ) + return comm::query_result(); + double timeout; comm::StoreQueryCallback* cb; comm::StoreHandleVal* handle; diff --git a/src/logging/Manager.h b/src/logging/Manager.h index 8130a1ddd4..5d3372fb9b 100644 --- a/src/logging/Manager.h +++ b/src/logging/Manager.h @@ -158,12 +158,30 @@ public: void Terminate(); #ifdef ENABLE_BROKER + /** + * Enable remote logs for a given stream. + * @param stream_id the stream to enable remote logs for. + * @param flags tune behavior of how log entries are sent to peer endpoints. + * @return true if remote logs are enabled. + */ bool EnableRemoteLogs(EnumVal* stream_id, int flags); + /** + * Disable remote logs for a given stream. + * @param stream_id the stream to disable remote logs for. + * @return true if remote logs are disabled. + */ bool DisableRemoteLogs(EnumVal* stream_id); + /** + * @return true if remote logs are enabled for a given stream. + */ bool RemoteLogsAreEnabled(EnumVal* stream_id); + /** + * @return the type which corresponds to the columns in a log entry for + * a given log stream. + */ RecordType* StreamColumns(EnumVal* stream_id); #endif From 9025b425344c150b5c06431b63cf3995c60916bb Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 17 Feb 2015 12:56:36 -0800 Subject: [PATCH 085/256] Updating submodule. --- aux/bro-aux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/bro-aux b/aux/bro-aux index 8c37b26823..fa145348ab 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 8c37b26823ada9c77614b2f8f781c11c8fe3d078 +Subproject commit fa145348abe15dcd5f8e52cc96e1fb758c092e36 From 818ba9127f4856f1e83c5e42eba0117adfeafdbe Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 17 Feb 2015 13:59:21 -0800 Subject: [PATCH 086/256] Update submodules. --- aux/bro-aux | 2 +- cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aux/bro-aux b/aux/bro-aux index fa145348ab..c409d529cf 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit fa145348abe15dcd5f8e52cc96e1fb758c092e36 +Subproject commit c409d529cf0c3fa851d4720914badb04d0c6b7c2 diff --git a/cmake b/cmake index 9623367210..5e4e3507e2 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 962336721040fdf55a6b264f8bbc84153b54d9a5 +Subproject commit 5e4e3507e280c393778fd55fb0124217067e0078 From 093d4069206b9ae7ced009241cdd8e70aec1c4ec Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 17 Feb 2015 14:03:05 -0800 Subject: [PATCH 087/256] Updating plugin docs to recent changes. --- doc/devel/plugins.rst | 97 ++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/doc/devel/plugins.rst b/doc/devel/plugins.rst index c703345891..66ffba101f 100644 --- a/doc/devel/plugins.rst +++ b/doc/devel/plugins.rst @@ -3,7 +3,7 @@ Writing Bro Plugins =================== -Bro is internally moving to a plugin structure that enables extending +Bro internally provides plugin API that enables extending the system dynamically, without modifying the core code base. That way custom code remains self-contained and can be maintained, compiled, and installed independently. Currently, plugins can add the following @@ -42,13 +42,13 @@ certain structure. To get started, Bro's distribution provides a helper script ``aux/bro-aux/plugin-support/init-plugin`` that creates a skeleton plugin that can then be customized. Let's use that:: - # mkdir rot13-plugin - # cd rot13-plugin - # init-plugin Demo Rot13 + # init-plugin ./rot13-plugin Demo Rot13 -As you can see the script takes two arguments. The first is a -namespace the plugin will live in, and the second a descriptive name -for the plugin itself. Bro uses the combination of the two to identify +As you can see the script takes three arguments. The first is a +directory inside which the plugin skeleton will be create; it +shouldn't exist it. The second is namespace the plugin will live in, +and the third a descriptive name for the plugin itself relative to the +namespace. Bro uses the combination of namespace and name to identify a plugin. The namespace serves to avoid naming conflicts between plugins written by independent developers; pick, e.g., the name of your organisation. The namespace ``Bro`` is reserved for functionality @@ -82,18 +82,22 @@ The syntax of this file is just like any other ``*.bif`` file; we won't go into it here. Now we can already compile our plugin, we just need to tell the -configure script put in place by ``init-plugin`` where the Bro source -tree is located (Bro needs to have been built there first):: +configure script that ``init-plugin`` put in place where the Bro +source tree is located (Bro needs to have been built there first):: + # cd rot13-plugin # ./configure --bro-dist=/path/to/bro/dist && make [... cmake output ...] -Now our ``rot13-plugin`` directory has everything that it needs -for Bro to recognize it as a dynamic plugin. Once we point Bro to it, -it will pull it in automatically, as we can check with the ``-N`` +This builds the plugin in a subdirectory ``build/``. In fact, that +subdirectory *becomes* the plugin: when ``make`` finishes, ``build/`` +has everything it needs for Bro to recognize it as a dynamic plugin. + +Let's try that. Once we point Bro to the ``build/`` directory, it will +pull in our new plugin automatically, as we can check with the ``-N`` option:: - # export BRO_PLUGIN_PATH=/path/to/rot13-plugin + # export BRO_PLUGIN_PATH=/path/to/rot13-plugin/build # bro -N [...] Plugin: Demo::Rot13 - (dynamic, version 1) @@ -153,24 +157,28 @@ Once we install it, it works again:: The installed version went into ``/lib/bro/plugins/Demo_Rot13``. -We can distribute the plugin in either source or binary form by using -the Makefile's ``sdist`` and ``bdist`` target, respectively. Both -create corrsponding tarballs:: +One can distribute the plugin independently of Bro for others to use. +To distribute in source form, just remove the ``build/`` (``make +distclean`` does that) and then tar up the whole ``rot13-plugin/`` +directory. Others then follow the same process as above after +unpacking. To distribute the plugin in binary form, the build process +conviniently creates a corresponding tarball in ``build/dist/``. In +this case, it's called ``Demo_Rot13-0.1.tar.gz``, with the version +number coming out of the ``VERSION`` file that ``init-plugin`` put +into place. The binary tarball has everything needed to run the +plugin, but no further source files. Optionally, one can include +further files by specifying them in the plugin's ``CMakeLists.txt`` +through the ``bro_plugin_dist_files`` macro; the skeleton does that +for ``README``, ``VERSION``, ``CHANGES``, and ``COPYING``. To use the +plugin through the binary tarball, just unpack it and point +``BRO_PLUGIN_PATH`` there; or copy it into +``/lib/bro/plugins/`` directly. - # make sdist - [...] - Source distribution in build/sdist/Demo_Rot13.tar.gz - - # make bdist - [...] - Binary distribution in build/Demo_Rot13-darwin-x86_64.tar.gz - -The source archive will contain everything in the plugin directory -except any generated files. The binary archive will contain anything -needed to install and run the plugin, i.e., just what ``make install`` -puts into place as well. As the binary distribution is -platform-dependent, its name includes the OS and architecture the -plugin was built on. +Before distributing your plugin, you should edit some of the meta +files that ``init-plugin`` puts in place. Edit ``README`` and +``VERSION``, and update ``CHANGES`` when you make changes. Also put a +license file in place as ``COPYING``; if BSD is fine, you find a +template in ``COPYING.edit-me``. Plugin Directory Layout ======================= @@ -179,7 +187,7 @@ A plugin's directory needs to follow a set of conventions so that Bro (1) recognizes it as a plugin, and (2) knows what to load. While ``init-plugin`` takes care of most of this, the following is the full story. We'll use ```` to represent a plugin's top-level -directory. +directory. With the skeleton, ```` corresponds to ``build/``. ``/__bro_plugin__`` A file that marks a directory as containing a Bro plugin. The file @@ -205,6 +213,8 @@ directory. Directory with auto-generated Bro scripts that declare the plugin's bif elements. The files here are produced by ``bifcl``. +Any other files in ```` are ignored by Bro. + By convention, a plugin should put its custom scripts into sub folders of ``scripts/``, i.e., ``scripts//

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 literal 0 HcmV?d00001 From c268898e046008699602b5480e59e7d844308aeb Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sat, 14 Feb 2015 14:01:46 -0800 Subject: [PATCH 062/256] Add btest for FreeRDP pcap sample (NLA authentication) https://github.com/FreeRDP/FreeRDP/wiki/Network-Level-Authentication --- .../btest/Traces/rdp/nla_win7_win2k8r2.pcap | Bin 0 -> 134982 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap diff --git a/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap b/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3a6a2999eba4fa36f1655a95464494db44c8bede GIT binary patch literal 134982 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 e_S;kcZG8CMef3`TrFsiUL3u2o@ Date: Sun, 15 Feb 2015 09:24:28 -0800 Subject: [PATCH 063/256] Removed debug code for SSL --- scripts/base/protocols/rdp/main.bro | 67 ++--------- src/analyzer/protocol/rdp/RDP.cc | 3 - src/analyzer/protocol/rdp/events.bif | 33 +----- src/analyzer/protocol/rdp/rdp-analyzer.pac | 92 +++++---------- src/analyzer/protocol/rdp/rdp-protocol.pac | 125 +++++++-------------- 5 files changed, 80 insertions(+), 240 deletions(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 94aa26b6ec..0369cad3d4 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -14,7 +14,7 @@ export { id: conn_id &log; ## Cookie value used by the client machine. ## This is typically a username. - cookie: string &log &optional; + cookie: string &log &optional; ## Keyboard layout (language) of the client machine. keyboard_layout: string &log &optional; ## RDP client version used by the client machine. @@ -23,11 +23,8 @@ export { client_hostname: string &log &optional; ## Product ID of the client machine. client_product_id: string &log &optional; - ## Name of the server. - server_name: vector of string &log &optional; - ## Authentication result for the connection. This value is extracted from the payload for native authentication. - ## TODO: Perform heuristic authentication determination for NLA. - authentication_result: string &log &optional; + ## GCC result for the connection. This value is extracted from the payload for native encryption. + result: string &log &optional; ## Encryption level of the connection. encryption_level: string &log &optional; ## Encryption method of the connection. @@ -36,12 +33,6 @@ export { done: bool &default=F; }; - ## Variable to track if NTLM authentication is used. - global ntlm = F; - - ## Size in bytes of data sent by the server at which the RDP connection is presumed to be successful (NTLM authentication only). - const authentication_data_size = 1000 &redef; - ## Event that can be handled to access the rdp record as it is sent on ## to the loggin framework. global log_rdp: event(rec: Info); @@ -66,17 +57,6 @@ function rdp_done(c: connection, done: bool) { c$rdp$done = T; - # Not currently implemented -# if ( ntlm && use_conn_size_analyzer ) -# { -# if ( c$resp$size > authentication_data_size ) -# c$rdp$authentication_result = "Success (H)"; -# else c$rdp$authentication_result = "Undetermined"; -# } - - if ( c$rdp?$authentication_result && ( ! c$rdp?$encryption_method || ! c$rdp?$encryption_level ) ) - Reporter::error(fmt("Error parsing RDP security data in connection %s",c$uid)); - Log::write(RDP::LOG, c$rdp); skip_further_processing(c$id); set_record_packets(c$id, F); @@ -110,7 +90,7 @@ event rdp_tracker(c: connection) } } - # schedule the event to run again if necessary + # Schedule the event to run again if necessary schedule +5secs { rdp_tracker(c) }; } @@ -130,7 +110,7 @@ event connection_state_remove(c: connection) &priority=-5 rdp_done(c,T); } -event rdp_native_client_request(c: connection, cookie: string) &priority=5 +event rdp_client_request(c: connection, cookie: string) &priority=5 { if ( "Cookie" in clean(cookie) ) { @@ -142,7 +122,7 @@ event rdp_native_client_request(c: connection, cookie: string) &priority=5 } } -event rdp_native_client_info(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5 +event rdp_client_data(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5 { set_session(c); c$rdp$keyboard_layout = languages[keyboard_layout]; @@ -153,15 +133,15 @@ event rdp_native_client_info(c: connection, keyboard_layout: count, build: count schedule +5secs { rdp_tracker(c) }; } -event rdp_native_authentication(c: connection, result: count) &priority=5 +event rdp_result(c: connection, result: count) &priority=5 { set_session(c); - c$rdp$authentication_result = results[result]; + c$rdp$result = results[result]; schedule +5secs { rdp_tracker(c) }; } -event rdp_native_server_security(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string) &priority=5 +event rdp_server_security(c: connection, encryption_method: count, encryption_level: count) &priority=5 { set_session(c); c$rdp$encryption_method = encryption_methods[encryption_method]; @@ -169,32 +149,3 @@ event rdp_native_server_security(c: connection, encryption_method: count, encryp schedule +5secs { rdp_tracker(c) }; } - -event rdp_ntlm_client_request(c: connection, server: string) &priority=5 - { - set_session(c); - ntlm = T; - - if ( ! c$rdp?$server_name ) - c$rdp$server_name = vector(); - c$rdp$server_name[|c$rdp$server_name|] = server; - - schedule +5secs { rdp_tracker(c) }; - } - -event rdp_ntlm_server_response(c: connection, server: string) &priority=5 - { - set_session(c); - ntlm = T; - - if ( ! c$rdp?$server_name ) - c$rdp$server_name = vector(); - c$rdp$server_name[|c$rdp$server_name|] = server; - - schedule +5secs { rdp_tracker(c) }; - } - -event rdp_debug(c: connection, remainder: string) - { - Reporter::error(fmt("Debug RDP data generated in connection %s: %s",c$uid,remainder)); - } diff --git a/src/analyzer/protocol/rdp/RDP.cc b/src/analyzer/protocol/rdp/RDP.cc index 70cad773fe..aca184d844 100644 --- a/src/analyzer/protocol/rdp/RDP.cc +++ b/src/analyzer/protocol/rdp/RDP.cc @@ -1,9 +1,6 @@ #include "RDP.h" - #include "analyzer/protocol/tcp/TCP_Reassembler.h" - #include "Reporter.h" - #include "events.bif.h" using namespace analyzer::rdp; diff --git a/src/analyzer/protocol/rdp/events.bif b/src/analyzer/protocol/rdp/events.bif index dad76f801b..65917e98be 100644 --- a/src/analyzer/protocol/rdp/events.bif +++ b/src/analyzer/protocol/rdp/events.bif @@ -1,23 +1,9 @@ -## Generated for client-to-server RDP requests when NTLM authentication is used. -## -## c: The connection record for the underlying transport-layer session/flow. -## -## server: The RDP server name requested by the client. -event rdp_ntlm_client_request%(c: connection, server: string%); - -## Generated for server-to-client RDP responses when NTLM authentication is used. -## -## c: The connection record for the underlying transport-layer session/flow. -## -## server: The RDP server name responsed by the server. -event rdp_ntlm_server_response%(c: connection, server: string%); - ## Generated for X.224 client requests when native RDP encryption is used. ## ## c: The connection record for the underlying transport-layer session/flow. ## ## cookie: The cookie included in the request. -event rdp_native_client_request%(c: connection, cookie: string%); +event rdp_client_request%(c: connection, cookie: string%); ## Generated for MCS client requests when native RDP encryption is used. ## @@ -30,14 +16,14 @@ event rdp_native_client_request%(c: connection, cookie: string%); ## hostname: The hostname of the client machine (optional). ## ## product_id: The product ID of the client machine (optional). -event rdp_native_client_info%(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string%); +event rdp_client_data%(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string%); ## Generated for MCS server responses when native RDP encryption is used. ## ## c: The connection record for the underlying transport-layer session/flow. ## ## result: The 8-bit integer representing the GCC Conference Create Response result. -event rdp_native_authentication%(c: connection, result: count%); +event rdp_result%(c: connection, result: count%); ## Generated for MCS server responses when native RDP encryption is used. ## @@ -46,15 +32,4 @@ event rdp_native_authentication%(c: connection, result: count%); ## encryption_method: The 32-bit integer representing the encryption method used in the connection. ## ## encryption_level: The 32-bit integer representing the encryption level used in the connection. -## -## random: The random value used to derive session keys (optional). -## -## certificate: The certificate containing the server's public key information. -event rdp_native_server_security%(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string%); - -## Generated for unknown elements in RDP connections. Used for debugging and development purposes only. -## -## c: The connection record for the underlying transport-layer session/flow. -## -## remainder: The data to be debugged. -event rdp_debug%(c: connection, remainder: string%); +event rdp_server_security%(c: connection, encryption_method: count, encryption_level: count%); diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac index f95ff9f589..04d64409bd 100644 --- a/src/analyzer/protocol/rdp/rdp-analyzer.pac +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -1,101 +1,59 @@ refine flow RDP_Flow += { - function proc_rdp_debug(debug: Debug): bool - %{ - BifEvent::generate_rdp_debug(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${debug.remainder})); + function proc_rdp_client_request(client_request: ClientRequest): bool + %{ + BifEvent::generate_rdp_client_request(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${client_request.cookie})); return true; %} - function proc_rdp_ntlm_server_response(ntlm_server: NTLMServerResponse): bool + function proc_rdp_result(gcc_response: GCC_Server_CreateResponse): bool %{ - BifEvent::generate_rdp_ntlm_server_response(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${ntlm_server.server_name})); - - return true; - %} - - function proc_rdp_ntlm_client_request(ntlm_client: NTLMClientRequest): bool - %{ - BifEvent::generate_rdp_ntlm_client_request(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${ntlm_client.server_name})); - - return true; - %} - - function proc_rdp_native_client_request(client_request: ClientRequest): bool - %{ - BifEvent::generate_rdp_native_client_request(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${client_request.cookie})); - - return true; - %} - - - function proc_rdp_native_authentication(gcc_response: GCC_Server_CreateResponse): bool - %{ - BifEvent::generate_rdp_native_authentication(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ${gcc_response.result}); + BifEvent::generate_rdp_result(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${gcc_response.result}); return true; %} - function proc_rdp_native_client_info(ccore: ClientCore): bool + function proc_rdp_client_data(ccore: ClientCore): bool %{ - BifEvent::generate_rdp_native_client_info(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ${ccore.keyboard_layout}, - ${ccore.client_build}, - bytestring_to_val(${ccore.client_name}), - bytestring_to_val(${ccore.dig_product_id})); + BifEvent::generate_rdp_client_data(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${ccore.keyboard_layout}, + ${ccore.client_build}, + bytestring_to_val(${ccore.client_name}), + bytestring_to_val(${ccore.dig_product_id})); return true; %} - function proc_rdp_native_server_security(ssd: ServerSecurityData): bool + function proc_rdp_server_security(ssd: ServerSecurityData): bool %{ - BifEvent::generate_rdp_native_server_security(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ${ssd.encryption_method}, - ${ssd.encryption_level}, - bytestring_to_val(${ssd.server_random}), - bytestring_to_val(${ssd.server_certificate})); + BifEvent::generate_rdp_server_security(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${ssd.encryption_method}, + ${ssd.encryption_level}); return true; %} }; -refine typeattr Debug += &let { - proc: bool = $context.flow.proc_rdp_debug(this); -}; - -refine typeattr NTLMServerResponse += &let { - proc: bool = $context.flow.proc_rdp_ntlm_server_response(this); -}; - -refine typeattr NTLMClientRequest += &let { - proc: bool = $context.flow.proc_rdp_ntlm_client_request(this); -}; - refine typeattr ClientRequest += &let { - proc: bool = $context.flow.proc_rdp_native_client_request(this); + proc: bool = $context.flow.proc_rdp_client_request(this); }; refine typeattr ClientCore += &let { - proc: bool = $context.flow.proc_rdp_native_client_info(this); + proc: bool = $context.flow.proc_rdp_client_data(this); }; refine typeattr GCC_Server_CreateResponse += &let { - proc: bool = $context.flow.proc_rdp_native_authentication(this); + proc: bool = $context.flow.proc_rdp_result(this); }; refine typeattr ServerSecurityData += &let { - proc: bool = $context.flow.proc_rdp_native_server_security(this); + proc: bool = $context.flow.proc_rdp_server_security(this); }; diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac index ea68040314..d9546dbdc9 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -1,8 +1,8 @@ type RDP_PDU(is_orig: bool) = record { - type: uint16; + type: uint8; switch: case type of { - 0x1603 -> ntlm_authentication: NTLMAuthentication; # NTLM authentication appears to be flagged by this 16-bit integer - default -> native_encryption: NativeEncryption; # assume native encryption, this should be the value of the TPKT version + 0x16 -> ssl_encryption: bytestring &restofdata &transient; # send to SSL analyzer in the future + default -> native_encryption: NativeEncryption; # TPKT version }; } &byteorder=bigendian; @@ -11,8 +11,9 @@ type RDP_PDU(is_orig: bool) = record { ###################################################################### type NativeEncryption = record { - pad: padding[2]; # remaining TPKT values - cotp: COTP; + tpkt_reserved: uint8; + tpkt_length: uint16; + cotp: COTP; }; type COTP = record { @@ -20,12 +21,12 @@ type COTP = record { pdu: uint8; switch: case pdu of { 0xe0 -> cRequest: ClientRequest; - 0xf0 -> hdr: Header; + 0xf0 -> hdr: COTPHeader; default -> data: bytestring &restofdata &transient; }; } &byteorder=littleendian; -type Header = record { +type COTPHeader = record { tpdu_number: uint8; application_defined_type: uint8; # this begins a BER encoded multiple octet variant, but can be safely skipped application_type: uint8; # this is value for the BER encoded octet variant above @@ -36,6 +37,11 @@ type Header = record { }; } &byteorder=littleendian; +type DataHdr = record { + type: uint16; + length: uint16; +} &byteorder=littleendian; + ###################################################################### # Client X.224 ###################################################################### @@ -130,7 +136,7 @@ type ServerHeader = record { network_header: DataHdr; net_data: padding[network_header.length - 4]; # skip this data security_header: DataHdr; - security_data: ServerSecurityData; # there is some issue / bug where the length reported by the security header overruns the end of the packet + security_data: ServerSecurityData; }; type GCC_Server_ConnectionData = record { @@ -152,11 +158,6 @@ type GCC_Server_CreateResponse = record { user_data_value_length: uint16; }; -type DataHdr = record { - type: uint16; - length: uint16; -} &byteorder=littleendian; - type ServerCoreData = record { version_major: uint16; version_minor: uint16; @@ -174,83 +175,40 @@ type ServerSecurityData = record { server_random_length: uint32 &byteorder=littleendian; server_cert_length: uint32 &byteorder=littleendian; server_random: bytestring &length=server_random_length; - server_certificate: bytestring &length=server_cert_length-8; # arbitrarily cutting off 8 chars so the certificate doesn't overrun the end of the packet + server_certificate: ServerCertificate; }; -###################################################################### -# NTLM Authentication -###################################################################### - -type NTLMAuthentication = record { - type: uint16; - switch: case type of { # there may be further type bytes that need to be added to this switch - 0x0100 -> client_request: NTLMClientRequest; - 0x0300 -> client_request2: NTLMClientRequest; - 0x0103 -> server_response: NTLMServerResponse; - 0x0104 -> server_response2: NTLMServerResponse; - default -> data: bytestring &restofdata &transient; +type ServerCertificate = record { + cert_type: uint8; + switch: case cert_type of { + 0x01 -> proprietary: ServerProprietary; + 0x02 -> ssl: SSL; }; +} &byteorder=littleendian; + +type ServerProprietary = record { + cert_type: uint8[3]; # remainder of cert_type value + signature_algorithm: uint32; + key_algorithm: uint32; + public_key_blob_type: uint16; + public_key_blob_length: uint16; + public_key_blob: PublicKeyBlob &length=public_key_blob_length; + signature_blob_type: uint16; + signature_blob_length: uint16; + signature_blob: bytestring &length=signature_blob_length; }; -###################################################################### -# NTLM Client -###################################################################### - -type NTLMClientRequest = record { - payload_length: uint8; # total payload length - pad1: padding[3]; # arbitrary 3 bytes - remaining_length1: uint8; # remaining length of the payload - pad2: padding[36]; # arbitrary 36 bytes - unknown_length: uint8; # an unknown length value - unknown_value1: padding[unknown_length]; # arbitrary padding for the length value above - pad3: padding[3]; # arbitrary 3 bytes - remainder_length2: uint8; # remaining length of the payload - unknown: uint8; # this unknown field affects the length between here and the beginning of the requested server name - switch: case unknown of { - 0x00 -> case1: uint8[7]; # jump 7 bytes - 0xff -> case2: uint8[12]; # jump 12 bytes - default -> case3: Debug; # debug if an unknown value is seen - }; - server_length: uint8; - server_name: bytestring &length=server_length; - data: bytestring &restofdata &transient; +type PublicKeyBlob = record { + magic: bytestring &length=4; + key_length: uint32; + bit_length: uint32; + public_exponent: uint32; + modulus: bytestring &length=key_length; }; -###################################################################### -# NTLM Server -###################################################################### - -type NTLMServerResponse = record { - unknown_value1: uint8; # 1 variable byte - unknown_value2: uint8[3]; # 3 bytes that may be static - unknown_value3: uint8; # 1 variable byte - unknown_value4: uint8[2]; # 2 bytes that may be static - unknown_length1: uint8; # an unknown length value - pad1: padding[unknown_length1]; # arbitrary padding for the length value above - unknown_value5: uint8[3]; # 3 bytes that may be static - unknown_value6: uint8; # 1 variable byte - unknown_value7: uint8[3]; # 3 bytes that may be static - unknown_value8: uint8; # 1 variable byte - unknown_value9: uint8[7]; # 7 bytes that may be static - unknown_value10: uint8[16]; # 16 bytes that may be static - unknown_value11: uint8[16]; # 16 bytes that may be static - unknown_value12: uint8; # 1 variable byte - unknown_value13: uint8; # 1 byte that may be static - unknown_value14: uint8; # 1 variable byte - unknown_value15: uint8; # 1 byte that may be static - unknown_value16: uint8; # 1 variable byte - unknown_value17: uint8[6]; # 6 bytes that may be static - server_length: uint8; # length of server name - server_name: bytestring &length=server_length; # server name - data: bytestring &restofdata &transient; -} &byteorder=bigendian; - -###################################################################### -# Debugging -###################################################################### - -type Debug = record { - remainder: bytestring &restofdata; +type SSL = record { + pad1: padding[11]; + x509_cert: bytestring &restofdata &transient; # send to x509 analyzer }; ###################################################################### @@ -311,3 +269,4 @@ function binary_to_int64(bs: bytestring): int64 return rval; %} + From 0648dafa5456952caa10057757acad264518ed4f Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 10:08:31 -0800 Subject: [PATCH 064/256] Removed scheduling of rdp_tracker event in server response events --- scripts/base/protocols/rdp/main.bro | 49 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 0369cad3d4..6f6af9d4cf 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -14,23 +14,23 @@ export { id: conn_id &log; ## Cookie value used by the client machine. ## This is typically a username. - cookie: string &log &optional; + cookie: string &log &optional; ## Keyboard layout (language) of the client machine. - keyboard_layout: string &log &optional; + keyboard_layout: string &log &optional; ## RDP client version used by the client machine. - client_build: string &log &optional; + client_build: string &log &optional; ## Hostname of the client machine. - client_hostname: string &log &optional; + client_hostname: string &log &optional; ## Product ID of the client machine. - client_product_id: string &log &optional; - ## GCC result for the connection. This value is extracted from the payload for native encryption. - result: string &log &optional; + client_product_id: string &log &optional; + ## GCC result for the connection. + result: string &log &optional; ## Encryption level of the connection. - encryption_level: string &log &optional; + encryption_level: string &log &optional; ## Encryption method of the connection. - encryption_method: string &log &optional; + encryption_method: string &log &optional; ## Track status of logging RDP connections. - done: bool &default=F; + done: bool &default=F; }; ## Event that can be handled to access the rdp record as it is sent on @@ -38,6 +38,10 @@ export { global log_rdp: event(rec: Info); } +redef record connection += { + rdp: Info &optional; + }; + const ports = { 3389/tcp }; redef likely_server_ports += { ports }; @@ -47,9 +51,15 @@ event bro_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_RDP, ports); } -redef record connection += { - rdp: Info &optional; - }; +function set_session(c: connection) + { + if ( ! c?$rdp ) + { + c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid]; + # Need to do this manually because the DPD framework does not seem to register the protocol (even though DPD is working) + add c$service["rdp"]; + } + } function rdp_done(c: connection, done: bool) { @@ -94,15 +104,6 @@ event rdp_tracker(c: connection) schedule +5secs { rdp_tracker(c) }; } -function set_session(c: connection) - { - if ( ! c?$rdp ) - { - c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid]; - add c$service["rdp"]; - } - } - event connection_state_remove(c: connection) &priority=-5 { # Log the RDP connection if the connection is removed but the session has not been marked as done @@ -137,8 +138,6 @@ event rdp_result(c: connection, result: count) &priority=5 { set_session(c); c$rdp$result = results[result]; - - schedule +5secs { rdp_tracker(c) }; } event rdp_server_security(c: connection, encryption_method: count, encryption_level: count) &priority=5 @@ -146,6 +145,4 @@ event rdp_server_security(c: connection, encryption_method: count, encryption_le set_session(c); c$rdp$encryption_method = encryption_methods[encryption_method]; c$rdp$encryption_level = encryption_levels[encryption_level]; - - schedule +5secs { rdp_tracker(c) }; } From af1f4be5294a6b734723d0b118e92c69b4177973 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 10:16:16 -0800 Subject: [PATCH 065/256] Added comments and TODOs --- scripts/base/protocols/rdp/main.bro | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 6f6af9d4cf..a1026208de 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -34,7 +34,7 @@ export { }; ## Event that can be handled to access the rdp record as it is sent on - ## to the loggin framework. + ## to the logging framework. global log_rdp: event(rec: Info); } @@ -56,7 +56,8 @@ function set_session(c: connection) if ( ! c?$rdp ) { c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid]; - # Need to do this manually because the DPD framework does not seem to register the protocol (even though DPD is working) + ## Need to do this manually because the DPD framework does not seem to register the protocol (even though DPD is working) + ## TODO: Find out why DPD framework isn't working add c$service["rdp"]; } } @@ -113,12 +114,14 @@ event connection_state_remove(c: connection) &priority=-5 event rdp_client_request(c: connection, cookie: string) &priority=5 { + ## Possibly better to avoid this clean up and use regex in binpac to extract the cookie value if ( "Cookie" in clean(cookie) ) { set_session(c); local cookie_val = sub(cookie,/Cookie.*\=/,""); c$rdp$cookie = sub(cookie_val,/\x0d\x0a.*$/,""); + ## Schedule the rdp_tracker event so remaining data can be collected schedule +5secs { rdp_tracker(c) }; } } @@ -131,6 +134,8 @@ event rdp_client_data(c: connection, keyboard_layout: count, build: count, hostn c$rdp$client_hostname = gsub(cat(hostname),/\\0/,""); c$rdp$client_product_id = gsub(cat(product_id),/\\0/,""); + ## Schedule the rdp_tracker event so remaining data can be collected + ## This is scheduled twice because the cookie in rdp_client_request may not exist schedule +5secs { rdp_tracker(c) }; } From a3ab9f5b09517d469383419f150896aa0fb29834 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 10:18:52 -0800 Subject: [PATCH 066/256] Added comments and TODOs --- scripts/base/protocols/rdp/main.bro | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index a1026208de..718fb3fe87 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -62,6 +62,8 @@ function set_session(c: connection) } } +## Currently rdp_done and rdp_tracker mimic the SSH analyzer for disabling analysis, but there might be a better method +## Once the DPD framework bug is fixed, we could possibly use the same method as SSL analyzer function rdp_done(c: connection, done: bool) { if ( done ) @@ -91,8 +93,8 @@ event rdp_tracker(c: connection) if ( connection_exists(id) ) { - # If the RDP connection has been alive for more than 5secs, log it - # This duration should be sufficient to collect the data that needs to be logged + ## If the RDP connection has been alive for more than 5secs, log it + ## This duration should be sufficient to collect the data that needs to be logged local diff = network_time() - c$rdp$ts; if ( diff > 5secs ) { @@ -101,13 +103,13 @@ event rdp_tracker(c: connection) } } - # Schedule the event to run again if necessary + ## Schedule the event to run again if necessary schedule +5secs { rdp_tracker(c) }; } event connection_state_remove(c: connection) &priority=-5 { - # Log the RDP connection if the connection is removed but the session has not been marked as done + ## Log the RDP connection if the connection is removed but the session has not been marked as done if ( c?$rdp && ! c$rdp$done ) rdp_done(c,T); } From 90bfbf900295c425ea548e1ec0fe237b301d9505 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 22:43:31 -0800 Subject: [PATCH 067/256] Added comments, changed logging events to reduce analyzer errors --- scripts/base/protocols/rdp/main.bro | 165 ++++++++++++++++------------ 1 file changed, 94 insertions(+), 71 deletions(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 718fb3fe87..c4309e3686 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -29,10 +29,24 @@ export { encryption_level: string &log &optional; ## Encryption method of the connection. encryption_method: string &log &optional; + + ## The analyzer ID used for the analyzer instance attached + ## to each connection. It is not used for logging since it's a + ## meaningless arbitrary number. + analyzer_id: count &optional; ## Track status of logging RDP connections. done: bool &default=F; }; + ## If true, detach the RDP analyzer from the connection to prevent + ## continuing to process encrypted traffic. Helps with performance + ## (especially with large file transfers). + const disable_analyzer_after_detection = T &redef; + + ## The amount of time to monitor an RDP session from when it is first + ## identified. When this interval is reached, the session is logged. + const rdp_interval = 10secs &redef; + ## Event that can be handled to access the rdp record as it is sent on ## to the logging framework. global log_rdp: event(rec: Info); @@ -51,81 +65,71 @@ event bro_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_RDP, ports); } +# Verify that the RDP session contains +# RDP data before writing it to the log. +function verify_rdp(c: connection) + { + local info = c$rdp; + if ( info?$cookie || info?$keyboard_layout || info?$result ) + Log::write(RDP::LOG,info); + else + Reporter::error("RDP analyzer was initialized but no data was found"); + } + +event log_record(c: connection, remove_analyzer: bool) + { + # If the record was logged, then stop processing. + if ( c$rdp$done ) + return; + + # If the analyzer is no logger attached, then + # log the record and stop processing. + if ( ! remove_analyzer ) + { + c$rdp$done = T; + verify_rdp(c); + return; + } + + # If the value rdp_interval has passed since the + # RDP session was started, then log the record. + local diff = network_time() - c$rdp$ts; + if ( diff > rdp_interval ) + { + c$rdp$done = T; + verify_rdp(c); + + # Remove the analyzer if it is still attached. + if ( remove_analyzer && disable_analyzer_after_detection && c$rdp?$analyzer_id ) + { + disable_analyzer(c$id, c$rdp$analyzer_id); + delete c$rdp$analyzer_id; + } + + return; + } + # If the analyzer is attached and the duration + # to monitor the RDP session was not met, then + # reschedule the logging event. + else + schedule +rdp_interval { log_record(c,remove_analyzer) }; + } + function set_session(c: connection) { if ( ! c?$rdp ) - { + { c$rdp = [$ts=network_time(),$id=c$id,$uid=c$uid]; - ## Need to do this manually because the DPD framework does not seem to register the protocol (even though DPD is working) - ## TODO: Find out why DPD framework isn't working - add c$service["rdp"]; - } + # The RDP session is scheduled to be logged from + # the time it is first initiated. + schedule +rdp_interval { log_record(c,T) }; + } } -## Currently rdp_done and rdp_tracker mimic the SSH analyzer for disabling analysis, but there might be a better method -## Once the DPD framework bug is fixed, we could possibly use the same method as SSL analyzer -function rdp_done(c: connection, done: bool) - { - if ( done ) - { - c$rdp$done = T; - - Log::write(RDP::LOG, c$rdp); - skip_further_processing(c$id); - set_record_packets(c$id, F); - } - } - -event rdp_tracker(c: connection) - { - if ( c$rdp$done ) - return; - - local id = c$id; - - if ( ! connection_exists(id) ) - { - rdp_done(c,T); - return; - } - - lookup_connection(id); - - if ( connection_exists(id) ) - { - ## If the RDP connection has been alive for more than 5secs, log it - ## This duration should be sufficient to collect the data that needs to be logged - local diff = network_time() - c$rdp$ts; - if ( diff > 5secs ) - { - rdp_done(c,T); - return; - } - } - - ## Schedule the event to run again if necessary - schedule +5secs { rdp_tracker(c) }; - } - -event connection_state_remove(c: connection) &priority=-5 - { - ## Log the RDP connection if the connection is removed but the session has not been marked as done - if ( c?$rdp && ! c$rdp$done ) - rdp_done(c,T); - } - event rdp_client_request(c: connection, cookie: string) &priority=5 { - ## Possibly better to avoid this clean up and use regex in binpac to extract the cookie value - if ( "Cookie" in clean(cookie) ) - { - set_session(c); - local cookie_val = sub(cookie,/Cookie.*\=/,""); - c$rdp$cookie = sub(cookie_val,/\x0d\x0a.*$/,""); - - ## Schedule the rdp_tracker event so remaining data can be collected - schedule +5secs { rdp_tracker(c) }; - } + set_session(c); + c$rdp$cookie = cookie; } event rdp_client_data(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5 @@ -135,10 +139,6 @@ event rdp_client_data(c: connection, keyboard_layout: count, build: count, hostn c$rdp$client_build = builds[build]; c$rdp$client_hostname = gsub(cat(hostname),/\\0/,""); c$rdp$client_product_id = gsub(cat(product_id),/\\0/,""); - - ## Schedule the rdp_tracker event so remaining data can be collected - ## This is scheduled twice because the cookie in rdp_client_request may not exist - schedule +5secs { rdp_tracker(c) }; } event rdp_result(c: connection, result: count) &priority=5 @@ -153,3 +153,26 @@ event rdp_server_security(c: connection, encryption_method: count, encryption_le c$rdp$encryption_method = encryption_methods[encryption_method]; c$rdp$encryption_level = encryption_levels[encryption_level]; } + +event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5 + { + if ( atype == Analyzer::ANALYZER_RDP ) + { + set_session(c); + c$rdp$analyzer_id = aid; + } + } + +event protocol_violation(c: connection, atype: Analyzer::Tag, aid: count, reason: string) &priority=5 + { + # If a protocol violation occurs, then log the record immediately. + if ( c?$rdp ) + schedule +0secs { log_record(c,F) }; + } + +event connection_state_remove(c: connection) &priority=-5 + { + # If the connection is removed, then log the record immediately. + if ( c?$rdp ) + schedule +0secs { log_record(c,F) }; + } From 0ef8a106df3f23d5946b7e934400dfcea472b6f4 Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 22:44:00 -0800 Subject: [PATCH 068/256] Moved DPD to each individual event process --- src/analyzer/protocol/rdp/rdp-analyzer.pac | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac index 04d64409bd..28fb4afa6a 100644 --- a/src/analyzer/protocol/rdp/rdp-analyzer.pac +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -1,16 +1,18 @@ refine flow RDP_Flow += { - function proc_rdp_client_request(client_request: ClientRequest): bool + function proc_rdp_client_request(client_request: Client_Request): bool %{ - BifEvent::generate_rdp_client_request(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${client_request.cookie})); + connection()->bro_analyzer()->ProtocolConfirmation(); - return true; + BifEvent::generate_rdp_client_request(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${client_request.cookie_value})); + + return true; %} - - function proc_rdp_result(gcc_response: GCC_Server_CreateResponse): bool + function proc_rdp_result(gcc_response: GCC_Server_Create_Response): bool %{ + connection()->bro_analyzer()->ProtocolConfirmation(); BifEvent::generate_rdp_result(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${gcc_response.result}); @@ -19,8 +21,9 @@ refine flow RDP_Flow += { %} - function proc_rdp_client_data(ccore: ClientCore): bool + function proc_rdp_client_data(ccore: Client_Core_Data): bool %{ + connection()->bro_analyzer()->ProtocolConfirmation(); BifEvent::generate_rdp_client_data(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${ccore.keyboard_layout}, @@ -31,8 +34,9 @@ refine flow RDP_Flow += { return true; %} - function proc_rdp_server_security(ssd: ServerSecurityData): bool + function proc_rdp_server_security(ssd: Server_Security_Data): bool %{ + connection()->bro_analyzer()->ProtocolConfirmation(); BifEvent::generate_rdp_server_security(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${ssd.encryption_method}, @@ -42,18 +46,18 @@ refine flow RDP_Flow += { %} }; -refine typeattr ClientRequest += &let { +refine typeattr Client_Request += &let { proc: bool = $context.flow.proc_rdp_client_request(this); }; -refine typeattr ClientCore += &let { +refine typeattr Client_Core_Data += &let { proc: bool = $context.flow.proc_rdp_client_data(this); }; -refine typeattr GCC_Server_CreateResponse += &let { +refine typeattr GCC_Server_Create_Response += &let { proc: bool = $context.flow.proc_rdp_result(this); }; -refine typeattr ServerSecurityData += &let { +refine typeattr Server_Security_Data += &let { proc: bool = $context.flow.proc_rdp_server_security(this); }; From b1614b7fe9900f759bcdff193f6833633203073c Mon Sep 17 00:00:00 2001 From: Josh Liburdi Date: Sun, 15 Feb 2015 22:45:16 -0800 Subject: [PATCH 069/256] Modified how cookie value is handled --- src/analyzer/protocol/rdp/rdp-protocol.pac | 81 +++++++++++----------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac index d9546dbdc9..a89e622539 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -2,7 +2,7 @@ type RDP_PDU(is_orig: bool) = record { type: uint8; switch: case type of { 0x16 -> ssl_encryption: bytestring &restofdata &transient; # send to SSL analyzer in the future - default -> native_encryption: NativeEncryption; # TPKT version + default -> native_encryption: Native_Encryption; # TPKT version }; } &byteorder=bigendian; @@ -10,7 +10,7 @@ type RDP_PDU(is_orig: bool) = record { # Native Encryption ###################################################################### -type NativeEncryption = record { +type Native_Encryption = record { tpkt_reserved: uint8; tpkt_length: uint16; cotp: COTP; @@ -20,24 +20,24 @@ type COTP = record { length: uint8; pdu: uint8; switch: case pdu of { - 0xe0 -> cRequest: ClientRequest; - 0xf0 -> hdr: COTPHeader; + 0xe0 -> cRequest: Client_Request; + 0xf0 -> hdr: COTP_Header; default -> data: bytestring &restofdata &transient; }; } &byteorder=littleendian; -type COTPHeader = record { +type COTP_Header = record { tpdu_number: uint8; application_defined_type: uint8; # this begins a BER encoded multiple octet variant, but can be safely skipped application_type: uint8; # this is value for the BER encoded octet variant above - switch: case application_type of { - 0x65 -> cHeader: ClientHeader; # 0x65 is a client - 0x66 -> sHeader: ServerHeader; # 0x66 is a server - default -> data: bytestring &restofdata &transient; + switch: case application_type of { # this seems to cause a binpac exception error + 0x65 -> cHeader: Client_Header; # 0x65 is a client + 0x66 -> sHeader: Server_Header; # 0x66 is a server + default -> data: bytestring &restofdata; }; } &byteorder=littleendian; -type DataHdr = record { +type Data_Header = record { type: uint16; length: uint16; } &byteorder=littleendian; @@ -46,19 +46,20 @@ type DataHdr = record { # Client X.224 ###################################################################### -type ClientRequest = record { +type Client_Request = record { destination_reference: uint16; source_reference: uint16; flow_control: uint8; - cookie: bytestring &restofdata; # cookie value is a variable length field, so everything is captured + cookie_mstshash: RE/Cookie: mstshash\=/; # &check would be better here, but it is not implemented + cookie_value: RE/[^\x0d]*/; # the value is anything up to \x0d }; ###################################################################### # Client MCS ###################################################################### -type ClientHeader = record { - type_length: padding[3]; # BER encoded long variant, can be safely skipped for now +type Client_Header = record { + type_length: uint8[3]; # BER encoded long variant, can be safely skipped for now calling_domain_selector: ASN1OctetString; called_domain_selector: ASN1OctetString; upward_flag: ASN1Boolean; @@ -69,20 +70,20 @@ type ClientHeader = record { maximum_parameters: ASN1SequenceMeta; max_parameters_pad: padding[maximum_parameters.encoding.length]; user_data_length: uint32; # BER encoded OctetString and long variant, can be safely skipped for now - gcc_connection_data: GCC_Client_ConnectionData; - gcc_client_create_request: GCC_Client_CreateRequest; - core_header: DataHdr; - core_data: ClientCore; + gcc_connection_data: GCC_Client_Connection_Data; + gcc_client_create_request: GCC_Client_Create_Request; + core_header: Data_Header; + core_data: Client_Core_Data; remainder: bytestring &restofdata &transient; # everything after core_data can be discarded }; -type GCC_Client_ConnectionData = record { +type GCC_Client_Connection_Data = record { key_object_length: uint16; key_object: uint8[key_object_length]; connect_data_connect_pdu: uint16; } &byteorder=bigendian; -type GCC_Client_CreateRequest = record { +type GCC_Client_Create_Request = record { extension_bit: uint8; privileges: uint8; numeric_length: uint8; @@ -95,7 +96,7 @@ type GCC_Client_CreateRequest = record { user_data_value_length: uint16; }; -type ClientCore = record { +type Client_Core_Data = record { version_major: uint16; version_minor: uint16; desktop_width: uint16; @@ -122,30 +123,30 @@ type ClientCore = record { # Server MCS ###################################################################### -type ServerHeader = record { - type_length: padding[3]; # BER encoded long variant, can be safely skipped for now +type Server_Header = record { + type_length: uint8[3]; # BER encoded long variant, can be safely skipped for now connect_response_result: ASN1Enumerated; connect_response_called_id: ASN1Integer; connect_response_domain_parameters: ASN1SequenceMeta; domain_parameters_pad: padding[connect_response_domain_parameters.encoding.length]; # skip this data user_data_length: uint32; # BER encoded OctetString and long variant, can be safely skipped for now - gcc_connection_data: GCC_Server_ConnectionData; - gcc_create_response: GCC_Server_CreateResponse; - core_header: DataHdr; + gcc_connection_data: GCC_Server_Connection_Data; + gcc_create_response: GCC_Server_Create_Response; + core_header: Data_Header; core_data: padding[core_header.length - 4]; # skip this data - network_header: DataHdr; + network_header: Data_Header; net_data: padding[network_header.length - 4]; # skip this data - security_header: DataHdr; - security_data: ServerSecurityData; + security_header: Data_Header; + security_data: Server_Security_Data; }; -type GCC_Server_ConnectionData = record { +type GCC_Server_Connection_Data = record { key_object_length: uint16; key_object: uint8[key_object_length]; connect_data_connect_pdu: uint8; } &byteorder=bigendian; -type GCC_Server_CreateResponse = record { +type GCC_Server_Create_Response = record { extension_bit: uint8; node_id: uint8[2]; tag_length: uint8; @@ -158,47 +159,47 @@ type GCC_Server_CreateResponse = record { user_data_value_length: uint16; }; -type ServerCoreData = record { +type Server_Core_Data = record { version_major: uint16; version_minor: uint16; client_requested_protocols: uint32; }; -type ServerNetworkData = record { +type Server_Network_Data = record { mcs_channel_id: uint16; channel_count: uint16; }; -type ServerSecurityData = record { +type Server_Security_Data = record { encryption_method: uint32; encryption_level: uint32; server_random_length: uint32 &byteorder=littleendian; server_cert_length: uint32 &byteorder=littleendian; server_random: bytestring &length=server_random_length; - server_certificate: ServerCertificate; + server_certificate: Server_Certificate; }; -type ServerCertificate = record { +type Server_Certificate = record { cert_type: uint8; switch: case cert_type of { - 0x01 -> proprietary: ServerProprietary; + 0x01 -> proprietary: Server_Proprietary; 0x02 -> ssl: SSL; }; } &byteorder=littleendian; -type ServerProprietary = record { +type Server_Proprietary = record { cert_type: uint8[3]; # remainder of cert_type value signature_algorithm: uint32; key_algorithm: uint32; public_key_blob_type: uint16; public_key_blob_length: uint16; - public_key_blob: PublicKeyBlob &length=public_key_blob_length; + public_key_blob: Public_Key_Blob &length=public_key_blob_length; signature_blob_type: uint16; signature_blob_length: uint16; signature_blob: bytestring &length=signature_blob_length; }; -type PublicKeyBlob = record { +type Public_Key_Blob = record { magic: bytestring &length=4; key_length: uint32; bit_length: uint32; From 8a5bb0f6a7e0410098dcb2fbd7948ef98fefb8ed Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Sun, 15 Feb 2015 23:04:31 -0800 Subject: [PATCH 070/256] Added check for connection existence Added a check for connection existence before trying to remove the RDP analyzer from a connection. --- scripts/base/protocols/rdp/main.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index c4309e3686..1f120d1b98 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -100,7 +100,7 @@ event log_record(c: connection, remove_analyzer: bool) verify_rdp(c); # Remove the analyzer if it is still attached. - if ( remove_analyzer && disable_analyzer_after_detection && c$rdp?$analyzer_id ) + if ( remove_analyzer && disable_analyzer_after_detection && connection_exists(c$id) && c$rdp?$analyzer_id ) { disable_analyzer(c$id, c$rdp$analyzer_id); delete c$rdp$analyzer_id; From 10071ffddf7718e0bcb7cd2ae6bd560914c1ffd7 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Sun, 15 Feb 2015 23:05:11 -0800 Subject: [PATCH 071/256] Fixed typo --- scripts/base/protocols/rdp/main.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 1f120d1b98..2e3c3f8892 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -82,7 +82,7 @@ event log_record(c: connection, remove_analyzer: bool) if ( c$rdp$done ) return; - # If the analyzer is no logger attached, then + # If the analyzer is no longer attached, then # log the record and stop processing. if ( ! remove_analyzer ) { From dade1936be9e9a0dcc656587b57668326b663073 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Sun, 15 Feb 2015 23:06:36 -0800 Subject: [PATCH 072/256] Update dpd.sig --- scripts/base/protocols/rdp/dpd.sig | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/base/protocols/rdp/dpd.sig b/scripts/base/protocols/rdp/dpd.sig index 35aa8f9257..4ecb7999af 100644 --- a/scripts/base/protocols/rdp/dpd.sig +++ b/scripts/base/protocols/rdp/dpd.sig @@ -1,5 +1,3 @@ -# Generated by binpac_quickstart - signature dpd_rdp_client_request { ip-proto == tcp payload /.*Cookie: mstshash\=.*/ From 55a0b344af9a63e6b4fe2215587a9d24a4cb9910 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Sun, 15 Feb 2015 23:09:50 -0800 Subject: [PATCH 073/256] Delete nla_win7_win2k8r2.pcap --- .../btest/Traces/rdp/nla_win7_win2k8r2.pcap | Bin 134982 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap diff --git a/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap b/testing/btest/Traces/rdp/nla_win7_win2k8r2.pcap deleted file mode 100644 index 3a6a2999eba4fa36f1655a95464494db44c8bede..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134982 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 e_S;kcZG8CMef3`TrFsiUL3u2o@ Date: Sun, 15 Feb 2015 23:10:05 -0800 Subject: [PATCH 074/256] Delete RDP-004.pcap --- testing/btest/Traces/rdp/RDP-004.pcap | Bin 142910 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 testing/btest/Traces/rdp/RDP-004.pcap diff --git a/testing/btest/Traces/rdp/RDP-004.pcap b/testing/btest/Traces/rdp/RDP-004.pcap deleted file mode 100644 index a26dd5637f82d2d4ad3d74b79c84814644c6ea53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142910 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