Merge remote-tracking branch 'origin/topic/vern/vec-append'

* origin/topic/vern/vec-append:
  d'oh, still have a (deprecated) string_array rather than string_vector
  forgot to update test suite results for v += e
  reap the fruits of v += e
  test case for v += e
  documentation of v += e
  v += e implemented

Fixed a mistake in find_ip_addresses()
This commit is contained in:
Jon Siwek 2018-08-03 11:33:57 -05:00
commit 599af26496
45 changed files with 202 additions and 135 deletions

11
CHANGES
View file

@ -1,4 +1,15 @@
2.5-811 | 2018-08-03 11:33:57 -0500
* Update scripts to use vector "+=" append operation (Vern Paxson, Corelight)
* Add vector "+=" append operation (Vern Paxson, Corelight)
* Improve a travis output message in pull request builds (Daniel Thayer)
* Use default version of OpenSSL on all travis docker containers
(Daniel Thayer)
2.5-802 | 2018-08-02 10:40:36 -0500 2.5-802 | 2018-08-02 10:40:36 -0500
* Add set operations: union, intersection, difference, comparison * Add set operations: union, intersection, difference, comparison

3
NEWS
View file

@ -309,6 +309,9 @@ New Functionality
"s1 > s2", and "s1 >= s2" have the expected meanings in terms "s1 > s2", and "s1 >= s2" have the expected meanings in terms
of non-equality, proper superset, and superset-or-equal. of non-equality, proper superset, and superset-or-equal.
- An expression of the form "v += e" will append the value of the expression
"e" to the end of the vector "v" (of course assuming type-compatbility).
Changed Functionality Changed Functionality
--------------------- ---------------------

View file

@ -1 +1 @@
2.5-802 2.5-811

View file

@ -608,6 +608,20 @@ Here is a more detailed description of each type:
|v| |v|
A particularly common operation on a vector is to append an element
to its end. You can do so using:
.. code:: bro
v += e;
where if e's type is ``X``, v's type is ``vector of X``. Note that
this expression is equivalent to:
.. code:: bro
v[|v|] = e;
Vectors of integral types (``int`` or ``count``) support the pre-increment Vectors of integral types (``int`` or ``count``) support the pre-increment
(``++``) and pre-decrement operators (``--``), which will increment or (``++``) and pre-decrement operators (``--``), which will increment or
decrement each element in the vector. decrement each element in the vector.

View file

@ -3,10 +3,10 @@ event bro_init()
local v1: vector of count; local v1: vector of count;
local v2 = vector(1, 2, 3, 4); local v2 = vector(1, 2, 3, 4);
v1[|v1|] = 1; v1 += 1;
v1[|v1|] = 2; v1 += 2;
v1[|v1|] = 3; v1 += 3;
v1[|v1|] = 4; v1 += 4;
print fmt("contents of v1: %s", v1); print fmt("contents of v1: %s", v1);
print fmt("length of v1: %d", |v1|); print fmt("length of v1: %d", |v1|);

View file

@ -126,7 +126,7 @@ event pe_section_header(f: fa_file, h: PE::SectionHeader) &priority=5
if ( ! f$pe?$section_names ) if ( ! f$pe?$section_names )
f$pe$section_names = vector(); f$pe$section_names = vector();
f$pe$section_names[|f$pe$section_names|] = h$name; f$pe$section_names += h$name;
} }
event file_state_remove(f: fa_file) &priority=-5 event file_state_remove(f: fa_file) &priority=-5

View file

@ -66,7 +66,7 @@ event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certifi
event x509_extension(f: fa_file, ext: X509::Extension) &priority=5 event x509_extension(f: fa_file, ext: X509::Extension) &priority=5
{ {
if ( f$info?$x509 ) if ( f$info?$x509 )
f$info$x509$extensions[|f$info$x509$extensions|] = ext; f$info$x509$extensions += ext;
} }
event x509_ext_basic_constraints(f: fa_file, ext: X509::BasicConstraints) &priority=5 event x509_ext_basic_constraints(f: fa_file, ext: X509::BasicConstraints) &priority=5

View file

@ -251,7 +251,7 @@ function nodes_with_type(node_type: NodeType): vector of NamedNode
local names: vector of string = vector(); local names: vector of string = vector();
for ( name in Cluster::nodes ) for ( name in Cluster::nodes )
names[|names|] = name; names += name;
names = sort(names, strcmp); names = sort(names, strcmp);
@ -263,7 +263,7 @@ function nodes_with_type(node_type: NodeType): vector of NamedNode
if ( n$node_type != node_type ) if ( n$node_type != node_type )
next; next;
rval[|rval|] = NamedNode($name=name, $node=n); rval += NamedNode($name=name, $node=n);
} }
return rval; return rval;

View file

@ -157,7 +157,7 @@ global registered_pools: vector of Pool = vector();
function register_pool(spec: PoolSpec): Pool function register_pool(spec: PoolSpec): Pool
{ {
local rval = Pool($spec = spec); local rval = Pool($spec = spec);
registered_pools[|registered_pools|] = rval; registered_pools += rval;
return rval; return rval;
} }
@ -276,7 +276,7 @@ function init_pool_node(pool: Pool, name: string): bool
local pn = PoolNode($name=name, $alias=alias, $site_id=site_id, local pn = PoolNode($name=name, $alias=alias, $site_id=site_id,
$alive=Cluster::node == name); $alive=Cluster::node == name);
pool$nodes[name] = pn; pool$nodes[name] = pn;
pool$node_list[|pool$node_list|] = pn; pool$node_list += pn;
if ( pn$alive ) if ( pn$alive )
++pool$alive_count; ++pool$alive_count;
@ -366,7 +366,7 @@ event bro_init() &priority=-5
if ( |mgr| > 0 ) if ( |mgr| > 0 )
{ {
local eln = pool_eligibility[Cluster::LOGGER]$eligible_nodes; local eln = pool_eligibility[Cluster::LOGGER]$eligible_nodes;
eln[|eln|] = mgr[0]; eln += mgr[0];
} }
} }
@ -423,7 +423,7 @@ event bro_init() &priority=-5
if ( j < e ) if ( j < e )
next; next;
nen[|nen|] = pet$eligible_nodes[j]; nen += pet$eligible_nodes[j];
} }
pet$eligible_nodes = nen; pet$eligible_nodes = nen;

View file

@ -120,14 +120,14 @@ function format_value(value: any) : string
{ {
local it: set[bool] = value; local it: set[bool] = value;
for ( sv in it ) for ( sv in it )
part[|part|] = cat(sv); part += cat(sv);
return join_string_vec(part, ","); return join_string_vec(part, ",");
} }
else if ( /^vector/ in tn ) else if ( /^vector/ in tn )
{ {
local vit: vector of any = value; local vit: vector of any = value;
for ( i in vit ) for ( i in vit )
part[|part|] = cat(vit[i]); part += cat(vit[i]);
return join_string_vec(part, ","); return join_string_vec(part, ",");
} }
else if ( tn == "string" ) else if ( tn == "string" )

View file

@ -555,19 +555,19 @@ function quarantine_host(infected: addr, dns: addr, quarantine: addr, t: interva
local orules: vector of string = vector(); local orules: vector of string = vector();
local edrop: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected))]; local edrop: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected))];
local rdrop: Rule = [$ty=DROP, $target=FORWARD, $entity=edrop, $expire=t, $location=location]; local rdrop: Rule = [$ty=DROP, $target=FORWARD, $entity=edrop, $expire=t, $location=location];
orules[|orules|] = add_rule(rdrop); orules += add_rule(rdrop);
local todnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(dns), $dst_p=53/udp)]; local todnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(dns), $dst_p=53/udp)];
local todnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=todnse, $expire=t, $location=location, $mod=FlowMod($dst_h=quarantine), $priority=+5); local todnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=todnse, $expire=t, $location=location, $mod=FlowMod($dst_h=quarantine), $priority=+5);
orules[|orules|] = add_rule(todnsr); orules += add_rule(todnsr);
local fromdnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(dns), $src_p=53/udp, $dst_h=addr_to_subnet(infected))]; local fromdnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(dns), $src_p=53/udp, $dst_h=addr_to_subnet(infected))];
local fromdnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=fromdnse, $expire=t, $location=location, $mod=FlowMod($src_h=dns), $priority=+5); local fromdnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=fromdnse, $expire=t, $location=location, $mod=FlowMod($src_h=dns), $priority=+5);
orules[|orules|] = add_rule(fromdnsr); orules += add_rule(fromdnsr);
local wle: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(quarantine), $dst_p=80/tcp)]; local wle: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(quarantine), $dst_p=80/tcp)];
local wlr = Rule($ty=WHITELIST, $target=FORWARD, $entity=wle, $expire=t, $location=location, $priority=+5); local wlr = Rule($ty=WHITELIST, $target=FORWARD, $entity=wle, $expire=t, $location=location, $priority=+5);
orules[|orules|] = add_rule(wlr); orules += add_rule(wlr);
return orules; return orules;
} }
@ -637,7 +637,7 @@ event NetControl::init() &priority=-20
function activate_impl(p: PluginState, priority: int) function activate_impl(p: PluginState, priority: int)
{ {
p$_priority = priority; p$_priority = priority;
plugins[|plugins|] = p; plugins += p;
sort(plugins, function(p1: PluginState, p2: PluginState) : int { return p2$_priority - p1$_priority; }); sort(plugins, function(p1: PluginState, p2: PluginState) : int { return p2$_priority - p1$_priority; });
plugin_ids[plugin_counter] = p; plugin_ids[plugin_counter] = p;
@ -734,7 +734,7 @@ function find_rules_subnet(sn: subnet) : vector of Rule
for ( rule_id in rules_by_subnets[sn_entry] ) for ( rule_id in rules_by_subnets[sn_entry] )
{ {
if ( rule_id in rules ) if ( rule_id in rules )
ret[|ret|] = rules[rule_id]; ret += rules[rule_id];
else else
Reporter::error("find_rules_subnet - internal data structure error, missing rule"); Reporter::error("find_rules_subnet - internal data structure error, missing rule");
} }

View file

@ -158,17 +158,17 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat
if ( e$ty == CONNECTION ) if ( e$ty == CONNECTION )
{ {
v[|v|] = OpenFlow::match_conn(e$conn); # forward and... v += OpenFlow::match_conn(e$conn); # forward and...
v[|v|] = OpenFlow::match_conn(e$conn, T); # reverse v += OpenFlow::match_conn(e$conn, T); # reverse
return openflow_match_pred(p, e, v); return openflow_match_pred(p, e, v);
} }
if ( e$ty == MAC ) if ( e$ty == MAC )
{ {
v[|v|] = OpenFlow::ofp_match( v += OpenFlow::ofp_match(
$dl_src=e$mac $dl_src=e$mac
); );
v[|v|] = OpenFlow::ofp_match( v += OpenFlow::ofp_match(
$dl_dst=e$mac $dl_dst=e$mac
); );
@ -182,12 +182,12 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat
if ( is_v6_subnet(e$ip) ) if ( is_v6_subnet(e$ip) )
dl_type = OpenFlow::ETH_IPv6; dl_type = OpenFlow::ETH_IPv6;
v[|v|] = OpenFlow::ofp_match( v += OpenFlow::ofp_match(
$dl_type=dl_type, $dl_type=dl_type,
$nw_src=e$ip $nw_src=e$ip
); );
v[|v|] = OpenFlow::ofp_match( v += OpenFlow::ofp_match(
$dl_type=dl_type, $dl_type=dl_type,
$nw_dst=e$ip $nw_dst=e$ip
); );
@ -231,7 +231,7 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat
m$tp_dst = port_to_count(f$dst_p); m$tp_dst = port_to_count(f$dst_p);
} }
v[|v|] = m; v += m;
return openflow_match_pred(p, e, v); return openflow_match_pred(p, e, v);
} }

View file

@ -88,7 +88,7 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m
local flow_actions: vector of ryu_flow_action = vector(); local flow_actions: vector of ryu_flow_action = vector();
for ( i in flow_mod$actions$out_ports ) for ( i in flow_mod$actions$out_ports )
flow_actions[|flow_actions|] = ryu_flow_action($_type="OUTPUT", $_port=flow_mod$actions$out_ports[i]); flow_actions += ryu_flow_action($_type="OUTPUT", $_port=flow_mod$actions$out_ports[i]);
# Generate our ryu_flow_mod record for the ReST API call. # Generate our ryu_flow_mod record for the ReST API call.
local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod(

View file

@ -267,7 +267,7 @@ function add_observe_plugin_dependency(calc: Calculation, depends_on: Calculatio
{ {
if ( calc !in calc_deps ) if ( calc !in calc_deps )
calc_deps[calc] = vector(); calc_deps[calc] = vector();
calc_deps[calc][|calc_deps[calc]|] = depends_on; calc_deps[calc] += depends_on;
} }
event bro_init() &priority=100000 event bro_init() &priority=100000
@ -348,7 +348,7 @@ function add_calc_deps(calcs: vector of Calculation, c: Calculation)
{ {
if ( calc_deps[c][i] in calc_deps ) if ( calc_deps[c][i] in calc_deps )
add_calc_deps(calcs, calc_deps[c][i]); add_calc_deps(calcs, calc_deps[c][i]);
calcs[|c|] = calc_deps[c][i]; calcs += calc_deps[c][i];
#print fmt("add dep for %s [%s] ", c, calc_deps[c][i]); #print fmt("add dep for %s [%s] ", c, calc_deps[c][i]);
} }
} }
@ -387,7 +387,7 @@ function create(ss: SumStat)
skip_calc=T; skip_calc=T;
} }
if ( ! skip_calc ) if ( ! skip_calc )
reducer$calc_funcs[|reducer$calc_funcs|] = calc; reducer$calc_funcs += calc;
} }
if ( reducer$stream !in reducer_store ) if ( reducer$stream !in reducer_store )

View file

@ -11,7 +11,7 @@ event SumStats::process_epoch_result(ss: SumStat, now: time, data: ResultTable)
for ( key in data ) for ( key in data )
{ {
ss$epoch_result(now, key, data[key]); ss$epoch_result(now, key, data[key]);
keys_to_delete[|keys_to_delete|] = key; keys_to_delete += key;
if ( --i == 0 ) if ( --i == 0 )
break; break;

View file

@ -43,7 +43,7 @@ function sample_add_sample(obs:Observation, rv: ResultVal)
++rv$sample_elements; ++rv$sample_elements;
if ( |rv$samples| < rv$num_samples ) if ( |rv$samples| < rv$num_samples )
rv$samples[|rv$samples|] = obs; rv$samples += obs;
else else
{ {
local ra = rand(rv$sample_elements); local ra = rand(rv$sample_elements);

View file

@ -178,7 +178,7 @@ event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, ms
if ( uid !in log_info$uids ) if ( uid !in log_info$uids )
add log_info$uids[uid]; add log_info$uids[uid];
log_info$msg_types[|log_info$msg_types|] = DHCP::message_types[msg$m_type]; log_info$msg_types += DHCP::message_types[msg$m_type];
# Let's watch for messages in any DHCP message type # Let's watch for messages in any DHCP message type
# and split them out based on client and server. # and split them out based on client and server.

View file

@ -324,11 +324,11 @@ hook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string)
{ {
if ( ! c$dns?$answers ) if ( ! c$dns?$answers )
c$dns$answers = vector(); c$dns$answers = vector();
c$dns$answers[|c$dns$answers|] = reply; c$dns$answers += reply;
if ( ! c$dns?$TTLs ) if ( ! c$dns?$TTLs )
c$dns$TTLs = vector(); c$dns$TTLs = vector();
c$dns$TTLs[|c$dns$TTLs|] = ans$TTL; c$dns$TTLs += ans$TTL;
} }
} }
} }

View file

@ -87,14 +87,14 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
if ( ! c$http?$orig_fuids ) if ( ! c$http?$orig_fuids )
c$http$orig_fuids = string_vec(f$id); c$http$orig_fuids = string_vec(f$id);
else else
c$http$orig_fuids[|c$http$orig_fuids|] = f$id; c$http$orig_fuids += f$id;
if ( f$info?$filename ) if ( f$info?$filename )
{ {
if ( ! c$http?$orig_filenames ) if ( ! c$http?$orig_filenames )
c$http$orig_filenames = string_vec(f$info$filename); c$http$orig_filenames = string_vec(f$info$filename);
else else
c$http$orig_filenames[|c$http$orig_filenames|] = f$info$filename; c$http$orig_filenames += f$info$filename;
} }
} }
@ -103,14 +103,14 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
if ( ! c$http?$resp_fuids ) if ( ! c$http?$resp_fuids )
c$http$resp_fuids = string_vec(f$id); c$http$resp_fuids = string_vec(f$id);
else else
c$http$resp_fuids[|c$http$resp_fuids|] = f$id; c$http$resp_fuids += f$id;
if ( f$info?$filename ) if ( f$info?$filename )
{ {
if ( ! c$http?$resp_filenames ) if ( ! c$http?$resp_filenames )
c$http$resp_filenames = string_vec(f$info$filename); c$http$resp_filenames = string_vec(f$info$filename);
else else
c$http$resp_filenames[|c$http$resp_filenames|] = f$info$filename; c$http$resp_filenames += f$info$filename;
} }
} }
@ -130,14 +130,14 @@ event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
if ( ! f$http?$orig_mime_types ) if ( ! f$http?$orig_mime_types )
f$http$orig_mime_types = string_vec(meta$mime_type); f$http$orig_mime_types = string_vec(meta$mime_type);
else else
f$http$orig_mime_types[|f$http$orig_mime_types|] = meta$mime_type; f$http$orig_mime_types += meta$mime_type;
} }
else else
{ {
if ( ! f$http?$resp_mime_types ) if ( ! f$http?$resp_mime_types )
f$http$resp_mime_types = string_vec(meta$mime_type); f$http$resp_mime_types = string_vec(meta$mime_type);
else else
f$http$resp_mime_types[|f$http$resp_mime_types|] = meta$mime_type; f$http$resp_mime_types += meta$mime_type;
} }
} }

View file

@ -47,7 +47,7 @@ function extract_keys(data: string, kv_splitter: pattern): string_vec
{ {
local key_val = split_string1(parts[part_index], /=/); local key_val = split_string1(parts[part_index], /=/);
if ( 0 in key_val ) if ( 0 in key_val )
key_vec[|key_vec|] = key_val[0]; key_vec += key_val[0];
} }
return key_vec; return key_vec;
} }

View file

@ -226,7 +226,7 @@ event sip_header(c: connection, is_request: bool, name: string, value: string) &
c$sip$user_agent = value; c$sip$user_agent = value;
break; break;
case "VIA", "V": case "VIA", "V":
c$sip$request_path[|c$sip$request_path|] = split_string1(value, /;[ ]?branch/)[0]; c$sip$request_path += split_string1(value, /;[ ]?branch/)[0];
break; break;
} }
@ -256,7 +256,7 @@ event sip_header(c: connection, is_request: bool, name: string, value: string) &
c$sip$response_to = value; c$sip$response_to = value;
break; break;
case "VIA", "V": case "VIA", "V":
c$sip$response_path[|c$sip$response_path|] = split_string1(value, /;[ ]?branch/)[0]; c$sip$response_path += split_string1(value, /;[ ]?branch/)[0];
break; break;
} }

View file

@ -49,5 +49,5 @@ event bro_init() &priority=5
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5 event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5
{ {
if ( c?$smtp && !c$smtp$tls ) if ( c?$smtp && !c$smtp$tls )
c$smtp$fuids[|c$smtp$fuids|] = f$id; c$smtp$fuids += f$id;
} }

View file

@ -295,7 +295,7 @@ event mime_one_header(c: connection, h: mime_header_rec) &priority=3
c$smtp$process_received_from = F; c$smtp$process_received_from = F;
} }
if ( c$smtp$path[|c$smtp$path|-1] != ip ) if ( c$smtp$path[|c$smtp$path|-1] != ip )
c$smtp$path[|c$smtp$path|] = ip; c$smtp$path += ip;
} }
event connection_state_remove(c: connection) &priority=-5 event connection_state_remove(c: connection) &priority=-5

View file

@ -121,13 +121,13 @@ event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
if ( f$is_orig ) if ( f$is_orig )
{ {
c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = f$info; c$ssl$client_cert_chain += f$info;
c$ssl$client_cert_chain_fuids[|c$ssl$client_cert_chain_fuids|] = f$id; c$ssl$client_cert_chain_fuids += f$id;
} }
else else
{ {
c$ssl$cert_chain[|c$ssl$cert_chain|] = f$info; c$ssl$cert_chain += f$info;
c$ssl$cert_chain_fuids[|c$ssl$cert_chain_fuids|] = f$id; c$ssl$cert_chain_fuids += f$id;
} }
} }

View file

@ -118,7 +118,7 @@ function extract_ip_addresses(input: string): string_vec
for ( i in parts ) for ( i in parts )
{ {
if ( i % 2 == 1 && is_valid_ip(parts[i]) ) if ( i % 2 == 1 && is_valid_ip(parts[i]) )
output[|output|] = parts[i]; output += parts[i];
} }
return output; return output;
} }

View file

@ -10,7 +10,7 @@ function extract_email_addrs_vec(str: string): string_vec
local raw_addrs = find_all(str, /(^|[<,:[:blank:]])[^<,:[:blank:]@]+"@"[^>,;[:blank:]]+([>,;[:blank:]]|$)/); local raw_addrs = find_all(str, /(^|[<,:[:blank:]])[^<,:[:blank:]@]+"@"[^>,;[:blank:]]+([>,;[:blank:]]|$)/);
for ( raw_addr in raw_addrs ) for ( raw_addr in raw_addrs )
addrs[|addrs|] = gsub(raw_addr, /[<>,:;[:blank:]]/, ""); addrs += gsub(raw_addr, /[<>,:;[:blank:]]/, "");
return addrs; return addrs;
} }

View file

@ -69,14 +69,14 @@ event Exec::line(description: Input::EventDescription, tpe: Input::Event, s: str
if ( ! result?$stderr ) if ( ! result?$stderr )
result$stderr = vector(s); result$stderr = vector(s);
else else
result$stderr[|result$stderr|] = s; result$stderr += s;
} }
else else
{ {
if ( ! result?$stdout ) if ( ! result?$stdout )
result$stdout = vector(s); result$stdout = vector(s);
else else
result$stdout[|result$stdout|] = s; result$stdout += s;
} }
} }
@ -93,7 +93,7 @@ event Exec::file_line(description: Input::EventDescription, tpe: Input::Event, s
if ( track_file !in result$files ) if ( track_file !in result$files )
result$files[track_file] = vector(s); result$files[track_file] = vector(s);
else else
result$files[track_file][|result$files[track_file]|] = s; result$files[track_file] += s;
} }
event Input::end_of_data(orig_name: string, source:string) event Input::end_of_data(orig_name: string, source:string)

View file

@ -66,7 +66,7 @@ function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: p
if ( field_desc?$value && (!only_loggable || field_desc$log) ) if ( field_desc?$value && (!only_loggable || field_desc$log) )
{ {
local onepart = cat("\"", field, "\": ", to_json(field_desc$value, only_loggable)); local onepart = cat("\"", field, "\": ", to_json(field_desc$value, only_loggable));
rec_parts[|rec_parts|] = onepart; rec_parts += onepart;
} }
} }
return cat("{", join_string_vec(rec_parts, ", "), "}"); return cat("{", join_string_vec(rec_parts, ", "), "}");
@ -79,7 +79,7 @@ function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: p
local sa: set[bool] = v; local sa: set[bool] = v;
for ( sv in sa ) for ( sv in sa )
{ {
set_parts[|set_parts|] = to_json(sv, only_loggable); set_parts += to_json(sv, only_loggable);
} }
return cat("[", join_string_vec(set_parts, ", "), "]"); return cat("[", join_string_vec(set_parts, ", "), "]");
} }
@ -91,7 +91,7 @@ function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: p
{ {
local ts = to_json(ti); local ts = to_json(ti);
local if_quotes = (ts[0] == "\"") ? "" : "\""; local if_quotes = (ts[0] == "\"") ? "" : "\"";
tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", to_json(ta[ti], only_loggable)); tab_parts += cat(if_quotes, ts, if_quotes, ": ", to_json(ta[ti], only_loggable));
} }
return cat("{", join_string_vec(tab_parts, ", "), "}"); return cat("{", join_string_vec(tab_parts, ", "), "}");
} }
@ -101,7 +101,7 @@ function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: p
local va: vector of any = v; local va: vector of any = v;
for ( vi in va ) for ( vi in va )
{ {
vec_parts[|vec_parts|] = to_json(va[vi], only_loggable); vec_parts += to_json(va[vi], only_loggable);
} }
return cat("[", join_string_vec(vec_parts, ", "), "]"); return cat("[", join_string_vec(vec_parts, ", "), "]");
} }

View file

@ -35,7 +35,7 @@ hook notice(n: Notice::Info) &priority=10
when ( local src_name = lookup_addr(n$src) ) when ( local src_name = lookup_addr(n$src) )
{ {
output = string_cat("orig/src hostname: ", src_name, "\n"); output = string_cat("orig/src hostname: ", src_name, "\n");
tmp_notice_storage[uid]$email_body_sections[|tmp_notice_storage[uid]$email_body_sections|] = output; tmp_notice_storage[uid]$email_body_sections += output;
delete tmp_notice_storage[uid]$email_delay_tokens["hostnames-src"]; delete tmp_notice_storage[uid]$email_delay_tokens["hostnames-src"];
} }
} }
@ -45,7 +45,7 @@ hook notice(n: Notice::Info) &priority=10
when ( local dst_name = lookup_addr(n$dst) ) when ( local dst_name = lookup_addr(n$dst) )
{ {
output = string_cat("resp/dst hostname: ", dst_name, "\n"); output = string_cat("resp/dst hostname: ", dst_name, "\n");
tmp_notice_storage[uid]$email_body_sections[|tmp_notice_storage[uid]$email_body_sections|] = output; tmp_notice_storage[uid]$email_body_sections += output;
delete tmp_notice_storage[uid]$email_delay_tokens["hostnames-dst"]; delete tmp_notice_storage[uid]$email_delay_tokens["hostnames-dst"];
} }
} }

View file

@ -40,7 +40,7 @@ event bro_init() &priority=5
# Sort nodes list so that every node iterates over it in same order. # Sort nodes list so that every node iterates over it in same order.
for ( name in Cluster::nodes ) for ( name in Cluster::nodes )
sorted_node_names[|sorted_node_names|] = name; sorted_node_names += name;
sort(sorted_node_names, strcmp); sort(sorted_node_names, strcmp);

View file

@ -17,5 +17,5 @@ export {
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=3 event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=3
{ {
log_info$msg_orig[|log_info$msg_orig|] = is_orig ? id$orig_h : id$resp_h; log_info$msg_orig += is_orig ? id$orig_h : id$resp_h;
} }

View file

@ -35,7 +35,7 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr
{ {
if ( ! c$http?$client_header_names ) if ( ! c$http?$client_header_names )
c$http$client_header_names = vector(); c$http$client_header_names = vector();
c$http$client_header_names[|c$http$client_header_names|] = name; c$http$client_header_names += name;
} }
} }
else else
@ -44,7 +44,7 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr
{ {
if ( ! c$http?$server_header_names ) if ( ! c$http?$server_header_names )
c$http$server_header_names = vector(); c$http$server_header_names = vector();
c$http$server_header_names[|c$http$server_header_names|] = name; c$http$server_header_names += name;
} }
} }
} }

View file

@ -50,33 +50,33 @@ event bro_init()
# Minimum length a heartbeat packet must have for different cipher suites. # Minimum length a heartbeat packet must have for different cipher suites.
# Note - tls 1.1f and 1.0 have different lengths :( # Note - tls 1.1f and 1.0 have different lengths :(
# This should be all cipher suites usually supported by vulnerable servers. # This should be all cipher suites usually supported by vulnerable servers.
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_256_GCM_SHA384$/, $min_length=43]; min_lengths_tls11 += [$cipher=/_AES_256_GCM_SHA384$/, $min_length=43];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_128_GCM_SHA256$/, $min_length=43]; min_lengths_tls11 += [$cipher=/_AES_128_GCM_SHA256$/, $min_length=43];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA384$/, $min_length=96]; min_lengths_tls11 += [$cipher=/_256_CBC_SHA384$/, $min_length=96];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA256$/, $min_length=80]; min_lengths_tls11 += [$cipher=/_256_CBC_SHA256$/, $min_length=80];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA$/, $min_length=64]; min_lengths_tls11 += [$cipher=/_256_CBC_SHA$/, $min_length=64];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA256$/, $min_length=80]; min_lengths_tls11 += [$cipher=/_128_CBC_SHA256$/, $min_length=80];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA$/, $min_length=64]; min_lengths_tls11 += [$cipher=/_128_CBC_SHA$/, $min_length=64];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=48]; min_lengths_tls11 += [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=48];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=64]; min_lengths_tls11 += [$cipher=/_SEED_CBC_SHA$/, $min_length=64];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=48]; min_lengths_tls11 += [$cipher=/_IDEA_CBC_SHA$/, $min_length=48];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES_CBC_SHA$/, $min_length=48]; min_lengths_tls11 += [$cipher=/_DES_CBC_SHA$/, $min_length=48];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=48]; min_lengths_tls11 += [$cipher=/_DES40_CBC_SHA$/, $min_length=48];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; min_lengths_tls11 += [$cipher=/_RC4_128_SHA$/, $min_length=39];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; min_lengths_tls11 += [$cipher=/_RC4_128_MD5$/, $min_length=35];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; min_lengths_tls11 += [$cipher=/_RC4_40_MD5$/, $min_length=35];
min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=48]; min_lengths_tls11 += [$cipher=/_RC2_CBC_40_MD5$/, $min_length=48];
min_lengths[|min_lengths|] = [$cipher=/_256_CBC_SHA$/, $min_length=48]; min_lengths += [$cipher=/_256_CBC_SHA$/, $min_length=48];
min_lengths[|min_lengths|] = [$cipher=/_128_CBC_SHA$/, $min_length=48]; min_lengths += [$cipher=/_128_CBC_SHA$/, $min_length=48];
min_lengths[|min_lengths|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=40]; min_lengths += [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=40];
min_lengths[|min_lengths|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=48]; min_lengths += [$cipher=/_SEED_CBC_SHA$/, $min_length=48];
min_lengths[|min_lengths|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=40]; min_lengths += [$cipher=/_IDEA_CBC_SHA$/, $min_length=40];
min_lengths[|min_lengths|] = [$cipher=/_DES_CBC_SHA$/, $min_length=40]; min_lengths += [$cipher=/_DES_CBC_SHA$/, $min_length=40];
min_lengths[|min_lengths|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=40]; min_lengths += [$cipher=/_DES40_CBC_SHA$/, $min_length=40];
min_lengths[|min_lengths|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; min_lengths += [$cipher=/_RC4_128_SHA$/, $min_length=39];
min_lengths[|min_lengths|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; min_lengths += [$cipher=/_RC4_128_MD5$/, $min_length=35];
min_lengths[|min_lengths|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; min_lengths += [$cipher=/_RC4_40_MD5$/, $min_length=35];
min_lengths[|min_lengths|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=40]; min_lengths += [$cipher=/_RC2_CBC_40_MD5$/, $min_length=40];
} }
event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string) event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string)

View file

@ -56,7 +56,7 @@ event ssl_established(c: connection) &priority=3
local waits_already = digest in waitlist; local waits_already = digest in waitlist;
if ( ! waits_already ) if ( ! waits_already )
waitlist[digest] = vector(); waitlist[digest] = vector();
waitlist[digest][|waitlist[digest]|] = c$ssl; waitlist[digest] += c$ssl;
if ( waits_already ) if ( waits_already )
return; return;

View file

@ -76,7 +76,7 @@ event bro_init()
event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string) &priority=5 event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string) &priority=5
{ {
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_and_hashalgorithm$SignatureAlgorithm, $hash_alg=signature_and_hashalgorithm$HashAlgorithm, $signature=signature, $source=SCT_TLS_EXT); c$ssl$ct_proofs += SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_and_hashalgorithm$SignatureAlgorithm, $hash_alg=signature_and_hashalgorithm$HashAlgorithm, $signature=signature, $source=SCT_TLS_EXT);
} }
event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string) &priority=5 event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string) &priority=5
@ -103,7 +103,7 @@ event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, log
local c = f$conns[cid]; local c = f$conns[cid];
} }
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_algorithm, $hash_alg=hash_algorithm, $signature=signature, $source=src); c$ssl$ct_proofs += SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_algorithm, $hash_alg=hash_algorithm, $signature=signature, $source=src);
} }
# Priority = 19 will be handled after validation is done # Priority = 19 will be handled after validation is done

View file

@ -1449,7 +1449,8 @@ bool AddExpr::DoUnserialize(UnserialInfo* info)
} }
AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2) AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
: BinaryExpr(EXPR_ADD_TO, arg_op1->MakeLvalue(), arg_op2) : BinaryExpr(EXPR_ADD_TO,
is_vector(arg_op1) ? arg_op1 : arg_op1->MakeLvalue(), arg_op2)
{ {
if ( IsError() ) if ( IsError() )
return; return;
@ -1463,6 +1464,32 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
SetType(base_type(bt1)); SetType(base_type(bt1));
else if ( BothInterval(bt1, bt2) ) else if ( BothInterval(bt1, bt2) )
SetType(base_type(bt1)); SetType(base_type(bt1));
else if ( IsVector(bt1) )
{
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
if ( IsArithmetic(bt1) )
{
if ( IsArithmetic(bt2) )
{
if ( bt2 != bt1 )
op2 = new ArithCoerceExpr(op2, bt1);
SetType(op1->Type()->Ref());
}
else
ExprError("appending non-arithmetic to arithmetic vector");
}
else if ( bt1 != bt2 )
ExprError("incompatible vector append");
else
SetType(op1->Type()->Ref());
}
else else
ExprError("requires two arithmetic or two string operands"); ExprError("requires two arithmetic or two string operands");
} }
@ -1480,6 +1507,14 @@ Val* AddToExpr::Eval(Frame* f) const
return 0; return 0;
} }
if ( is_vector(v1) )
{
VectorVal* vv = v1->AsVectorVal();
if ( ! vv->Assign(vv->Size(), v2) )
reporter->Error("type-checking failed in vector append");
return v1;
}
Val* result = Fold(v1, v2); Val* result = Fold(v1, v2);
Unref(v1); Unref(v1);
Unref(v2); Unref(v2);

View file

@ -1031,8 +1031,6 @@ public:
// Returns false if the type of the argument was wrong. // Returns false if the type of the argument was wrong.
// The vector will automatically grow to accomodate the index. // The vector will automatically grow to accomodate the index.
// 'assigner" is the expression that is doing the assignment;
// it's just used for pinpointing errors.
// //
// Note: does NOT Ref() the element! Remember to do so unless // Note: does NOT Ref() the element! Remember to do so unless
// the element was just created and thus has refcount 1. // the element was just created and thus has refcount 1.

View file

@ -57,3 +57,4 @@ access element (PASS)
% operator (PASS) % operator (PASS)
&& operator (PASS) && operator (PASS)
|| operator (PASS) || operator (PASS)
+= operator (PASS)

View file

@ -91,7 +91,7 @@ function broker_to_bro_vector_recurse(it: opaque of Broker::VectorIterator,
if ( Broker::vector_iterator_last(it) ) if ( Broker::vector_iterator_last(it) )
return rval; return rval;
rval[|rval|] = Broker::vector_iterator_value(it) as string; rval += Broker::vector_iterator_value(it) as string;
Broker::vector_iterator_next(it); Broker::vector_iterator_next(it);
return broker_to_bro_vector_recurse(it, rval); return broker_to_bro_vector_recurse(it, rval);
} }

View file

@ -3,30 +3,30 @@
local v: vector of addr = vector(); local v: vector of addr = vector();
v[|v|] = [::1]; v += [::1];
v[|v|] = [::ffff]; v += [::ffff];
v[|v|] = [::ffff:ffff]; v += [::ffff:ffff];
v[|v|] = [::0a0a:ffff]; v += [::0a0a:ffff];
v[|v|] = [1::1]; v += [1::1];
v[|v|] = [1::a]; v += [1::a];
v[|v|] = [1::1:1]; v += [1::1:1];
v[|v|] = [1::1:a]; v += [1::1:a];
v[|v|] = [a::a]; v += [a::a];
v[|v|] = [a::1]; v += [a::1];
v[|v|] = [a::a:a]; v += [a::a:a];
v[|v|] = [a::a:1]; v += [a::a:1];
v[|v|] = [a:a::a]; v += [a:a::a];
v[|v|] = [aaaa:0::ffff]; v += [aaaa:0::ffff];
v[|v|] = [::ffff:192.168.1.100]; v += [::ffff:192.168.1.100];
v[|v|] = [ffff::192.168.1.100]; v += [ffff::192.168.1.100];
v[|v|] = [::192.168.1.100]; v += [::192.168.1.100];
v[|v|] = [::ffff:0:192.168.1.100]; v += [::ffff:0:192.168.1.100];
v[|v|] = [805B:2D9D:DC28::FC57:212.200.31.255]; v += [805B:2D9D:DC28::FC57:212.200.31.255];
v[|v|] = [0xaaaa::bbbb]; v += [0xaaaa::bbbb];
v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222]; v += [aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222];
v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:1:2222]; v += [aaaa:bbbb:cccc:dddd:eeee:ffff:1:2222];
v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:ffff:0:2222]; v += [aaaa:bbbb:cccc:dddd:eeee:ffff:0:2222];
v[|v|] = [aaaa:bbbb:cccc:dddd:eeee:0:0:2222]; v += [aaaa:bbbb:cccc:dddd:eeee:0:0:2222];
for (i in v) for (i in v)
print v[i]; print v[i];

View file

@ -43,6 +43,6 @@ print_bar(bar6);
local r: MyRecord = [$c=13]; local r: MyRecord = [$c=13];
print r; print r;
print |r$v|; print |r$v|;
r$v[|r$v|] = "test"; r$v += "test";
print r; print r;
print |r$v|; print |r$v|;

View file

@ -163,5 +163,10 @@ event bro_init()
test_case( "&& operator", v14[0] == F && v14[1] == F && v14[2] == T ); test_case( "&& operator", v14[0] == F && v14[1] == F && v14[2] == T );
test_case( "|| operator", v15[0] == T && v15[1] == F && v15[2] == T ); test_case( "|| operator", v15[0] == T && v15[1] == F && v15[2] == T );
# Test += operator.
local v16 = v6;
v16 += 40;
test_case( "+= operator", all_set(v16 == vector( 10, 20, 30, 40 )) );
} }

View file

@ -43,10 +43,10 @@ event dump_info()
event connection_established(c: connection) event connection_established(c: connection)
{ {
local id = c$id; local id = c$id;
rules[|rules|] = NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs); rules += NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs);
rules[|rules|] = NetControl::drop_address(id$orig_h, 0secs); rules += NetControl::drop_address(id$orig_h, 0secs);
rules[|rules|] = NetControl::whitelist_address(id$orig_h, 0secs); rules += NetControl::whitelist_address(id$orig_h, 0secs);
rules[|rules|] = NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs); rules += NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs);
schedule 1sec { remove_all() }; schedule 1sec { remove_all() };
schedule 2sec { dump_info() }; schedule 2sec { dump_info() };

View file

@ -27,10 +27,10 @@ event remove_all()
event connection_established(c: connection) event connection_established(c: connection)
{ {
local id = c$id; local id = c$id;
rules[|rules|] = NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs); rules += NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 0secs);
rules[|rules|] = NetControl::drop_address(id$orig_h, 0secs); rules += NetControl::drop_address(id$orig_h, 0secs);
rules[|rules|] = NetControl::whitelist_address(id$orig_h, 0secs); rules += NetControl::whitelist_address(id$orig_h, 0secs);
rules[|rules|] = NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs); rules += NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 0secs);
schedule 1sec { remove_all() }; schedule 1sec { remove_all() };
} }

View file

@ -31,7 +31,7 @@ event bro_init() &priority=5
print fmt("Host: %s Sampled observations: %d", key$host, r$sample_elements); print fmt("Host: %s Sampled observations: %d", key$host, r$sample_elements);
local sample_nums: vector of count = vector(); local sample_nums: vector of count = vector();
for ( sample in r$samples ) for ( sample in r$samples )
sample_nums[|sample_nums|] =r$samples[sample]$num; sample_nums += r$samples[sample]$num;
print fmt(" %s", sort(sample_nums)); print fmt(" %s", sort(sample_nums));
}, },