From 08c7dd3d717bc159f7ad8dcbd754af1b9e7e6a09 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sat, 28 Sep 2013 16:06:40 -0700 Subject: [PATCH 1/2] Prettyfing Describe() for record types. If a record type has a name and ODesc is set to short, we now print the name instead of the full field list. --- src/Type.cc | 14 ++++++++++---- src/Var.cc | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index a6d8b90c6c..30deb3cd2a 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1038,10 +1038,16 @@ void RecordType::Describe(ODesc* d) const { if ( d->IsReadable() ) { - d->AddSP("record {"); - DescribeFields(d); - d->SP(); - d->Add("}"); + if ( d->IsShort() && GetTypeID() ) + d->Add(GetTypeID()); + + else + { + d->AddSP("record {"); + DescribeFields(d); + d->SP(); + d->Add("}"); + } } else diff --git a/src/Var.cc b/src/Var.cc index d384fedc74..08129bdc3e 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -314,9 +314,9 @@ void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */) delete [] data; } - tnew->SetTypeID(copy_string(id->Name())); } + tnew->SetTypeID(copy_string(id->Name())); id->SetType(tnew); id->MakeType(); From de9f03b0bffae6cc89d5a4430bba8db7550e881f Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 22 Nov 2013 14:17:15 -0800 Subject: [PATCH 2/2] New script misc/dump-events.bro, along with core support, that dumps events Bro is raising in an easily readable form. This is for debugging purposes, obviously. Example, including only SMTP events: > bro -r smtp.trace misc/dump-events.bro DumpEvents::include=/smtp/ [...] 1254722768.219663 smtp_reply [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, [...] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > [4] msg: string = xc90.websitewelcome.com ESMTP Exim 4.69 #1 Mon, 05 Oct 2009 01:05:54 -0500 [5] cont_resp: bool = T 1254722768.219663 smtp_reply [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, [...] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > [4] msg: string = We do not authorize the use of this system to transport unsolicited, [5] cont_resp: bool = T [...] --- scripts/base/init-bare.bro | 18 ++++++++++ scripts/policy/misc/dump-events.bro | 35 +++++++++++++++++++ src/EventHandler.cc | 54 +++++++++++++++++++++++++++++ src/EventHandler.h | 2 ++ src/NetVar.cc | 4 +++ src/NetVar.h | 2 ++ src/event.bif | 11 ++++++ 7 files changed, 126 insertions(+) create mode 100644 scripts/policy/misc/dump-events.bro diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index de26e6a41d..1cfc570a6e 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -529,6 +529,24 @@ type record_field: record { ## directly and then remove this alias. type record_field_table: table[string] of record_field; +## Meta-information about a parameter to a function/event. +## +## .. bro:see:: call_argument_event new_event +type call_argument: record { + name: string; ##< The name of the parameter. + type_name: string; ##< The name of the parameters's type. + default_val: any &optional; ##< The value of the :bro:attr:`&default` attribute if defined. + + ## The value of the parameter as passed into a given call instance. Might be unset + ## in the case a :bro:attr:`&default` attribute is defined. + value: any &optional; +}; + +## Vector type used to capture parameters of a function/event call. +## +## .. bro:see:: call_argument new_event +type call_argument_vector: vector of call_argument; + # todo:: Do we still need these here? Can they move into the packet filter # framework? # diff --git a/scripts/policy/misc/dump-events.bro b/scripts/policy/misc/dump-events.bro new file mode 100644 index 0000000000..a88f980b2e --- /dev/null +++ b/scripts/policy/misc/dump-events.bro @@ -0,0 +1,35 @@ + +module DumpEvents; + +export { + # If true, include event argument in output. + const include_args = T &redef; + + # Only include events matching the given pattern into output. + const include = /.*/ &redef; +} + +event new_event(name: string, args: call_argument_vector) + { + if ( include !in name ) + return; + + if ( ! include_args || |args| == 0 ) + return; + + print fmt("%.6f %s", network_time(), name); + + for ( i in args ) + { + local a = args[i]; + + local proto = fmt("%s: %s", a$name, a$type_name); + + if ( a?$value ) + print fmt(" [%d] %-15s = %s", i, proto, a$value); + else + print fmt(" | %-15s = %s [default]", proto, a$value); + } + + print ""; + } diff --git a/src/EventHandler.cc b/src/EventHandler.cc index 4a74d68a08..43940e0d27 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -3,6 +3,7 @@ #include "Func.h" #include "Scope.h" #include "RemoteSerializer.h" +#include "NetVar.h" EventHandler::EventHandler(const char* arg_name) { @@ -56,6 +57,9 @@ void EventHandler::Call(val_list* vl, bool no_remote) DEBUG_MSG("Event: %s\n", Name()); #endif + if ( new_event ) + NewEvent(vl); + if ( ! no_remote ) { loop_over_list(receivers, i) @@ -75,6 +79,56 @@ void EventHandler::Call(val_list* vl, bool no_remote) } } +void EventHandler::NewEvent(val_list* vl) + { + if ( ! new_event ) + return; + + if ( this == new_event.Ptr() ) + return; + + RecordType* args = FType()->Args(); + VectorVal* vargs = new VectorVal(call_argument_vector); + + for ( int i = 0; i < args->NumFields(); i++ ) + { + const char* fname = args->FieldName(i); + BroType* ftype = args->FieldType(i); + Val* fdefault = args->FieldDefault(i); + + RecordVal* rec = new RecordVal(call_argument); + + rec->Assign(0, new StringVal(fname)); + + ODesc d; + d.SetShort(); + ftype->Describe(&d); + rec->Assign(1, new StringVal(d.Description())); + + if ( fdefault ) + { + Ref(fdefault); + rec->Assign(2, fdefault); + } + + if ( i < vl->length() && (*vl)[i] ) + { + Val* val = (*vl)[i]; + Ref(val); + rec->Assign(3, val); + } + + vargs->Assign(i, rec); + } + + val_list* mvl = new val_list(2); + mvl->append(new StringVal(name)); + mvl->append(vargs); + + Event* ev = new Event(new_event, mvl); + mgr.Dispatch(ev); + } + void EventHandler::AddRemoteHandler(SourceID peer) { receivers.append(peer); diff --git a/src/EventHandler.h b/src/EventHandler.h index 786d9f94ba..e84f635175 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -49,6 +49,8 @@ public: static EventHandler* Unserialize(UnserialInfo* info); private: + void NewEvent(val_list* vl); // Raise new_event() meta event. + const char* name; Func* local; FuncType* type; diff --git a/src/NetVar.cc b/src/NetVar.cc index 7a11c3f2d1..79652112f3 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -235,6 +235,8 @@ RecordType* script_id; TableType* id_table; RecordType* record_field; TableType* record_field_table; +RecordType* call_argument; +VectorType* call_argument_vector; StringVal* cmd_line_bpf_filter; @@ -528,4 +530,6 @@ void init_net_var() id_table = internal_type("id_table")->AsTableType(); record_field = internal_type("record_field")->AsRecordType(); record_field_table = internal_type("record_field_table")->AsTableType(); + call_argument_vector = internal_type("call_argument_vector")->AsVectorType(); + call_argument = internal_type("call_argument")->AsRecordType(); } diff --git a/src/NetVar.h b/src/NetVar.h index c30895d5d4..12949c0e55 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -239,6 +239,8 @@ extern RecordType* script_id; extern TableType* id_table; extern RecordType* record_field; extern TableType* record_field_table; +extern RecordType* call_argument; +extern VectorType* call_argument_vector; extern StringVal* cmd_line_bpf_filter; diff --git a/src/event.bif b/src/event.bif index ddadb47f8a..fc2b9c4d5d 100644 --- a/src/event.bif +++ b/src/event.bif @@ -1007,6 +1007,17 @@ event dns_mapping_lost_name%(dm: dns_mapping%); ## dns_mapping_valid event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr_set%); +## A meta event generated for each event Bro raises. This will report *all* events, +## even those for which no handler is defined. +## +## Note that handling this meta event is expensive and should be limited to +## debugging purposes. +## +## name: The name of the event. +## +## params: The event's parameters. +event new_event%(name: string, params: call_argument_vector%); + ## Deprecated. Will be removed. event root_backdoor_signature_found%(c: connection%);