diff --git a/CHANGES b/CHANGES index 62a07a4993..e90e85f125 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,39 @@ +2.4-422 | 2016-03-21 19:48:30 -0700 + + * Adapt to recent change in CAF CMake script. (Matthias Vallentin) + + * Deprecate --with-libcaf in favor of --with-caf, as already done in + Broker. (Matthias Vallentin) + +2.4-418 | 2016-03-21 12:22:15 -0700 + + * Add protocol confirmation to MySQL analyzer. (Vlad Grigorescu) + + * Check that there is only one of &read_expire, &write_expire, + &create_expire. (Johanna Amann) + + * Fixed &read_expire for subnet-indexed tables, plus test case. (Jan + Grashoefer) + + * Add filter_subnet_table() that works similar to matching_subnet() + but returns a filtered view of the original set/table only + containing the changed subnets. (Jan Grashoefer) + + * Fix bug in tablue values' tracking read operations. (Johanna + Amann) + + * Update TLS constants and extensions from IANA. (Johanna Amann) + +2.4-406 | 2016-03-11 14:27:47 -0800 + + * Add NetControl and OpenFlow frameworks. (Johanna Amann) + +2.4-313 | 2016-03-08 07:47:57 -0800 + + * Remove old string functions in C++ code. This removes the + functions: strcasecmp_n, strchr_n, and strrchr_n. (Johanna Amann) + 2.4-307 | 2016-03-07 13:33:45 -0800 * Add "disable_analyzer_after_detection" and remove diff --git a/NEWS b/NEWS index fecf7ad336..86c3b1891a 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ New Dependencies New Functionality ----------------- +- Bro now includes the NetControl framework. The framework allows for easy + interaction of Bro with hard- and software switches, firewalls, etc. + - Bro now supports the Radiotap header for 802.11 frames. - Bro now tracks VLAN IDs. To record them inside the connection log, @@ -37,12 +40,37 @@ New Functionality argument that will be used for decoding errors into weird.log (instead of reporter.log). +- Two new built-in functions for handling set[subnet] and table[subnet]: + + - check_subnet(subnet, table) checks if a specific subnet is a member + of a set/table. This is different from the "in" operator, which always + performs a longest prefix match. + + - matching_subnets(subnet, table) returns all subnets of the set or table + that contain the given subnet. + + - filter_subnet_table(subnet, table) works like check_subnet, but returns + a table containing all matching entries. + +- Several built-in functions for handling IP addresses and subnets were added: + + - is_v4_subnet(subnet) checks whether a subnet specification is IPv4. + + - is_v6_subnet(subnet) checks whether a subnet specification is IPv6. + + - addr_to_subnet(addr) converts an IP address to a /32 subnet. + + - subnet_to_addr(subnet) returns the IP address part of a subnet. + + - subnet_width(subnet) returns the width of a subnet. + - The IRC analyzer now recognizes StartTLS sessions and enable the SSL analyzer for them. - New Bro plugins in aux/plugins: - af_packet: Native AF_PACKET support. + - kafka : Log writer interfacing to Kafka. - myricom: Native Myricom SNF v3 support. - pf_ring: Native PF_RING support. - redis: An experimental log writer for Redis. diff --git a/VERSION b/VERSION index 633b8e97fc..032d05a7ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4-307 +2.4-422 diff --git a/aux/binpac b/aux/binpac index 8dff7992f6..424d40c1e8 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 8dff7992f64f91a84f436a3c015991e450faa376 +Subproject commit 424d40c1e8d5888311b50c0e5a9dfc9c5f818b66 diff --git a/aux/bro-aux b/aux/bro-aux index 866dad93a1..105dfe4ad6 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 866dad93a1b5d84b2a1606ef05c3d919df23e15b +Subproject commit 105dfe4ad6c4ae4563b21cb0466ee350f0af0d43 diff --git a/aux/broccoli b/aux/broccoli index 2b1390d95b..6ded82da49 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 2b1390d95b39a8902cf135cb26df68ae0bb79dd3 +Subproject commit 6ded82da498d805def6aa129cd7691d3b7287c37 diff --git a/aux/broctl b/aux/broctl index 1081032c63..583f3a3ff1 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 1081032c63318f9cd42720e9399483e7c8319451 +Subproject commit 583f3a3ff1847cf96a87f865d5cf0f36fae9dd67 diff --git a/aux/broker b/aux/broker index fe35cde8f0..6684ab5109 160000 --- a/aux/broker +++ b/aux/broker @@ -1 +1 @@ -Subproject commit fe35cde8f07ff7cf6decd2fb761cffc32e763d2d +Subproject commit 6684ab5109f526fb535013760f17a4c8dff093ae diff --git a/aux/plugins b/aux/plugins index d251af520c..ab61be0c4f 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit d251af520ccdede694d7b3b7bcbc47df1080508c +Subproject commit ab61be0c4f128c976f72dfa5a09a87cd842f387a diff --git a/cmake b/cmake index 392e6be9b7..537e45afe1 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 392e6be9b7e0ac2e7a892853ef185a7a927ea60e +Subproject commit 537e45afe1006a10f73847fab5f13d28ce43fc4d diff --git a/configure b/configure index a7a6f3b059..8859a6fa9b 100755 --- a/configure +++ b/configure @@ -276,8 +276,12 @@ while [ $# -ne 0 ]; do --with-swig=*) append_cache_entry SWIG_EXECUTABLE PATH $optarg ;; + --with-caf=*) + append_cache_entry CAF_ROOT_DIR PATH $optarg + ;; --with-libcaf=*) - append_cache_entry LIBCAF_ROOT_DIR PATH $optarg + echo "warning: --with-libcaf deprecated, use --with-caf instead" + append_cache_entry CAF_ROOT_DIR PATH $optarg ;; --with-rocksdb=*) append_cache_entry ROCKSDB_ROOT_DIR PATH $optarg diff --git a/scripts/base/frameworks/netcontrol/__load__.bro b/scripts/base/frameworks/netcontrol/__load__.bro new file mode 100644 index 0000000000..a8e391f7c8 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/__load__.bro @@ -0,0 +1,15 @@ +@load ./types +@load ./main +@load ./plugins +@load ./drop +@load ./shunt +@load ./catch-and-release + +# The cluster framework must be loaded first. +@load base/frameworks/cluster + +@if ( Cluster::is_enabled() ) +@load ./cluster +@else +@load ./non-cluster +@endif diff --git a/scripts/base/frameworks/netcontrol/catch-and-release.bro b/scripts/base/frameworks/netcontrol/catch-and-release.bro new file mode 100644 index 0000000000..a95954ac07 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -0,0 +1,104 @@ +##! Implementation of catch-and-release functionality for NetControl. + +module NetControl; + +@load ./main +@load ./drop + +export { + ## Stops all packets involving an IP address from being forwarded. This function + ## uses catch-and-release functionality, where the IP address is only dropped for + ## a short amount of time that is incremented steadily when the IP is encountered + ## again. + ## + ## a: The address to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_address_catch_release: function(a: addr, location: string &default="") : string; + + ## Time intervals for which a subsequent drops of the same IP take + ## effect. + const catch_release_intervals: vector of interval = vector(10min, 1hr, 24hrs, 7days) &redef; +} + +function per_block_interval(t: table[addr] of count, idx: addr): interval + { + local ct = t[idx]; + + # watch for the time of the next block... + local blocktime = catch_release_intervals[ct]; + if ( (ct+1) in catch_release_intervals ) + blocktime = catch_release_intervals[ct+1]; + + return blocktime; + } + +# This is the internally maintained table containing all the currently going on catch-and-release +# blocks. +global blocks: table[addr] of count = {} + &create_expire=0secs + &expire_func=per_block_interval; + +function current_block_interval(s: set[addr], idx: addr): interval + { + if ( idx !in blocks ) + { + Reporter::error(fmt("Address %s not in blocks while inserting into current_blocks!", idx)); + return 0sec; + } + + return catch_release_intervals[blocks[idx]]; + } + +global current_blocks: set[addr] = set() + &create_expire=0secs + &expire_func=current_block_interval; + +function drop_address_catch_release(a: addr, location: string &default=""): string + { + if ( a in blocks ) + { + Reporter::warning(fmt("Address %s already blocked using catch-and-release - ignoring duplicate", a)); + return ""; + } + + local block_interval = catch_release_intervals[0]; + local ret = drop_address(a, block_interval, location); + if ( ret != "" ) + { + blocks[a] = 0; + add current_blocks[a]; + } + + return ret; + } + +function check_conn(a: addr) + { + if ( a in blocks ) + { + if ( a in current_blocks ) + # block has not been applied yet? + return; + + # ok, this one returned again while still in the backoff period. + local try = blocks[a]; + if ( (try+1) in catch_release_intervals ) + ++try; + + blocks[a] = try; + add current_blocks[a]; + local block_interval = catch_release_intervals[try]; + drop_address(a, block_interval, "Re-drop by catch-and-release"); + } + } + +event new_connection(c: connection) + { + # let's only check originating connections... + check_conn(c$id$orig_h); + } diff --git a/scripts/base/frameworks/netcontrol/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro new file mode 100644 index 0000000000..7f635b4375 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -0,0 +1,99 @@ +##! Cluster support for the NetControl framework. + +@load ./main +@load base/frameworks/cluster + +module NetControl; + +export { + ## This is the event used to transport add_rule calls to the manager. + global cluster_netcontrol_add_rule: event(r: Rule); + + ## This is the event used to transport remove_rule calls to the manager. + global cluster_netcontrol_remove_rule: event(id: string); +} + +## Workers need ability to forward commands to manager. +redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove)_rule/; +## Workers need to see the result events from the manager. +redef Cluster::manager2worker_events += /NetControl::rule_(added|removed|timeout|error)/; + + +function activate(p: PluginState, priority: int) + { + # we only run the activate function on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + activate_impl(p, priority); + } + +global local_rule_count: count = 1; + +function add_rule(r: Rule) : string + { + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return add_rule_impl(r); + else + { + if ( r$id == "" ) + r$id = cat(Cluster::node, ":", ++local_rule_count); + + event NetControl::cluster_netcontrol_add_rule(r); + return r$id; + } + } + +function remove_rule(id: string) : bool + { + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return remove_rule_impl(id); + else + { + event NetControl::cluster_netcontrol_remove_rule(id); + return T; # well, we can't know here. So - just hope... + } + } + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event NetControl::cluster_netcontrol_add_rule(r: Rule) + { + add_rule_impl(r); + } + +event NetControl::cluster_netcontrol_remove_rule(id: string) + { + remove_rule_impl(id); + } +@endif + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event rule_expire(r: Rule, p: PluginState) &priority=-5 + { + rule_expire_impl(r, p); + } + +event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 + { + rule_added_impl(r, p, msg); + + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) + schedule r$expire { rule_expire(r, p) }; + } + +event rule_removed(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_removed_impl(r, p, msg); + } + +event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) &priority=-5 + { + rule_timeout_impl(r, i, p); + } + +event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_error_impl(r, p, msg); + } +@endif + diff --git a/scripts/base/frameworks/netcontrol/drop.bro b/scripts/base/frameworks/netcontrol/drop.bro new file mode 100644 index 0000000000..63c70f0e88 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/drop.bro @@ -0,0 +1,98 @@ +##! Implementation of the drop functionality for NetControl. + +module NetControl; + +@load ./main + +export { + redef enum Log::ID += { DROP }; + + ## Stops all packets involving an IP address from being forwarded. + ## + ## a: The address to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_address: function(a: addr, t: interval, location: string &default="") : string; + + ## Stops all packets involving an connection address from being forwarded. + ## + ## c: The connection to be dropped. + ## + ## t: How long to drop it, with 0 being indefinitly. + ## + ## location: An optional string describing where the drop was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_connection: function(c: conn_id, t: interval, location: string &default="") : string; + + type DropInfo: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log; + orig_h: addr &log; ##< The originator's IP address. + orig_p: port &log &optional; ##< The originator's port number. + resp_h: addr &log &optional; ##< The responder's IP address. + resp_p: port &log &optional; ##< The responder's port number. + ## Expiry time of the shunt + expire: interval &log; + ## Location where the underlying action was triggered. + location: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::ShuntInfo` + ## record as it is sent on to the logging framework. + global log_netcontrol_drop: event(rec: DropInfo); +} + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::DROP, [$columns=DropInfo, $ev=log_netcontrol_drop, $path="netcontrol_drop"]); + } + +function drop_connection(c: conn_id, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=CONNECTION, $conn=c]; + local r: Rule = [$ty=DROP, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = DropInfo($ts=network_time(), $rule_id=id, $orig_h=c$orig_h, $orig_p=c$orig_p, $resp_h=c$resp_h, $resp_p=c$resp_p, $expire=t); + + if ( location != "" ) + log$location=location; + + Log::write(DROP, log); + + return id; + } + +function drop_address(a: addr, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; + local r: Rule = [$ty=DROP, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = DropInfo($ts=network_time(), $rule_id=id, $orig_h=a, $expire=t); + + if ( location != "" ) + log$location=location; + + Log::write(DROP, log); + + return id; + } + diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro new file mode 100644 index 0000000000..563188921d --- /dev/null +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -0,0 +1,935 @@ +##! Bro's packet aquisition and control framework. +##! +##! This plugin-based framework allows to control the traffic that Bro monitors +##! as well as, if having access to the forwarding path, the traffic the network +##! forwards. By default, the framework lets everything through, to both Bro +##! itself as well as on the network. Scripts can then add rules to impose +##! restrictions on entities, such as specific connections or IP addresses. +##! +##! This framework has two APIs: a high-level and low-level. The high-level API +##! provides convinience functions for a set of common operations. The +##! low-level API provides full flexibility. + +module NetControl; + +@load ./plugin +@load ./types + +export { + ## The framework's logging stream identifier. + redef enum Log::ID += { LOG }; + + # ### + # ### Generic functions and events. + # ### + + # Activates a plugin. + # + # p: The plugin to acticate. + # + # priority: The higher the priority, the earlier this plugin will be checked + # whether it supports an operation, relative to other plugins. + global activate: function(p: PluginState, priority: int); + + # Event that is used to initialize plugins. Place all plugin initialization + # related functionality in this event. + global NetControl::init: event(); + + # Event that is raised once all plugins activated in ``NetControl::init`` have finished + # their initialization. + global NetControl::init_done: event(); + + # ### + # ### High-level API. + # ### + + # ### Note - other high level primitives are in catch-and-release.bro, shunt.bro and + # ### drop.bro + + ## Allows all traffic involving a specific IP address to be forwarded. + ## + ## a: The address to be whitelistet. + ## + ## t: How long to whitelist it, with 0 being indefinitly. + ## + ## location: An optional string describing whitelist was triddered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global whitelist_address: function(a: addr, t: interval, location: string &default="") : string; + + ## Allows all traffic involving a specific IP subnet to be forwarded. + ## + ## s: The subnet to be whitelistet. + ## + ## t: How long to whitelist it, with 0 being indefinitly. + ## + ## location: An optional string describing whitelist was triddered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global whitelist_subnet: function(s: subnet, t: interval, location: string &default="") : string; + + ## Redirects an uni-directional flow to another port. + ## + ## f: The flow to redirect. + ## + ## out_port: Port to redirect the flow to + ## + ## t: How long to leave the redirect in place, with 0 being indefinitly. + ## + ## location: An optional string describing where the redirect was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global redirect_flow: function(f: flow_id, out_port: count, t: interval, location: string &default="") : string; + + ## Quarantines a host by redirecting rewriting DNS queries to the network dns server dns + ## to the host. Host has to answer to all queries with its own address. Only http communication + ## from infected to quarantinehost is allowed. + ## + ## infected: the host to quarantine + ## + ## dns: the network dns server + ## + ## quarantine: the quarantine server running a dns and a web server + ## + ## t: how long to leave the quarantine in place + ## + ## Returns: Vector of inserted rules on success, empty list on failure. + global quarantine_host: function(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string; + + ## Flushes all state. + global clear: function(); + + # ### + # ### Low-level API. + # ### + + ###### Manipulation of rules. + + ## Installs a rule. + ## + ## r: The rule to install. + ## + ## Returns: If succesful, returns an ID string unique to the rule that can later + ## be used to refer to it. If unsuccessful, returns an empty string. The ID is also + ## assigned to ``r$id``. Note that "successful" means "a plugin knew how to handle + ## the rule", it doesn't necessarily mean that it was indeed successfully put in + ## place, because that might happen asynchronously and thus fail only later. + global add_rule: function(r: Rule) : string; + + ## Removes a rule. + ## + ## id: The rule to remove, specified as the ID returned by :bro:id:`add_rule` . + ## + ## Returns: True if succesful, the relevant plugin indicated that it knew how + ## to handle the removal. Note that again "success" means the plugin accepted the + ## removal. They might still fail to put it into effect, as that might happen + ## asynchronously and thus go wrong at that point. + global remove_rule: function(id: string) : bool; + + ## Searches all rules affecting a certain IP address. + ## + ## ip: The ip address to search for + ## + ## Returns: vector of all rules affecting the IP address + global find_rules_addr: function(ip: addr) : vector of Rule; + + ## Searches all rules affecting a certain subnet. + ## + ## sn: The subnet to search for + ## + ## Returns: vector of all rules affecting the subnet + global find_rules_subnet: function(sn: subnet) : vector of Rule; + + ###### Asynchronous feedback on rules. + + ## Confirms that a rule was put in place. + ## + ## r: The rule now in place. + ## + ## p: The state for the plugin that put it into place. + ## + ## msg: An optional informational message by the plugin. + global rule_added: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Reports that a rule was removed due to a remove: function() call. + ## + ## r: The rule now removed. + ## + ## p: The state for the plugin that had the rule in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global rule_removed: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Reports that a rule was removed internally due to a timeout. + ## + ## r: The rule now removed. + ## + ## i: Additional flow information, if supported by the protocol. + ## + ## p: The state for the plugin that had the rule in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global rule_timeout: event(r: Rule, i: FlowInfo, p: PluginState); + + ## Reports an error when operating on a rule. + ## + ## r: The rule that encountered an error. + ## + ## p: The state for the plugin that reported the error. + ## + ## msg: An optional informational message by the plugin. + global rule_error: event(r: Rule, p: PluginState, msg: string &default=""); + + ## Hook that allows the modification of rules passed to add_rule before they + ## are passed on to the plugins. If one of the hooks uses break, the rule is + ## ignored and not passed on to any plugin. + ## + ## r: The rule to be added + global NetControl::rule_policy: hook(r: Rule); + + ##### Plugin functions + + ## Function called by plugins once they finished their activation. After all + ## plugins defined in bro_init finished to activate, rules will start to be sent + ## to the plugins. Rules that scripts try to set before the backends are ready + ## will be discarded. + global plugin_activated: function(p: PluginState); + + ## Type of an entry in the NetControl log. + type InfoCategory: enum { + ## A log entry reflecting a framework message. + MESSAGE, + ## A log entry reflecting a framework message. + ERROR, + ## A log entry about about a rule. + RULE + }; + + ## State of an entry in the NetControl log. + type InfoState: enum { + REQUESTED, + SUCCEEDED, + FAILED, + REMOVED, + TIMEOUT, + }; + + ## The record type defining the column fields of the NetControl log. + type Info: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log &optional; + ## Type of the log entry. + category: InfoCategory &log &optional; + ## The command the log entry is about. + cmd: string &log &optional; + ## State the log entry reflects. + state: InfoState &log &optional; + ## String describing an action the entry is about. + action: string &log &optional; + ## The target type of the action. + target: TargetType &log &optional; + ## Type of the entity the log entry is about. + entity_type: string &log &optional; + ## String describing the entity the log entry is about. + entity: string &log &optional; + ## String describing the optional modification of the entry (e.h. redirect) + mod: string &log &optional; + ## String with an additional message. + msg: string &log &optional; + ## Number describing the priority of the log entry + priority: int &log &optional; + ## Expiry time of the log entry + expire: interval &log &optional; + ## Location where the underlying action was triggered. + location: string &log &optional; + ## Plugin triggering the log entry. + plugin: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::Info` + ## record as it is sent on to the logging framework. + global log_netcontrol: event(rec: Info); +} + +redef record Rule += { + ##< Internally set to the plugins handling the rule. + _plugin_ids: set[count] &default=count_set(); + ##< Internally set to the plugins on which the rule is currently active. + _active_plugin_ids: set[count] &default=count_set(); + ##< Track if the rule was added succesfully by all responsible plugins. + _added: bool &default=F; +}; + +# Variable tracking the state of plugin activation. Once all plugins that +# have been added in bro_init are activated, this will switch to T and +# the event NetControl::init_done will be raised. +global plugins_active: bool = F; + +# Set to true at the end of bro_init (with very low priority). +# Used to track when plugin activation could potentially be finished +global bro_init_done: bool = F; + +# The counters that are used to generate the rule and plugin IDs +global rule_counter: count = 1; +global plugin_counter: count = 1; + +# List of the currently active plugins +global plugins: vector of PluginState; +global plugin_ids: table[count] of PluginState; + +# These tables hold information about rules. +global rules: table[string] of Rule; # Rules indexed by id and cid + +# All rules that apply to a certain subnet/IP address. +global rules_by_subnets: table[subnet] of set[string]; + +# Rules pertaining to a specific entity. +# There always only can be one rule of each type for one entity. +global rule_entities: table[Entity, RuleType] of Rule; + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::LOG, [$columns=Info, $ev=log_netcontrol, $path="netcontrol"]); + } + +function entity_to_info(info: Info, e: Entity) + { + info$entity_type = fmt("%s", e$ty); + + switch ( e$ty ) { + case ADDRESS: + info$entity = fmt("%s", e$ip); + break; + + case CONNECTION: + info$entity = fmt("%s/%d<->%s/%d", + e$conn$orig_h, e$conn$orig_p, + e$conn$resp_h, e$conn$resp_p); + break; + + case FLOW: + local ffrom_ip = "*"; + local ffrom_port = "*"; + local fto_ip = "*"; + local fto_port = "*"; + local ffrom_mac = "*"; + local fto_mac = "*"; + if ( e$flow?$src_h ) + ffrom_ip = cat(e$flow$src_h); + if ( e$flow?$src_p ) + ffrom_port = fmt("%d", e$flow$src_p); + if ( e$flow?$dst_h ) + fto_ip = cat(e$flow$dst_h); + if ( e$flow?$dst_p ) + fto_port = fmt("%d", e$flow$dst_p); + info$entity = fmt("%s/%s->%s/%s", + ffrom_ip, ffrom_port, + fto_ip, fto_port); + if ( e$flow?$src_m || e$flow?$dst_m ) + { + if ( e$flow?$src_m ) + ffrom_mac = e$flow$src_m; + if ( e$flow?$dst_m ) + fto_mac = e$flow$dst_m; + + info$entity = fmt("%s (%s->%s)", info$entity, ffrom_mac, fto_mac); + } + break; + + case MAC: + info$entity = e$mac; + break; + + default: + info$entity = ""; + break; + } + } + +function rule_to_info(info: Info, r: Rule) + { + info$action = fmt("%s", r$ty); + info$target = r$target; + info$rule_id = r$id; + info$expire = r$expire; + info$priority = r$priority; + + if ( r?$location && r$location != "" ) + info$location = r$location; + + if ( r$ty == REDIRECT ) + info$mod = fmt("-> %d", r$out_port); + + if ( r$ty == MODIFY ) + { + local mfrom_ip = "_"; + local mfrom_port = "_"; + local mto_ip = "_"; + local mto_port = "_"; + local mfrom_mac = "_"; + local mto_mac = "_"; + if ( r$mod?$src_h ) + mfrom_ip = cat(r$mod$src_h); + if ( r$mod?$src_p ) + mfrom_port = fmt("%d", r$mod$src_p); + if ( r$mod?$dst_h ) + mto_ip = cat(r$mod$dst_h); + if ( r$mod?$dst_p ) + mto_port = fmt("%d", r$mod$dst_p); + + if ( r$mod?$src_m ) + mfrom_mac = r$mod$src_m; + if ( r$mod?$dst_m ) + mto_mac = r$mod$dst_m; + + info$mod = fmt("Src: %s/%s (%s) Dst: %s/%s (%s)", + mfrom_ip, mfrom_port, mfrom_mac, mto_ip, mto_port, mto_mac); + + if ( r$mod?$redirect_port ) + info$mod = fmt("%s -> %d", info$mod, r$mod$redirect_port); + + } + + entity_to_info(info, r$entity); + } + +function log_msg(msg: string, p: PluginState) + { + Log::write(LOG, [$ts=network_time(), $category=MESSAGE, $msg=msg, $plugin=p$plugin$name(p)]); + } + +function log_error(msg: string, p: PluginState) + { + Log::write(LOG, [$ts=network_time(), $category=ERROR, $msg=msg, $plugin=p$plugin$name(p)]); + } + +function log_msg_no_plugin(msg: string) + { + Log::write(LOG, [$ts=network_time(), $category=MESSAGE, $msg=msg]); + } + +function log_rule(r: Rule, cmd: string, state: InfoState, p: PluginState, msg: string &default="") + { + local info: Info = [$ts=network_time()]; + info$category = RULE; + info$cmd = cmd; + info$state = state; + info$plugin = p$plugin$name(p); + if ( msg != "" ) + info$msg = msg; + + rule_to_info(info, r); + + Log::write(LOG, info); + } + +function log_rule_error(r: Rule, msg: string, p: PluginState) + { + local info: Info = [$ts=network_time(), $category=ERROR, $msg=msg, $plugin=p$plugin$name(p)]; + rule_to_info(info, r); + Log::write(LOG, info); + } + +function log_rule_no_plugin(r: Rule, state: InfoState, msg: string) + { + local info: Info = [$ts=network_time()]; + info$category = RULE; + info$state = state; + info$msg = msg; + + rule_to_info(info, r); + + Log::write(LOG, info); + } + +function whitelist_address(a: addr, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; + local r: Rule = [$ty=WHITELIST, $priority=whitelist_priority, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + return add_rule(r); + } + +function whitelist_subnet(s: subnet, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=s]; + local r: Rule = [$ty=WHITELIST, $priority=whitelist_priority, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + return add_rule(r); + } + + +function redirect_flow(f: flow_id, out_port: count, t: interval, location: string &default="") : string + { + local flow = NetControl::Flow( + $src_h=addr_to_subnet(f$src_h), + $src_p=f$src_p, + $dst_h=addr_to_subnet(f$dst_h), + $dst_p=f$dst_p + ); + local e: Entity = [$ty=FLOW, $flow=flow]; + local r: Rule = [$ty=REDIRECT, $target=FORWARD, $entity=e, $expire=t, $location=location, $out_port=out_port]; + + return add_rule(r); + } + +function quarantine_host(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string + { + local orules: vector of string = vector(); + 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]; + orules[|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 todnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=todnse, $expire=t, $location=location, $mod=FlowMod($dst_h=quarantine), $priority=+5); + orules[|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 fromdnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=fromdnse, $expire=t, $location=location, $mod=FlowMod($src_h=dns), $priority=+5); + orules[|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 wlr = Rule($ty=WHITELIST, $target=FORWARD, $entity=wle, $expire=t, $location=location, $priority=+5); + orules[|orules|] = add_rule(wlr); + + return orules; + } + +function check_plugins() + { + if ( plugins_active ) + return; + + local all_active = T; + for ( i in plugins ) + { + local p = plugins[i]; + if ( p$_activated == F ) + all_active = F; + } + + if ( all_active ) + { + plugins_active = T; + + # Skip log message if there are no plugins + if ( |plugins| > 0 ) + log_msg_no_plugin("plugin initialization done"); + + event NetControl::init_done(); + } + } + +function plugin_activated(p: PluginState) + { + local id = p$_id; + if ( id !in plugin_ids ) + { + log_error("unknown plugin activated", p); + return; + } + plugin_ids[id]$_activated = T; + log_msg("activation finished", p); + + if ( bro_init_done ) + check_plugins(); + } + +event bro_init() &priority=-5 + { + event NetControl::init(); + } + +event NetControl::init() &priority=-20 + { + bro_init_done = T; + + check_plugins(); + + if ( plugins_active == F ) + log_msg_no_plugin("waiting for plugins to initialize"); + } + +# Low-level functions that only runs on the manager (or standalone) Bro node. + +function activate_impl(p: PluginState, priority: int) + { + p$_priority = priority; + plugins[|plugins|] = p; + sort(plugins, function(p1: PluginState, p2: PluginState) : int { return p2$_priority - p1$_priority; }); + + plugin_ids[plugin_counter] = p; + p$_id = plugin_counter; + ++plugin_counter; + + # perform one-time initialization + if ( p$plugin?$init ) + { + log_msg(fmt("activating plugin with priority %d", priority), p); + p$plugin$init(p); + } + else + { + # no initialization necessary, mark plugin as active right away + plugin_activated(p); + } + + } + +function add_one_subnet_entry(s: subnet, r: Rule) + { + if ( ! check_subnet(s, rules_by_subnets) ) + rules_by_subnets[s] = set(r$id); + else + add rules_by_subnets[s][r$id]; + } + +function add_subnet_entry(rule: Rule) + { + local e = rule$entity; + if ( e$ty == ADDRESS ) + { + add_one_subnet_entry(e$ip, rule); + } + else if ( e$ty == CONNECTION ) + { + add_one_subnet_entry(addr_to_subnet(e$conn$orig_h), rule); + add_one_subnet_entry(addr_to_subnet(e$conn$resp_h), rule); + } + else if ( e$ty == FLOW ) + { + if ( e$flow?$src_h ) + add_one_subnet_entry(e$flow$src_h, rule); + if ( e$flow?$dst_h ) + add_one_subnet_entry(e$flow$dst_h, rule); + } + } + +function remove_one_subnet_entry(s: subnet, r: Rule) + { + if ( ! check_subnet(s, rules_by_subnets) ) + return; + + if ( r$id !in rules_by_subnets[s] ) + return; + + delete rules_by_subnets[s][r$id]; + if ( |rules_by_subnets[s]| == 0 ) + delete rules_by_subnets[s]; + } + +function remove_subnet_entry(rule: Rule) + { + local e = rule$entity; + if ( e$ty == ADDRESS ) + { + remove_one_subnet_entry(e$ip, rule); + } + else if ( e$ty == CONNECTION ) + { + remove_one_subnet_entry(addr_to_subnet(e$conn$orig_h), rule); + remove_one_subnet_entry(addr_to_subnet(e$conn$resp_h), rule); + } + else if ( e$ty == FLOW ) + { + if ( e$flow?$src_h ) + remove_one_subnet_entry(e$flow$src_h, rule); + if ( e$flow?$dst_h ) + remove_one_subnet_entry(e$flow$dst_h, rule); + } + } + +function find_rules_subnet(sn: subnet) : vector of Rule + { + local ret: vector of Rule = vector(); + + local matches = matching_subnets(sn, rules_by_subnets); + + for ( m in matches ) + { + local sn_entry = matches[m]; + local rule_ids = rules_by_subnets[sn_entry]; + for ( rule_id in rules_by_subnets[sn_entry] ) + { + if ( rule_id in rules ) + ret[|ret|] = rules[rule_id]; + else + Reporter::error("find_rules_subnet - internal data structure error, missing rule"); + } + } + + return ret; + } + +function find_rules_addr(ip: addr) : vector of Rule + { + return find_rules_subnet(addr_to_subnet(ip)); + } + +function add_rule_impl(rule: Rule) : string + { + if ( ! plugins_active ) + { + log_rule_no_plugin(rule, FAILED, "plugins not initialized yet"); + return ""; + } + + rule$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. + + if ( ! rule?$id || rule$id == "" ) + rule$id = cat(rule$cid); + + if ( ! hook NetControl::rule_policy(rule) ) + return ""; + + if ( [rule$entity, rule$ty] in rule_entities ) + { + log_rule_no_plugin(rule, FAILED, "discarded duplicate insertion"); + return ""; + } + + local accepted = F; + local priority: int = +0; + + for ( i in plugins ) + { + local p = plugins[i]; + + if ( p$_activated == F ) + next; + + # in this case, rule was accepted by earlier plugin and this plugin has a lower + # priority. Abort and do not send there... + if ( accepted == T && p$_priority != priority ) + break; + + if ( p$plugin$add_rule(p, rule) ) + { + accepted = T; + priority = p$_priority; + log_rule(rule, "ADD", REQUESTED, p); + + add rule$_plugin_ids[p$_id]; + } + } + + if ( accepted ) + { + rules[rule$id] = rule; + rule_entities[rule$entity, rule$ty] = rule; + + add_subnet_entry(rule); + + return rule$id; + } + + log_rule_no_plugin(rule, FAILED, "not supported"); + return ""; + } + +function remove_rule_plugin(r: Rule, p: PluginState): bool + { + local success = T; + + if ( ! p$plugin$remove_rule(p, r) ) + { + # still continue and send to other plugins + log_rule_error(r, "remove failed", p); + success = F; + } + else + { + log_rule(r, "REMOVE", REQUESTED, p); + } + + return success; + } + +function remove_rule_impl(id: string) : bool + { + if ( id !in rules ) + { + Reporter::error(fmt("Rule %s does not exist in NetControl::remove_rule", id)); + return F; + } + + local r = rules[id]; + + local success = T; + for ( plugin_id in r$_active_plugin_ids ) + { + local p = plugin_ids[plugin_id]; + success = remove_rule_plugin(r, p); + } + + return success; + } + +function rule_expire_impl(r: Rule, p: PluginState) &priority=-5 + { + # do not emit timeout events on shutdown + if ( bro_is_terminating() ) + return; + + if ( r$id !in rules ) + # Removed already. + return; + + event NetControl::rule_timeout(r, FlowInfo(), p); # timeout implementation will handle the removal + } + +function rule_added_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Addition of unknown rule", p); + return; + } + + # use our version to prevent operating on copies. + local rule = rules[r$id]; + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(rule, "Rule added to non-responsible plugin", p); + return; + } + + log_rule(r, "ADD", SUCCEEDED, p, msg); + + add rule$_active_plugin_ids[p$_id]; + if ( |rule$_plugin_ids| == |rule$_active_plugin_ids| ) + { + # rule was completely added. + rule$_added = T; + } + } + +function rule_cleanup(r: Rule) + { + if ( |r$_active_plugin_ids| > 0 ) + return; + + remove_subnet_entry(r); + + delete rule_entities[r$entity, r$ty]; + delete rules[r$id]; + } + +function rule_removed_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Removal of non-existing rule", p); + return; + } + + # use our version to prevent operating on copies. + local rule = rules[r$id]; + + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Removed from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + delete rule$_active_plugin_ids[p$_id]; + } + + log_rule(rule, "REMOVE", SUCCEEDED, p, msg); + rule_cleanup(rule); + } + +function rule_timeout_impl(r: Rule, i: FlowInfo, p: PluginState) + { + if ( r$id !in rules ) + { + log_rule_error(r, "Timeout of non-existing rule", p); + return; + } + + local rule = rules[r$id]; + + local msg = ""; + if ( i?$packet_count ) + msg = fmt("Packets: %d", i$packet_count); + if ( i?$byte_count ) + { + if ( msg != "" ) + msg = msg + " "; + msg = fmt("%sBytes: %s", msg, i$byte_count); + } + + log_rule(rule, "EXPIRE", TIMEOUT, p, msg); + + if ( ! p$plugin$can_expire ) + { + # in this case, we actually have to delete the rule and the timeout + # call just originated locally + remove_rule_plugin(rule, p); + return; + } + + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Timeout from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + delete rule$_active_plugin_ids[p$_id]; + } + + rule_cleanup(rule); + } + +function rule_error_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( r$id !in rules ) + { + log_rule_error(r, "Error of non-existing rule", p); + return; + } + + local rule = rules[r$id]; + + log_rule_error(rule, msg, p); + + # Remove the plugin both from active and all plugins of the rule. If there + # are no plugins left afterwards - delete it + if ( p$_id !in rule$_plugin_ids ) + { + log_rule_error(r, "Error from non-assigned plugin", p); + return; + } + + if ( p$_id in rule$_active_plugin_ids ) + { + # error during removal. Let's pretend it worked. + delete rule$_plugin_ids[p$_id]; + delete rule$_active_plugin_ids[p$_id]; + rule_cleanup(rule); + } + else + { + # error during insertion. Meh. If we are the only plugin, remove the rule again. + # Otherwhise - keep it, minus us. + delete rule$_plugin_ids[p$_id]; + if ( |rule$_plugin_ids| == 0 ) + { + rule_cleanup(rule); + } + } + } + +function clear() + { + for ( id in rules ) + remove_rule(id); + } diff --git a/scripts/base/frameworks/netcontrol/non-cluster.bro b/scripts/base/frameworks/netcontrol/non-cluster.bro new file mode 100644 index 0000000000..4098586be4 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/non-cluster.bro @@ -0,0 +1,47 @@ +module NetControl; + +@load ./main + +function activate(p: PluginState, priority: int) + { + activate_impl(p, priority); + } + +function add_rule(r: Rule) : string + { + return add_rule_impl(r); + } + +function remove_rule(id: string) : bool + { + return remove_rule_impl(id); + } + +event rule_expire(r: Rule, p: PluginState) &priority=-5 + { + rule_expire_impl(r, p); + } + +event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 + { + rule_added_impl(r, p, msg); + + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) + schedule r$expire { rule_expire(r, p) }; + } + +event rule_removed(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_removed_impl(r, p, msg); + } + +event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) &priority=-5 + { + rule_timeout_impl(r, i, p); + } + +event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 + { + rule_error_impl(r, p, msg); + } + diff --git a/scripts/base/frameworks/netcontrol/plugin.bro b/scripts/base/frameworks/netcontrol/plugin.bro new file mode 100644 index 0000000000..7d0ee13a81 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugin.bro @@ -0,0 +1,89 @@ +##! Plugin interface for NetControl backends. + +module NetControl; + +@load ./types + +export { + ## State for a plugin instance. + type PluginState: record { + ## Table for a plugin to store custom, instance-specfific state. + config: table[string] of string &default=table(); + + ## Unique plugin identifier -- used for backlookup of plugins from Rules. Set internally. + _id: count &optional; + + ## Set internally. + _priority: int &default=+0; + + ## Set internally. Signifies if the plugin has returned that it has activated succesfully + _activated: bool &default=F; + }; + + # Definition of a plugin. + # + # Generally a plugin needs to implement only what it can support. By + # returning failure, it indicates that it can't support something and the + # the framework will then try another plugin, if available; or inform the + # that the operation failed. If a function isn't implemented by a plugin, + # that's considered an implicit failure to support the operation. + # + # If plugin accepts a rule operation, it *must* generate one of the reporting + # events ``rule_{added,remove,error}`` to signal if it indeed worked out; + # this is separate from accepting the operation because often a plugin + # will only know later (i.e., asynchrously) if that was an error for + # something it thought it could handle. + type Plugin: record { + # Returns a descriptive name of the plugin instance, suitable for use in logging + # messages. Note that this function is not optional. + name: function(state: PluginState) : string; + + ## If true, plugin can expire rules itself. If false, + ## framework will manage rule expiration. + can_expire: bool; + + # One-time initialization function called when plugin gets registered, and + # before any other methods are called. + # + # If this function is provided, NetControl assumes that the plugin has to + # perform, potentially lengthy, initialization before the plugin will become + # active. In this case, the plugin has to call ``NetControl::plugin_activated``, + # once initialization finishes. + init: function(state: PluginState) &optional; + + # One-time finalization function called when a plugin is shutdown; no further + # functions will be called afterwords. + done: function(state: PluginState) &optional; + + # Implements the add_rule() operation. If the plugin accepts the rule, + # it returns true, false otherwise. The rule will already have its + # ``id`` field set, which the plugin may use for identification + # purposes. + add_rule: function(state: PluginState, r: Rule) : bool &optional; + + # Implements the remove_rule() operation. This will only be called for + # rules that the plugins has previously accepted with add_rule(). The + # ``id`` field will match that of the add_rule() call. Generally, + # a plugin that accepts an add_rule() should also accept the + # remove_rule(). + remove_rule: function(state: PluginState, r: Rule) : bool &optional; + + # A transaction groups a number of operations. The plugin can add them internally + # and postpone putting them into effect until committed. This allows to build a + # configuration of multiple rules at once, including replaying a previous state. + transaction_begin: function(state: PluginState) &optional; + transaction_end: function(state: PluginState) &optional; + }; + + # Table for a plugin to store instance-specific configuration information. + # + # Note, it would be nicer to pass the Plugin instance to all the below, instead + # of this state table. However Bro's type resolver has trouble with refering to a + # record type from inside itself. + redef record PluginState += { + ## The plugin that the state belongs to. (Defined separately + ## because of cyclic type dependency.) + plugin: Plugin &optional; + }; + +} diff --git a/scripts/base/frameworks/netcontrol/plugins/__load__.bro b/scripts/base/frameworks/netcontrol/plugins/__load__.bro new file mode 100644 index 0000000000..255cee5f69 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/__load__.bro @@ -0,0 +1,5 @@ +@load ./debug +@load ./openflow +@load ./packetfilter +@load ./broker +@load ./acld diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro new file mode 100644 index 0000000000..76661bc857 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -0,0 +1,294 @@ +##! Acld plugin for the netcontrol framework. + +module NetControl; + +@load ../main +@load ../plugin +@load base/frameworks/broker + +export { + type AclRule : record { + command: string; + cookie: count; + arg: string; + comment: string &optional; + }; + + type AcldConfig: record { + ## The acld topic used to send events to + acld_topic: string; + ## Broker host to connect to + acld_host: addr; + ## Broker port to connect to + acld_port: port; + ## Do we accept rules for the monitor path? Default false + monitor: bool &default=F; + ## Do we accept rules for the forward path? Default true + forward: bool &default=T; + + ## Predicate that is called on rule insertion or removal. + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## Returns: T if the rule can be handled by the current backend, F otherwhise + check_pred: function(p: PluginState, r: Rule): bool &optional; + }; + + ## Instantiates the acld plugin. + global create_acld: function(config: AcldConfig) : PluginState; + + redef record PluginState += { + acld_config: AcldConfig &optional; + ## The ID of this acld instance - for the mapping to PluginStates + acld_id: count &optional; + }; + + ## Hook that is called after a rule is converted to an acld rule. + ## The hook may modify the rule before it is sent to acld. + ## Setting the acld command to F will cause the rule to be rejected + ## by the plugin + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## ar: The acld rule to be inserted or removed + global NetControl::acld_rule_policy: hook(p: PluginState, r: Rule, ar: AclRule); + + ## Events that are sent from us to Broker + global acld_add_rule: event(id: count, r: Rule, ar: AclRule); + global acld_remove_rule: event(id: count, r: Rule, ar: AclRule); + + ## Events that are sent from Broker to us + global acld_rule_added: event(id: count, r: Rule, msg: string); + global acld_rule_removed: event(id: count, r: Rule, msg: string); + global acld_rule_error: event(id: count, r: Rule, msg: string); +} + +global netcontrol_acld_peers: table[port, string] of PluginState; +global netcontrol_acld_topics: set[string] = set(); +global netcontrol_acld_id: table[count] of PluginState = table(); +global netcontrol_acld_current_id: count = 0; + +const acld_add_to_remove: table[string] of string = { + ["drop"] = "restore", + ["whitelist"] = "remwhitelist", + ["blockhosthost"] = "restorehosthost", + ["droptcpport"] = "restoretcpport", + ["dropudpport"] = "restoreudpport", + ["droptcpdsthostport"] ="restoretcpdsthostport", + ["dropudpdsthostport"] ="restoreudpdsthostport", + ["permittcpdsthostport"] ="unpermittcpdsthostport", + ["permitudpdsthostport"] ="unpermitudpdsthostport", + ["nullzero"] ="nonullzero" +}; + +event NetControl::acld_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_added(r, p, msg); + } + +event NetControl::acld_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_removed(r, p, msg); + } + +event NetControl::acld_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_acld_id ) + { + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_acld_id[id]; + + event NetControl::rule_error(r, p, msg); + } + +function acld_name(p: PluginState) : string + { + return fmt("Acld-%s", p$acld_config$acld_topic); + } + +# check that subnet specifies an addr +function check_sn(sn: subnet) : bool + { + if ( is_v4_subnet(sn) && subnet_width(sn) == 32 ) + return T; + if ( is_v6_subnet(sn) && subnet_width(sn) == 128 ) + return T; + + Reporter::error(fmt("Acld: rule_to_acl_rule was given a subnet that does not specify a distinct address where needed - %s", sn)); + return F; + } + +function rule_to_acl_rule(p: PluginState, r: Rule) : AclRule + { + local e = r$entity; + + local command: string = ""; + local arg: string = ""; + + if ( e$ty == ADDRESS ) + { + if ( r$ty == DROP ) + command = "drop"; + else if ( r$ty == WHITELIST ) + command = "whitelist"; + arg = cat(e$ip); + } + else if ( e$ty == FLOW ) + { + local f = e$flow; + if ( ( ! f?$src_h ) && ( ! f?$src_p ) && f?$dst_h && f?$dst_p && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( !check_sn(f$dst_h) ) + command = ""; # invalid addr, do nothing + else if ( is_tcp_port(f$dst_p) && r$ty == DROP ) + command = "droptcpdsthostport"; + else if ( is_tcp_port(f$dst_p) && r$ty == WHITELIST ) + command = "permittcpdsthostport"; + else if ( is_udp_port(f$dst_p) && r$ty == DROP) + command = "dropucpdsthostport"; + else if ( is_udp_port(f$dst_p) && r$ty == WHITELIST) + command = "permitucpdsthostport"; + + arg = fmt("%s %d", subnet_to_addr(f$dst_h), f$dst_p); + } + else if ( f?$src_h && ( ! f?$src_p ) && f?$dst_h && ( ! f?$dst_p ) && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( !check_sn(f$src_h) || !check_sn(f$dst_h) ) + command = ""; + else if ( r$ty == DROP ) + command = "blockhosthost"; + arg = fmt("%s %s", subnet_to_addr(f$src_h), subnet_to_addr(f$dst_h)); + } + else if ( ( ! f?$src_h ) && ( ! f?$src_p ) && ( ! f?$dst_h ) && f?$dst_p && ( ! f?$src_m ) && ( ! f?$dst_m ) ) + { + if ( is_tcp_port(f$dst_p) && r$ty == DROP ) + command = "droptcpport"; + else if ( is_udp_port(f$dst_p) && r$ty == DROP ) + command = "dropudpport"; + arg = fmt("%d", f$dst_p); + } + } + + local ar = AclRule($command=command, $cookie=r$cid, $arg=arg); + if ( r?$location ) + ar$comment = r$location; + + hook NetControl::acld_rule_policy(p, r, ar); + + return ar; + } + +function acld_check_rule(p: PluginState, r: Rule) : bool + { + local c = p$acld_config; + + if ( p$acld_config?$check_pred ) + return p$acld_config$check_pred(p, r); + + if ( r$target == MONITOR && c$monitor ) + return T; + + if ( r$target == FORWARD && c$forward ) + return T; + + return F; + } + +function acld_add_rule_fun(p: PluginState, r: Rule) : bool + { + if ( ! acld_check_rule(p, r) ) + return F; + + local ar = rule_to_acl_rule(p, r); + + if ( ar$command == "" ) + return F; + + BrokerComm::event(p$acld_config$acld_topic, BrokerComm::event_args(acld_add_rule, p$acld_id, r, ar)); + return T; + } + +function acld_remove_rule_fun(p: PluginState, r: Rule) : bool + { + if ( ! acld_check_rule(p, r) ) + return F; + + local ar = rule_to_acl_rule(p, r); + if ( ar$command in acld_add_to_remove ) + ar$command = acld_add_to_remove[ar$command]; + else + return F; + + BrokerComm::event(p$acld_config$acld_topic, BrokerComm::event_args(acld_remove_rule, p$acld_id, r, ar)); + return T; + } + +function acld_init(p: PluginState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(p$acld_config$acld_host), p$acld_config$acld_port, 1sec); + BrokerComm::subscribe_to_events(p$acld_config$acld_topic); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in netcontrol_acld_peers ) + # ok, this one was none of ours... + return; + + local p = netcontrol_acld_peers[peer_port, peer_address]; + plugin_activated(p); + } + +global acld_plugin = Plugin( + $name=acld_name, + $can_expire = F, + $add_rule = acld_add_rule_fun, + $remove_rule = acld_remove_rule_fun, + $init = acld_init + ); + +function create_acld(config: AcldConfig) : PluginState + { + if ( config$acld_topic in netcontrol_acld_topics ) + Reporter::warning(fmt("Topic %s was added to NetControl acld plugin twice. Possible duplication of commands", config$acld_topic)); + else + add netcontrol_acld_topics[config$acld_topic]; + + local host = cat(config$acld_host); + local p: PluginState = [$acld_config=config, $plugin=acld_plugin, $acld_id=netcontrol_acld_current_id]; + + if ( [config$acld_port, host] in netcontrol_acld_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl acld plugin twice.", host, config$acld_port)); + else + netcontrol_acld_peers[config$acld_port, host] = p; + + netcontrol_acld_id[netcontrol_acld_current_id] = p; + ++netcontrol_acld_current_id; + + return p; + } + diff --git a/scripts/base/frameworks/netcontrol/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro new file mode 100644 index 0000000000..619b6b607b --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -0,0 +1,163 @@ +##! Broker plugin for the netcontrol framework. Sends the raw data structures +##! used in NetControl on to Broker to allow for easy handling, e.g., of +##! command-line scripts. + +module NetControl; + +@load ../main +@load ../plugin +@load base/frameworks/broker + +export { + ## Instantiates the broker plugin. + global create_broker: function(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState; + + redef record PluginState += { + ## The broker topic used to send events to + broker_topic: string &optional; + ## The ID of this broker instance - for the mapping to PluginStates + broker_id: count &optional; + ## Broker host to connect to + broker_host: addr &optional; + ## Broker port to connect to + broker_port: port &optional; + }; + + global broker_add_rule: event(id: count, r: Rule); + global broker_remove_rule: event(id: count, r: Rule); + + global broker_rule_added: event(id: count, r: Rule, msg: string); + global broker_rule_removed: event(id: count, r: Rule, msg: string); + global broker_rule_error: event(id: count, r: Rule, msg: string); + global broker_rule_timeout: event(id: count, r: Rule, i: FlowInfo); +} + +global netcontrol_broker_peers: table[port, string] of PluginState; +global netcontrol_broker_topics: set[string] = set(); +global netcontrol_broker_id: table[count] of PluginState = table(); +global netcontrol_broker_current_id: count = 0; + +event NetControl::broker_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_added(r, p, msg); + } + +event NetControl::broker_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_removed(r, p, msg); + } + +event NetControl::broker_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_error(r, p, msg); + } + +event NetControl::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) + { + if ( id !in netcontrol_broker_id ) + { + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); + return; + } + + local p = netcontrol_broker_id[id]; + + event NetControl::rule_timeout(r, i, p); + } + +function broker_name(p: PluginState) : string + { + return fmt("Broker-%s", p$broker_topic); + } + +function broker_add_rule_fun(p: PluginState, r: Rule) : bool + { + BrokerComm::event(p$broker_topic, BrokerComm::event_args(broker_add_rule, p$broker_id, r)); + return T; + } + +function broker_remove_rule_fun(p: PluginState, r: Rule) : bool + { + BrokerComm::event(p$broker_topic, BrokerComm::event_args(broker_remove_rule, p$broker_id, r)); + return T; + } + +function broker_init(p: PluginState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(p$broker_host), p$broker_port, 1sec); + BrokerComm::subscribe_to_events(p$broker_topic); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in netcontrol_broker_peers ) + return; + + local p = netcontrol_broker_peers[peer_port, peer_address]; + plugin_activated(p); + } + +global broker_plugin = Plugin( + $name=broker_name, + $can_expire = F, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun, + $init = broker_init + ); + +global broker_plugin_can_expire = Plugin( + $name=broker_name, + $can_expire = T, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun, + $init = broker_init + ); + +function create_broker(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState + { + if ( topic in netcontrol_broker_topics ) + Reporter::warning(fmt("Topic %s was added to NetControl broker plugin twice. Possible duplication of commands", topic)); + else + add netcontrol_broker_topics[topic]; + + local plugin = broker_plugin; + if ( can_expire ) + plugin = broker_plugin_can_expire; + + local p: PluginState = [$broker_host=host, $broker_port=host_port, $plugin=plugin, $broker_topic=topic, $broker_id=netcontrol_broker_current_id]; + + if ( [host_port, cat(host)] in netcontrol_broker_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl broker plugin twice.", host, host_port)); + else + netcontrol_broker_peers[host_port, cat(host)] = p; + + netcontrol_broker_id[netcontrol_broker_current_id] = p; + ++netcontrol_broker_current_id; + + return p; + } diff --git a/scripts/base/frameworks/netcontrol/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro new file mode 100644 index 0000000000..f421dc55e3 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -0,0 +1,99 @@ +##! Debugging plugin for the NetControl framework, providing insight into +##! executed operations. + +@load ../plugin +@load ../main + +module NetControl; + +export { + ## Instantiates a debug plugin for the NetControl framework. The debug + ## plugin simply logs the operations it receives. + ## + ## do_something: If true, the plugin will claim it supports all operations; if + ## false, it will indicate it doesn't support any. + global create_debug: function(do_something: bool) : PluginState; +} + +function do_something(p: PluginState) : bool + { + return p$config["all"] == "1"; + } + +function debug_name(p: PluginState) : string + { + return fmt("Debug-%s", (do_something(p) ? "All" : "None")); + } + +function debug_log(p: PluginState, msg: string) + { + print fmt("netcontrol debug (%s): %s", debug_name(p), msg); + } + +function debug_init(p: PluginState) + { + debug_log(p, "init"); + plugin_activated(p); + } + +function debug_done(p: PluginState) + { + debug_log(p, "init"); + } + +function debug_add_rule(p: PluginState, r: Rule) : bool + { + local s = fmt("add_rule: %s", r); + debug_log(p, s); + + if ( do_something(p) ) + { + event NetControl::rule_added(r, p); + return T; + } + + return F; + } + +function debug_remove_rule(p: PluginState, r: Rule) : bool + { + local s = fmt("remove_rule: %s", r); + debug_log(p, s); + + event NetControl::rule_removed(r, p); + return T; + } + +function debug_transaction_begin(p: PluginState) + { + debug_log(p, "transaction_begin"); + } + +function debug_transaction_end(p: PluginState) + { + debug_log(p, "transaction_end"); + } + +global debug_plugin = Plugin( + $name=debug_name, + $can_expire = F, + $init = debug_init, + $done = debug_done, + $add_rule = debug_add_rule, + $remove_rule = debug_remove_rule, + $transaction_begin = debug_transaction_begin, + $transaction_end = debug_transaction_end + ); + +function create_debug(do_something: bool) : PluginState + { + local p: PluginState = [$plugin=debug_plugin]; + + # FIXME: Why's the default not working? + p$config = table(); + p$config["all"] = (do_something ? "1" : "0"); + + return p; + } + + diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro new file mode 100644 index 0000000000..44a8bb2f1a --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -0,0 +1,432 @@ +##! OpenFlow plugin for the NetControl framework. + +@load ../main +@load ../plugin +@load base/frameworks/openflow + +module NetControl; + +export { + type OfConfig: record { + monitor: bool &default=T; + forward: bool &default=T; + idle_timeout: count &default=0; + table_id: count &optional; + priority_offset: int &default=+0; ##< add this to all rule priorities. Can be useful if you want the openflow priorities be offset from the netcontrol priorities without having to write a filter function. + + ## Predicate that is called on rule insertion or removal. + ## + ## p: Current plugin state + ## + ## r: The rule to be inserted or removed + ## + ## Returns: T if the rule can be handled by the current backend, F otherwhise + check_pred: function(p: PluginState, r: Rule): bool &optional; + match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional; + flow_mod_pred: function(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod &optional; + }; + + redef record PluginState += { + ## OpenFlow controller for NetControl OpenFlow plugin + of_controller: OpenFlow::Controller &optional; + ## OpenFlow configuration record that is passed on initialization + of_config: OfConfig &optional; + }; + + type OfTable: record { + p: PluginState; + r: Rule; + c: count &default=0; # how many replies did we see so far? needed for ids where we have multiple rules... + packet_count: count &default=0; + byte_count: count &default=0; + duration_sec: double &default=0.0; + }; + + ## the time interval after which an openflow message is considered to be timed out + ## and we delete it from our internal tracking. + const openflow_message_timeout = 20secs &redef; + + ## the time interval after we consider a flow timed out. This should be fairly high (or + ## even disabled) if you expect a lot of long flows. However, one also will have state + ## buildup for quite a while if keeping this around... + const openflow_flow_timeout = 24hrs &redef; + + ## Instantiates an openflow plugin for the NetControl framework. + global create_openflow: function(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState; +} + +global of_messages: table[count, OpenFlow::ofp_flow_mod_command] of OfTable &create_expire=openflow_message_timeout + &expire_func=function(t: table[count, OpenFlow::ofp_flow_mod_command] of OfTable, idx: any): interval + { + local rid: count; + local command: OpenFlow::ofp_flow_mod_command; + [rid, command] = idx; + + local p = t[rid, command]$p; + local r = t[rid, command]$r; + event NetControl::rule_error(r, p, "Timeout during rule insertion/removal"); + return 0secs; + }; + +global of_flows: table[count] of OfTable &create_expire=openflow_flow_timeout; +global of_instances: table[string] of PluginState; + +function openflow_name(p: PluginState) : string + { + return fmt("Openflow-%s", p$of_controller$describe(p$of_controller$state)); + } + +function openflow_check_rule(p: PluginState, r: Rule) : bool + { + local c = p$of_config; + + if ( p$of_config?$check_pred ) + return p$of_config$check_pred(p, r); + + if ( r$target == MONITOR && c$monitor ) + return T; + + if ( r$target == FORWARD && c$forward ) + return T; + + return F; + } + +function openflow_match_pred(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match) : vector of OpenFlow::ofp_match + { + if ( p$of_config?$match_pred ) + return p$of_config$match_pred(p, e, m); + + return m; + } + +function openflow_flow_mod_pred(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod + { + if ( p$of_config?$flow_mod_pred ) + return p$of_config$flow_mod_pred(p, r, m); + + return m; + } + +function determine_dl_type(s: subnet): count + { + local pdl = OpenFlow::ETH_IPv4; + if ( is_v6_subnet(s) ) + pdl = OpenFlow::ETH_IPv6; + + return pdl; + } + +function determine_proto(p: port): count + { + local proto = OpenFlow::IP_TCP; + if ( is_udp_port(p) ) + proto = OpenFlow::IP_UDP; + else if ( is_icmp_port(p) ) + proto = OpenFlow::IP_ICMP; + + return proto; + } + +function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_match + { + local v : vector of OpenFlow::ofp_match = vector(); + + if ( e$ty == CONNECTION ) + { + v[|v|] = OpenFlow::match_conn(e$conn); # forward and... + v[|v|] = OpenFlow::match_conn(e$conn, T); # reverse + return openflow_match_pred(p, e, v); + } + + if ( e$ty == MAC ) + { + v[|v|] = OpenFlow::ofp_match( + $dl_src=e$mac + ); + v[|v|] = OpenFlow::ofp_match( + $dl_dst=e$mac + ); + + return openflow_match_pred(p, e, v); + } + + local dl_type = OpenFlow::ETH_IPv4; + + if ( e$ty == ADDRESS ) + { + if ( is_v6_subnet(e$ip) ) + dl_type = OpenFlow::ETH_IPv6; + + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_src=e$ip + ); + + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_dst=e$ip + ); + + return openflow_match_pred(p, e, v); + } + + local proto = OpenFlow::IP_TCP; + + if ( e$ty == FLOW ) + { + local m = OpenFlow::ofp_match(); + local f = e$flow; + + if ( f?$src_m ) + m$dl_src=f$src_m; + if ( f?$dst_m ) + m$dl_dst=f$dst_m; + + if ( f?$src_h ) + { + m$dl_type = determine_dl_type(f$src_h); + m$nw_src = f$src_h; + } + + if ( f?$dst_h ) + { + m$dl_type = determine_dl_type(f$dst_h); + m$nw_dst = f$dst_h; + } + + if ( f?$src_p ) + { + m$nw_proto = determine_proto(f$src_p); + m$tp_src = port_to_count(f$src_p); + } + + if ( f?$dst_p ) + { + m$nw_proto = determine_proto(f$dst_p); + m$tp_dst = port_to_count(f$dst_p); + } + + v[|v|] = m; + + return openflow_match_pred(p, e, v); + } + + Reporter::error(fmt("Entity type %s not supported for openflow yet", cat(e$ty))); + return openflow_match_pred(p, e, v); + } + +function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow_mod + { + local c = p$of_config; + + local flow_mod = OpenFlow::ofp_flow_mod( + $cookie=OpenFlow::generate_cookie(r$cid*2), # leave one space for the cases in which we need two rules. + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=c$idle_timeout, + $priority=int_to_count(r$priority + c$priority_offset), + $flags=OpenFlow::OFPFF_SEND_FLOW_REM # please notify us when flows are removed + ); + + if ( r?$expire ) + flow_mod$hard_timeout = double_to_count(interval_to_double(r$expire)); + if ( c?$table_id ) + flow_mod$table_id = c$table_id; + + if ( r$ty == DROP ) + { + # default, nothing to do. We simply do not add an output port to the rule... + } + else if ( r$ty == WHITELIST ) + { + # at the moment our interpretation of whitelist is to hand this off to the switches L2/L3 routing. + flow_mod$actions$out_ports = vector(OpenFlow::OFPP_NORMAL); + } + else if ( r$ty == MODIFY ) + { + # if no ports are given, just assume normal pipeline... + flow_mod$actions$out_ports = vector(OpenFlow::OFPP_NORMAL); + + local mod = r$mod; + if ( mod?$redirect_port ) + flow_mod$actions$out_ports = vector(mod$redirect_port); + + if ( mod?$src_h ) + flow_mod$actions$nw_src = mod$src_h; + if ( mod?$dst_h ) + flow_mod$actions$nw_dst = mod$dst_h; + if ( mod?$src_m ) + flow_mod$actions$dl_src = mod$src_m; + if ( mod?$dst_m ) + flow_mod$actions$dl_dst = mod$dst_m; + if ( mod?$src_p ) + flow_mod$actions$tp_src = mod$src_p; + if ( mod?$dst_p ) + flow_mod$actions$tp_dst = mod$dst_p; + } + else if ( r$ty == REDIRECT ) + { + # redirect to port c + flow_mod$actions$out_ports = vector(r$out_port); + } + else + { + Reporter::error(fmt("Rule type %s not supported for openflow yet", cat(r$ty))); + } + + return openflow_flow_mod_pred(p, r, flow_mod); + } + +function openflow_add_rule(p: PluginState, r: Rule) : bool + { + if ( ! openflow_check_rule(p, r) ) + return F; + + local flow_mod = openflow_rule_to_flow_mod(p, r); + local matches = entity_to_match(p, r$entity); + + for ( i in matches ) + { + if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + { + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); + flow_mod = copy(flow_mod); + ++flow_mod$cookie; + } + else + event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); + } + + return T; + } + +function openflow_remove_rule(p: PluginState, r: Rule) : bool + { + if ( ! openflow_check_rule(p, r) ) + return F; + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(r$cid*2), + $command=OpenFlow::OFPFC_DELETE + ]; + + if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); + else + { + event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); + return F; + } + + # if this was an address or mac match, we also need to remove the reverse + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + local flow_mod_2 = copy(flow_mod); + ++flow_mod_2$cookie; + OpenFlow::flow_mod(p$of_controller, [], flow_mod_2); + } + + return T; + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; + if ( [id, flow_mod$command] !in of_messages ) + return; + + local r = of_messages[id,flow_mod$command]$r; + local p = of_messages[id,flow_mod$command]$p; + local c = of_messages[id,flow_mod$command]$c; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_messages[id,flow_mod$command]$c; + if ( of_messages[id,flow_mod$command]$c < 2 ) + return; # will do stuff once the second part arrives... + } + + delete of_messages[id,flow_mod$command]; + + if ( p$of_controller$supports_flow_removed ) + of_flows[id] = OfTable($p=p, $r=r); + + if ( flow_mod$command == OpenFlow::OFPFC_ADD ) + event NetControl::rule_added(r, p, msg); + else if ( flow_mod$command == OpenFlow::OFPFC_DELETE || flow_mod$command == OpenFlow::OFPFC_DELETE_STRICT ) + event NetControl::rule_removed(r, p, msg); + } + +event OpenFlow::flow_mod_failure(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; + if ( [id, flow_mod$command] !in of_messages ) + return; + + local r = of_messages[id,flow_mod$command]$r; + local p = of_messages[id,flow_mod$command]$p; + delete of_messages[id,flow_mod$command]; + + event NetControl::rule_error(r, p, msg); + } + +event OpenFlow::flow_removed(name: string, match: OpenFlow::ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count) + { + local id = OpenFlow::get_cookie_uid(cookie)/2; + if ( id !in of_flows ) + return; + + local rec = of_flows[id]; + local r = rec$r; + local p = rec$p; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_flows[id]$c; + if ( of_flows[id]$c < 2 ) + return; # will do stuff once the second part arrives... + else + event NetControl::rule_timeout(r, FlowInfo($duration=double_to_interval((rec$duration_sec+duration_sec)/2), $packet_count=packet_count+rec$packet_count, $byte_count=byte_count+rec$byte_count), p); + + return; + } + + event NetControl::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); + } + +function openflow_init(p: PluginState) + { + local name = p$of_controller$state$_name; + if ( name in of_instances ) + Reporter::error(fmt("OpenFlow instance %s added to NetControl twice.", name)); + + of_instances[name] = p; + + # let's check, if our OpenFlow controller is already active. If not, we have to wait for it to become active. + if ( p$of_controller$state$_activated ) + plugin_activated(p); + } + +event OpenFlow::controller_activated(name: string, controller: OpenFlow::Controller) + { + if ( name in of_instances ) + plugin_activated(of_instances[name]); + } + +global openflow_plugin = Plugin( + $name=openflow_name, + $can_expire = T, + $init = openflow_init, +# $done = openflow_done, + $add_rule = openflow_add_rule, + $remove_rule = openflow_remove_rule +# $transaction_begin = openflow_transaction_begin, +# $transaction_end = openflow_transaction_end + ); + +function create_openflow(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState + { + local p: PluginState = [$plugin=openflow_plugin, $of_controller=controller, $of_config=config]; + + return p; + } diff --git a/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro new file mode 100644 index 0000000000..437c08eb73 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro @@ -0,0 +1,113 @@ +##! NetControl plugin for the process-level PacketFilter that comes with +##! Bro. Since the PacketFilter in Bro is quite limited in scope +##! and can only add/remove filters for addresses, this is quite +##! limited in scope at the moment. + +module NetControl; + +@load ../plugin + +export { + ## Instantiates the packetfilter plugin. + global create_packetfilter: function() : PluginState; +} + +# Check if we can handle this rule. If it specifies ports or +# anything Bro cannot handle, simply ignore it for now. +function packetfilter_check_rule(r: Rule) : bool + { + if ( r$ty != DROP ) + return F; + + if ( r$target != MONITOR ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + return T; + + if ( e$ty != FLOW ) # everything else requires ports or MAC stuff + return F; + + if ( e$flow?$src_p || e$flow?$dst_p || e$flow?$src_m || e$flow?$dst_m ) + return F; + + return T; + } + + +function packetfilter_add_rule(p: PluginState, r: Rule) : bool + { + if ( ! packetfilter_check_rule(r) ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + { + install_src_net_filter(e$ip, 0, 1.0); + install_dst_net_filter(e$ip, 0, 1.0); + return T; + } + + if ( e$ty == FLOW ) + { + local f = e$flow; + if ( f?$src_h ) + install_src_net_filter(f$src_h, 0, 1.0); + if ( f?$dst_h ) + install_dst_net_filter(f$dst_h, 0, 1.0); + + return T; + } + + return F; + } + +function packetfilter_remove_rule(p: PluginState, r: Rule) : bool + { + if ( ! packetfilter_check_rule(r) ) + return F; + + local e = r$entity; + if ( e$ty == ADDRESS ) + { + uninstall_src_net_filter(e$ip); + uninstall_dst_net_filter(e$ip); + return T; + } + + if ( e$ty == FLOW ) + { + local f = e$flow; + if ( f?$src_h ) + uninstall_src_net_filter(f$src_h); + if ( f?$dst_h ) + uninstall_dst_net_filter(f$dst_h); + + return T; + } + + return F; + } + +function packetfilter_name(p: PluginState) : string + { + return "Packetfilter"; + } + +global packetfilter_plugin = Plugin( + $name=packetfilter_name, + $can_expire = F, +# $init = packetfilter_init, +# $done = packetfilter_done, + $add_rule = packetfilter_add_rule, + $remove_rule = packetfilter_remove_rule + ); + +function create_packetfilter() : PluginState + { + local p: PluginState = [$plugin=packetfilter_plugin]; + + return p; + } + diff --git a/scripts/base/frameworks/netcontrol/shunt.bro b/scripts/base/frameworks/netcontrol/shunt.bro new file mode 100644 index 0000000000..e1a5715582 --- /dev/null +++ b/scripts/base/frameworks/netcontrol/shunt.bro @@ -0,0 +1,69 @@ +##! Implementation of the shunt functionality for NetControl. + +module NetControl; + +@load ./main + +export { + redef enum Log::ID += { SHUNT }; + + ## Stops forwarding a uni-directional flow's packets to Bro. + ## + ## f: The flow to shunt. + ## + ## t: How long to leave the shunt in place, with 0 being indefinitly. + ## + ## location: An optional string describing where the shunt was triggered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : string; + + type ShuntInfo: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## ID of the rule; unique during each Bro run + rule_id: string &log; + ## Flow ID of the shunted flow + f: flow_id &log; + ## Expiry time of the shunt + expire: interval &log; + ## Location where the underlying action was triggered. + location: string &log &optional; + }; + + ## Event that can be handled to access the :bro:type:`NetControl::ShuntInfo` + ## record as it is sent on to the logging framework. + global log_netcontrol_shunt: event(rec: ShuntInfo); +} + +event bro_init() &priority=5 + { + Log::create_stream(NetControl::SHUNT, [$columns=ShuntInfo, $ev=log_netcontrol_shunt, $path="netcontrol_shunt"]); + } + +function shunt_flow(f: flow_id, t: interval, location: string &default="") : string + { + local flow = NetControl::Flow( + $src_h=addr_to_subnet(f$src_h), + $src_p=f$src_p, + $dst_h=addr_to_subnet(f$dst_h), + $dst_p=f$dst_p + ); + local e: Entity = [$ty=FLOW, $flow=flow]; + local r: Rule = [$ty=DROP, $target=MONITOR, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + + # Error should already be logged + if ( id == "" ) + return id; + + local log = ShuntInfo($ts=network_time(), $rule_id=id, $f=f, $expire=t); + if ( location != "" ) + log$location=location; + + Log::write(SHUNT, log); + + return id; + } + diff --git a/scripts/base/frameworks/netcontrol/types.bro b/scripts/base/frameworks/netcontrol/types.bro new file mode 100644 index 0000000000..440d63d8bc --- /dev/null +++ b/scripts/base/frameworks/netcontrol/types.bro @@ -0,0 +1,109 @@ +##! Types used by the NetControl framework. + +module NetControl; + +export { + const default_priority: int = +0 &redef; + const whitelist_priority: int = +5 &redef; + + ## Type of a :bro:id:`Entity` for defining an action. + type EntityType: enum { + ADDRESS, ##< Activity involving a specific IP address. + CONNECTION, ##< All of a bi-directional connection's activity. + FLOW, ##< All of a uni-directional flow's activity. Can contain wildcards. + MAC, ##< Activity involving a MAC address. + }; + + ## Type of a :bro:id:`Flow` for defining a flow. + type Flow: record { + src_h: subnet &optional; ##< The source IP address/subnet. + src_p: port &optional; ##< The source port number. + dst_h: subnet &optional; ##< The destination IP address/subnet. + dst_p: port &optional; ##< The desintation port number. + src_m: string &optional; ##< The source MAC address. + dst_m: string &optional; ##< The destination MAC address. + }; + + ## Type defining the enity an :bro:id:`Rule` is operating on. + type Entity: record { + ty: EntityType; ##< Type of entity. + conn: conn_id &optional; ##< Used with :bro:id:`CONNECTION` . + flow: Flow &optional; ##< Used with :bro:id:`FLOW` . + ip: subnet &optional; ##< Used with bro:id:`ADDRESS`; can specifiy a CIDR subnet. + mac: string &optional; ##< Used with :bro:id:`MAC`. + }; + + ## Target of :bro:id:`Rule` action. + type TargetType: enum { + FORWARD, #< Apply rule actively to traffic on forwarding path. + MONITOR, #< Apply rule passively to traffic sent to Bro for monitoring. + }; + + ## Type of rules that the framework supports. Each type lists the + ## :bro:id:`Rule` argument(s) it uses, if any. + ## + ## Plugins may extend this type to define their own. + type RuleType: enum { + ## Stop forwarding all packets matching entity. + ## + ## No arguments. + DROP, + + ## Begin modifying all packets matching entity. + ## + ## .. todo:: + ## Define arguments. + MODIFY, + + ## Begin redirecting all packets matching entity. + ## + ## .. todo:: + ## c: output port to redirect traffic to. + REDIRECT, + + ## Whitelists all packets of an entity, meaning no restrictions will be applied. + ## While whitelisting is the default if no rule matches an this can type can be + ## used to override lower-priority rules that would otherwise take effect for the + ## entity. + WHITELIST, + }; + + ## Type of a :bro:id:`FlowMod` for defining a flow modification action. + type FlowMod: record { + src_h: addr &optional; ##< The source IP address. + src_p: count &optional; ##< The source port number. + dst_h: addr &optional; ##< The destination IP address. + dst_p: count &optional; ##< The desintation port number. + src_m: string &optional; ##< The source MAC address. + dst_m: string &optional; ##< The destination MAC address. + redirect_port: count &optional; + }; + + ## A rule for the framework to put in place. Of all rules currently in + ## place, the first match will be taken, sorted by priority. All + ## further rules will be ignored. + type Rule: record { + ty: RuleType; ##< Type of rule. + target: TargetType; ##< Where to apply rule. + entity: Entity; ##< Entity to apply rule to. + expire: interval &optional; ##< Timeout after which to expire the rule. + priority: int &default=default_priority; ##< Priority if multiple rules match an entity (larger value is higher priority). + location: string &optional; ##< Optional string describing where/what installed the rule. + + out_port: count &optional; ##< Argument for bro:id:`REDIRECT` rules. + mod: FlowMod &optional; ##< Argument for :bro:id:`MODIFY` rules. + + id: string &default=""; ##< Internally determined unique ID for this rule. Will be set when added. + cid: count &default=0; ##< Internally determined unique numeric ID for this rule. Set when added. + }; + + ## Information of a flow that can be provided by switches when the flow times out. + ## Currently this is heavily influenced by the data that OpenFlow returns by default. + ## That being said - their design makes sense and this is probably the data one + ## can expect to be available. + type FlowInfo: record { + duration: interval &optional; ##< total duration of the rule + packet_count: count &optional; ##< number of packets exchanged over connections matched by the rule + byte_count: count &optional; ##< total bytes exchanged over connections matched by the rule + }; +} diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro new file mode 100644 index 0000000000..bd9128b5aa --- /dev/null +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -0,0 +1,13 @@ +@load ./consts +@load ./types +@load ./main +@load ./plugins + +# The cluster framework must be loaded first. +@load base/frameworks/cluster + +@if ( Cluster::is_enabled() ) +@load ./cluster +@else +@load ./non-cluster +@endif diff --git a/scripts/base/frameworks/openflow/cluster.bro b/scripts/base/frameworks/openflow/cluster.bro new file mode 100644 index 0000000000..28de1db3c3 --- /dev/null +++ b/scripts/base/frameworks/openflow/cluster.bro @@ -0,0 +1,120 @@ +##! Cluster support for the OpenFlow framework. + +@load ./main +@load base/frameworks/cluster + +module OpenFlow; + +export { + ## This is the event used to transport flow_mod messages to the manager. + global cluster_flow_mod: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod); + + ## This is the event used to transport flow_clear messages to the manager. + global cluster_flow_clear: event(name: string); +} + +## Workers need ability to forward commands to manager. +redef Cluster::worker2manager_events += /OpenFlow::cluster_flow_(mod|clear)/; + +# the flow_mod function wrapper +function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool + { + if ( ! controller?$flow_mod ) + return F; + + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return controller$flow_mod(controller$state, match, flow_mod); + else + event OpenFlow::cluster_flow_mod(controller$state$_name, match, flow_mod); + + return T; + } + +function flow_clear(controller: Controller): bool + { + if ( ! controller?$flow_clear ) + return F; + + if ( Cluster::local_node_type() == Cluster::MANAGER ) + return controller$flow_clear(controller$state); + else + event OpenFlow::cluster_flow_clear(controller$state$_name); + + return T; + } + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event OpenFlow::cluster_flow_mod(name: string, match: ofp_match, flow_mod: ofp_flow_mod) + { + if ( name !in name_to_controller ) + { + Reporter::error(fmt("OpenFlow controller %s not found in mapping on master", name)); + return; + } + + local c = name_to_controller[name]; + + if ( ! c$state$_activated ) + return; + + if ( c?$flow_mod ) + c$flow_mod(c$state, match, flow_mod); + } + +event OpenFlow::cluster_flow_clear(name: string) + { + if ( name !in name_to_controller ) + { + Reporter::error(fmt("OpenFlow controller %s not found in mapping on master", name)); + return; + } + + local c = name_to_controller[name]; + + if ( ! c$state$_activated ) + return; + + if ( c?$flow_clear ) + c$flow_clear(c$state); + } +@endif + +function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + controller$state$_name = cat(tpe, name); + controller$state$_plugin = tpe; + + # we only run the init functions on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + register_controller_impl(tpe, name, controller); + } + +function unregister_controller(controller: Controller) + { + # we only run the on the manager. + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return; + + unregister_controller_impl(controller); + } + +function lookup_controller(name: string): vector of Controller + { + # we only run the on the manager. Otherwhise we don't have a mapping or state -> return empty + if ( Cluster::local_node_type() != Cluster::MANAGER ) + return vector(); + + # I am not quite sure if we can actually get away with this - in the + # current state, this means that the individual nodes cannot lookup + # a controller by name. + # + # This means that there can be no reactions to things on the actual + # worker nodes - because they cannot look up a name. On the other hand - + # currently we also do not even send the events to the worker nodes (at least + # not if we are using broker). Because of that I am not really feeling that + # badly about it... + + return lookup_controller_impl(name); + } diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro new file mode 100644 index 0000000000..ca956702a7 --- /dev/null +++ b/scripts/base/frameworks/openflow/consts.bro @@ -0,0 +1,229 @@ +##! Constants used by the OpenFlow framework. + +# All types/constants not specific to OpenFlow will be defined here +# unitl they somehow get into Bro. + +module OpenFlow; + +# Some cookie specific constants. +# first 24 bits +const COOKIE_BID_SIZE = 16777216; +# start at bit 40 (1 << 40) +const COOKIE_BID_START = 1099511627776; +# bro specific cookie ID shall have the 42 bit set (1 << 42) +const BRO_COOKIE_ID = 4; +# 8 bits group identifier +const COOKIE_GID_SIZE = 256; +# start at bit 32 (1 << 32) +const COOKIE_GID_START = 4294967296; +# 32 bits unique identifier +const COOKIE_UID_SIZE = 4294967296; +# start at bit 0 (1 << 0) +const COOKIE_UID_START = 0; + +export { + # All ethertypes can be found at + # http://standards.ieee.org/develop/regauth/ethertype/eth.txt + # but are not interesting for us at this point +#type ethertype: enum { + # Internet protocol version 4 + const ETH_IPv4 = 0x0800; + # Address resolution protocol + const ETH_ARP = 0x0806; + # Wake on LAN + const ETH_WOL = 0x0842; + # Reverse address resolution protocol + const ETH_RARP = 0x8035; + # Appletalk + const ETH_APPLETALK = 0x809B; + # Appletalk address resolution protocol + const ETH_APPLETALK_ARP = 0x80F3; + # IEEE 802.1q & IEEE 802.1aq + const ETH_VLAN = 0x8100; + # Novell IPX old + const ETH_IPX_OLD = 0x8137; + # Novell IPX + const ETH_IPX = 0x8138; + # Internet protocol version 6 + const ETH_IPv6 = 0x86DD; + # IEEE 802.3x + const ETH_ETHER_FLOW_CONTROL = 0x8808; + # Multiprotocol Label Switching unicast + const ETH_MPLS_UNICAST = 0x8847; + # Multiprotocol Label Switching multicast + const ETH_MPLS_MULTICAST = 0x8848; + # Point-to-point protocol over Ethernet discovery phase (rfc2516) + const ETH_PPPOE_DISCOVERY = 0x8863; + # Point-to-point protocol over Ethernet session phase (rfc2516) + const ETH_PPPOE_SESSION = 0x8864; + # Jumbo frames + const ETH_JUMBO_FRAMES = 0x8870; + # IEEE 802.1X + const ETH_EAP_OVER_LAN = 0x888E; + # IEEE 802.1ad & IEEE 802.1aq + const ETH_PROVIDER_BRIDING = 0x88A8; + # IEEE 802.1ae + const ETH_MAC_SECURITY = 0x88E5; + # IEEE 802.1ad (QinQ) + const ETH_QINQ = 0x9100; +#}; + + # A list of ip protocol numbers can be found at + # http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers +#type iptype: enum { + # IPv6 Hop-by-Hop Option (RFC2460) + const IP_HOPOPT = 0x00; + # Internet Control Message Protocol (RFC792) + const IP_ICMP = 0x01; + # Internet Group Management Protocol (RFC1112) + const IP_IGMP = 0x02; + # Gateway-to-Gateway Protocol (RFC823) + const IP_GGP = 0x03; + # IP-Within-IP (encapsulation) (RFC2003) + const IP_IPIP = 0x04; + # Internet Stream Protocol (RFC1190;RFC1819) + const IP_ST = 0x05; + # Tansmission Control Protocol (RFC793) + const IP_TCP = 0x06; + # Core-based trees (RFC2189) + const IP_CBT = 0x07; + # Exterior Gateway Protocol (RFC888) + const IP_EGP = 0x08; + # Interior Gateway Protocol (any private interior + # gateway (used by Cisco for their IGRP)) + const IP_IGP = 0x09; + # User Datagram Protocol (RFC768) + const IP_UDP = 0x11; + # Reliable Datagram Protocol (RFC908) + const IP_RDP = 0x1B; + # IPv6 Encapsulation (RFC2473) + const IP_IPv6 = 0x29; + # Resource Reservation Protocol (RFC2205) + const IP_RSVP = 0x2E; + # Generic Routing Encapsulation (RFC2784;RFC2890) + const IP_GRE = 0x2F; + # Open Shortest Path First (RFC1583) + const IP_OSPF = 0x59; + # Multicast Transport Protocol + const IP_MTP = 0x5C; + # IP-within-IP Encapsulation Protocol (RFC2003) + ### error 0x5E; + # Ethernet-within-IP Encapsulation Protocol (RFC3378) + const IP_ETHERIP = 0x61; + # Layer Two Tunneling Protocol Version 3 (RFC3931) + const IP_L2TP = 0x73; + # Intermediate System to Intermediate System (IS-IS) Protocol over IPv4 (RFC1142;RFC1195) + const IP_ISIS = 0x7C; + # Fibre Channel + const IP_FC = 0x85; + # Multiprotocol Label Switching Encapsulated in IP (RFC4023) + const IP_MPLS = 0x89; +#}; + + ## Return value for a cookie from a flow + ## which is not added, modified or deleted + ## from the bro openflow framework + const INVALID_COOKIE = 0xffffffffffffffff; + # Openflow pysical port definitions + ## Send the packet out the input port. This + ## virual port must be explicitly used in + ## order to send back out of the input port. + const OFPP_IN_PORT = 0xfffffff8; + ## Perform actions in flow table. + ## NB: This can only be the destination port + ## for packet-out messages. + const OFPP_TABLE = 0xfffffff9; + ## Process with normal L2/L3 switching. + const OFPP_NORMAL = 0xfffffffa; + ## All pysical ports except input port and + ## those disabled by STP. + const OFPP_FLOOD = 0xfffffffb; + ## All pysical ports except input port. + const OFPP_ALL = 0xfffffffc; + ## Send to controller. + const OFPP_CONTROLLER = 0xfffffffd; + ## Local openflow "port". + const OFPP_LOCAL = 0xfffffffe; + ## Wildcard port used only for flow mod (delete) and flow stats requests. + const OFPP_ANY = 0xffffffff; + # Openflow no buffer constant. + const OFP_NO_BUFFER = 0xffffffff; + ## Send flow removed message when flow + ## expires or is deleted. + const OFPFF_SEND_FLOW_REM = 0x1; + ## Check for overlapping entries first. + const OFPFF_CHECK_OVERLAP = 0x2; + ## Remark this is for emergency. + ## Flows added with this are only used + ## when the controller is disconnected. + const OFPFF_EMERG = 0x4; + + # Wildcard table used for table config, + # flow stats and flow deletes. + const OFPTT_ALL = 0xff; + + ## Openflow action_type definitions + ## + ## The openflow action type defines + ## what actions openflow can take + ## to modify a packet + type ofp_action_type: enum { + ## Output to switch port. + OFPAT_OUTPUT = 0x0000, + ## Set the 802.1q VLAN id. + OFPAT_SET_VLAN_VID = 0x0001, + ## Set the 802.1q priority. + OFPAT_SET_VLAN_PCP = 0x0002, + ## Strip the 802.1q header. + OFPAT_STRIP_VLAN = 0x0003, + ## Ethernet source address. + OFPAT_SET_DL_SRC = 0x0004, + ## Ethernet destination address. + OFPAT_SET_DL_DST = 0x0005, + ## IP source address + OFPAT_SET_NW_SRC = 0x0006, + ## IP destination address. + OFPAT_SET_NW_DST = 0x0007, + ## IP ToS (DSCP field, 6 bits). + OFPAT_SET_NW_TOS = 0x0008, + ## TCP/UDP source port. + OFPAT_SET_TP_SRC = 0x0009, + ## TCP/UDP destination port. + OFPAT_SET_TP_DST = 0x000a, + ## Output to queue. + OFPAT_ENQUEUE = 0x000b, + ## Vendor specific + OFPAT_VENDOR = 0xffff, + }; + + ## Openflow flow_mod_command definitions + ## + ## The openflow flow_mod_command describes + ## of what kind an action is. + type ofp_flow_mod_command: enum { + ## New flow. + OFPFC_ADD = 0x0, + ## Modify all matching flows. + OFPFC_MODIFY = 0x1, + ## Modify entry strictly matching wildcards. + OFPFC_MODIFY_STRICT = 0x2, + ## Delete all matching flows. + OFPFC_DELETE = 0x3, + ## Strictly matching wildcards and priority. + OFPFC_DELETE_STRICT = 0x4, + }; + + ## Openflow config flag definitions + ## + ## TODO: describe + type ofp_config_flags: enum { + ## No special handling for fragments. + OFPC_FRAG_NORMAL = 0, + ## Drop fragments. + OFPC_FRAG_DROP = 1, + ## Reassemble (only if OFPC_IP_REASM set). + OFPC_FRAG_REASM = 2, + OFPC_FRAG_MASK = 3, + }; + +} diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro new file mode 100644 index 0000000000..889929c641 --- /dev/null +++ b/scripts/base/frameworks/openflow/main.bro @@ -0,0 +1,289 @@ +##! Bro's OpenFlow control framework +##! +##! This plugin-based framework allows to control OpenFlow capable +##! switches by implementing communication to an OpenFlow controller +##! via plugins. The framework has to be instantiated via the new function +##! in one of the plugins. This framework only offers very low-level +##! functionality; if you want to use OpenFlow capable switches, e.g., +##! for shunting, please look at the PACF framework, which provides higher +##! level functions and can use the OpenFlow framework as a backend. + +module OpenFlow; + +@load ./consts +@load ./types + +export { + ## Global flow_mod function. + ## + ## controller: The controller which should execute the flow modification + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## Returns: F on error or if the plugin does not support the operation, T when the operation was queued. + global flow_mod: function(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool; + + ## Clear the current flow table of the controller. + ## + ## controller: The controller which should execute the flow modification + ## + ## Returns: F on error or if the plugin does not support the operation, T when the operation was queued. + global flow_clear: function(controller: Controller): bool; + + ## Event confirming successful modification of a flow rule. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## msg: An optional informational message by the plugin. + global flow_mod_success: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + ## Reports an error while installing a flow Rule. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which describes the flow to match. + ## + ## flow_mod: The openflow flow_mod record which describes the action to take. + ## + ## msg: Message to describe the event. + global flow_mod_failure: event(name: string, match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + ## Reports that a flow was removed by the switch because of either the hard or the idle timeout. + ## This message is only generated by controllers that indicate that they support flow removal + ## in supports_flow_removed. + ## + ## name: The unique name of the OpenFlow controller from which this event originated. + ## + ## match: The ofp_match record which was used to create the flow. + ## + ## cookie: The cookie that was specified when creating the flow. + ## + ## priority: The priority that was specified when creating the flow. + ## + ## reason: The reason for flow removal (OFPRR_*) + ## + ## duration_sec: duration of the flow in seconds + ## + ## packet_count: packet count of the flow + ## + ## byte_count: byte count of the flow + global flow_removed: event(name: string, match: ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count); + + ## Convert a conn_id record into an ofp_match record that can be used to + ## create match objects for OpenFlow. + ## + ## id: the conn_id record that describes the record. + ## + ## reverse: reverse the sources and destinations when creating the match record (default F) + ## + ## Returns: ofp_match object for the conn_id record. + global match_conn: function(id: conn_id, reverse: bool &default=F): ofp_match; + + # ### + # ### Low-level functions for cookie handling and plugin registration. + # ### + + ## Function to get the unique id out of a given cookie. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie unique id. + global get_cookie_uid: function(cookie: count): count; + + ## Function to get the group id out of a given cookie. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie group id. + global get_cookie_gid: function(cookie: count): count; + + ## Function to generate a new cookie using our group id. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie group id. + global generate_cookie: function(cookie: count &default=0): count; + + ## Function to register a controller instance. This function + ## is called automatically by the plugin _new functions. + ## + ## tpe: type of this plugin + ## + ## name: unique name of this controller instance. + ## + ## controller: The controller to register + global register_controller: function(tpe: OpenFlow::Plugin, name: string, controller: Controller); + + ## Function to unregister a controller instance. This function + ## should be called when a specific controller should no longer + ## be used. + ## + ## controller: The controller to unregister + global unregister_controller: function(controller: Controller); + + ## Function to signal that a controller finished activation and is + ## ready to use. Will throw the ``OpenFlow::controller_activated`` + ## event. + global controller_init_done: function(controller: Controller); + + ## Event that is raised once a controller finishes initialization + ## and is completely activated. + ## name: unique name of this controller instance. + ## + ## controller: The controller that finished activation. + global OpenFlow::controller_activated: event(name: string, controller: Controller); + + ## Function to lookup a controller instance by name + ## + ## name: unique name of the controller to look up + ## + ## Returns: one element vector with controller, if found. Empty vector otherwhise. + global lookup_controller: function(name: string): vector of Controller; +} + +global name_to_controller: table[string] of Controller; + + +function match_conn(id: conn_id, reverse: bool &default=F): ofp_match + { + local dl_type = ETH_IPv4; + local proto = IP_TCP; + + local orig_h: addr; + local orig_p: port; + local resp_h: addr; + local resp_p: port; + + if ( reverse == F ) + { + orig_h = id$orig_h; + orig_p = id$orig_p; + resp_h = id$resp_h; + resp_p = id$resp_p; + } + else + { + orig_h = id$resp_h; + orig_p = id$resp_p; + resp_h = id$orig_h; + resp_p = id$orig_p; + } + + if ( is_v6_addr(orig_h) ) + dl_type = ETH_IPv6; + + if ( is_udp_port(orig_p) ) + proto = IP_UDP; + else if ( is_icmp_port(orig_p) ) + proto = IP_ICMP; + + return ofp_match( + $dl_type=dl_type, + $nw_proto=proto, + $nw_src=addr_to_subnet(orig_h), + $tp_src=port_to_count(orig_p), + $nw_dst=addr_to_subnet(resp_h), + $tp_dst=port_to_count(resp_p) + ); + } + +# local function to forge a flow_mod cookie for this framework. +# all flow entries from the openflow framework should have the +# 42 bit of the cookie set. +function generate_cookie(cookie: count &default=0): count + { + local c = BRO_COOKIE_ID * COOKIE_BID_START; + + if ( cookie >= COOKIE_UID_SIZE ) + Reporter::warning(fmt("The given cookie uid '%d' is > 32bit and will be discarded", cookie)); + else + c += cookie; + + return c; + } + +# local function to check if a given flow_mod cookie is forged from this framework. +function is_valid_cookie(cookie: count): bool + { + if ( cookie / COOKIE_BID_START == BRO_COOKIE_ID ) + return T; + + Reporter::warning(fmt("The given Openflow cookie '%d' is not valid", cookie)); + + return F; + } + +function get_cookie_uid(cookie: count): count + { + if( is_valid_cookie(cookie) ) + return (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START)); + + return INVALID_COOKIE; + } + +function get_cookie_gid(cookie: count): count + { + if( is_valid_cookie(cookie) ) + return ( + (cookie - (COOKIE_BID_START * BRO_COOKIE_ID) - + (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START))) / + COOKIE_GID_START + ); + + return INVALID_COOKIE; + } + +function controller_init_done(controller: Controller) + { + if ( controller$state$_name !in name_to_controller ) + { + Reporter::error(fmt("Openflow initialized unknown plugin %s successfully?", controller$state$_name)); + return; + } + + controller$state$_activated = T; + event OpenFlow::controller_activated(controller$state$_name, controller); + } + +# Functions that are called from cluster.bro and non-cluster.bro + +function register_controller_impl(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + if ( controller$state$_name in name_to_controller ) + { + Reporter::error(fmt("OpenFlow Controller %s was already registered. Ignored duplicate registration", controller$state$_name)); + return; + } + + name_to_controller[controller$state$_name] = controller; + + if ( controller?$init ) + controller$init(controller$state); + else + controller_init_done(controller); + } + +function unregister_controller_impl(controller: Controller) + { + if ( controller$state$_name in name_to_controller ) + delete name_to_controller[controller$state$_name]; + else + Reporter::error("OpenFlow Controller %s was not registered in unregister."); + + if ( controller?$destroy ) + controller$destroy(controller$state); + } + +function lookup_controller_impl(name: string): vector of Controller + { + if ( name in name_to_controller ) + return vector(name_to_controller[name]); + else + return vector(); + } diff --git a/scripts/base/frameworks/openflow/non-cluster.bro b/scripts/base/frameworks/openflow/non-cluster.bro new file mode 100644 index 0000000000..22b5980924 --- /dev/null +++ b/scripts/base/frameworks/openflow/non-cluster.bro @@ -0,0 +1,44 @@ +@load ./main + +module OpenFlow; + +# the flow_mod function wrapper +function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool + { + if ( ! controller$state$_activated ) + return F; + + if ( controller?$flow_mod ) + return controller$flow_mod(controller$state, match, flow_mod); + else + return F; + } + +function flow_clear(controller: Controller): bool + { + if ( ! controller$state$_activated ) + return F; + + if ( controller?$flow_clear ) + return controller$flow_clear(controller$state); + else + return F; + } + +function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Controller) + { + controller$state$_name = cat(tpe, name); + controller$state$_plugin = tpe; + + register_controller_impl(tpe, name, controller); + } + +function unregister_controller(controller: Controller) + { + unregister_controller_impl(controller); + } + +function lookup_controller(name: string): vector of Controller + { + return lookup_controller_impl(name); + } diff --git a/scripts/base/frameworks/openflow/plugins/__load__.bro b/scripts/base/frameworks/openflow/plugins/__load__.bro new file mode 100644 index 0000000000..e387132034 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/__load__.bro @@ -0,0 +1,3 @@ +@load ./ryu +@load ./log +@load ./broker diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro new file mode 100644 index 0000000000..d6cf52a92c --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -0,0 +1,95 @@ +##! OpenFlow plugin for interfacing to controllers via Broker. + +@load base/frameworks/openflow +@load base/frameworks/broker + +module OpenFlow; + +export { + redef enum Plugin += { + BROKER, + }; + + ## Broker controller constructor. + ## + ## host: Controller ip. + ## + ## host_port: Controller listen port. + ## + ## topic: broker topic to send messages to. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global broker_new: function(name: string, host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller; + + redef record ControllerState += { + ## Controller ip. + broker_host: addr &optional; + ## Controller listen port. + broker_port: port &optional; + ## OpenFlow switch datapath id. + broker_dpid: count &optional; + ## Topic to sent events for this controller to + broker_topic: string &optional; + }; + + global broker_flow_mod: event(name: string, dpid: count, match: ofp_match, flow_mod: ofp_flow_mod); + global broker_flow_clear: event(name: string, dpid: count); +} + +global broker_peers: table[port, string] of Controller; + +function broker_describe(state: ControllerState): string + { + return fmt("Broker-%s:%d-%d", state$broker_host, state$broker_port, state$broker_dpid); + } + +function broker_flow_mod_fun(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_mod, state$_name, state$broker_dpid, match, flow_mod)); + + return T; + } + +function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool + { + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_clear, state$_name, state$broker_dpid)); + + return T; + } + +function broker_init(state: OpenFlow::ControllerState) + { + BrokerComm::enable(); + BrokerComm::connect(cat(state$broker_host), state$broker_port, 1sec); + BrokerComm::subscribe_to_events(state$broker_topic); # openflow success and failure events are directly sent back via the other plugin via broker. + } + +event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string) + { + if ( [peer_port, peer_address] !in broker_peers ) + # ok, this one was none of ours... + return; + + local p = broker_peers[peer_port, peer_address]; + controller_init_done(p); + delete broker_peers[peer_port, peer_address]; + } + +# broker controller constructor +function broker_new(name: string, host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic), + $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe, $supports_flow_removed=T, $init=broker_init); + + register_controller(OpenFlow::BROKER, name, c); + + if ( [host_port, cat(host)] in broker_peers ) + Reporter::warning(fmt("Peer %s:%s was added to NetControl acld plugin twice.", host, host_port)); + else + broker_peers[host_port, cat(host)] = c; + + return c; + } + diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro new file mode 100644 index 0000000000..18aa0c1584 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -0,0 +1,76 @@ +##! OpenFlow plugin that outputs flow-modification commands +##! to a Bro log file. + +@load base/frameworks/openflow +@load base/frameworks/logging + +module OpenFlow; + +export { + redef enum Plugin += { + OFLOG, + }; + + redef enum Log::ID += { LOG }; + + ## Log controller constructor. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## success_event: If true, flow_mod_success is raised for each logged line. + ## + ## Returns: OpenFlow::Controller record + global log_new: function(dpid: count, success_event: bool &default=T): OpenFlow::Controller; + + redef record ControllerState += { + ## OpenFlow switch datapath id. + log_dpid: count &optional; + ## Raise or do not raise success event + log_success_event: bool &optional; + }; + + ## The record type which contains column fields of the OpenFlow log. + type Info: record { + ## Network time + ts: time &log; + ## OpenFlow switch datapath id + dpid: count &log; + ## OpenFlow match fields + match: ofp_match &log; + ## OpenFlow modify flow entry message + flow_mod: ofp_flow_mod &log; + }; + + ## Event that can be handled to access the :bro:type:`OpenFlow::Info` + ## record as it is sent on to the logging framework. + global log_openflow: event(rec: Info); +} + +event bro_init() &priority=5 + { + Log::create_stream(OpenFlow::LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]); + } + +function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + Log::write(OpenFlow::LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); + if ( state$log_success_event ) + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); + + return T; + } + +function log_describe(state: ControllerState): string + { + return fmt("Log-%d", state$log_dpid); + } + +function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($log_dpid=dpid, $log_success_event=success_event), + $flow_mod=log_flow_mod, $describe=log_describe, $supports_flow_removed=F); + + register_controller(OpenFlow::OFLOG, cat(dpid), c); + + return c; + } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro new file mode 100644 index 0000000000..69d51adc9b --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -0,0 +1,190 @@ +##! OpenFlow plugin for the Ryu controller. + +@load base/frameworks/openflow +@load base/utils/active-http +@load base/utils/exec +@load base/utils/json + +module OpenFlow; + +export { + redef enum Plugin += { + RYU, + }; + + ## Ryu controller constructor. + ## + ## host: Controller ip. + ## + ## host_port: Controller listen port. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global ryu_new: function(host: addr, host_port: count, dpid: count): OpenFlow::Controller; + + redef record ControllerState += { + ## Controller ip. + ryu_host: addr &optional; + ## Controller listen port. + ryu_port: count &optional; + ## OpenFlow switch datapath id. + ryu_dpid: count &optional; + ## Enable debug mode - output JSON to stdout; do not perform actions + ryu_debug: bool &default=F; + }; +} + +# Ryu ReST API flow_mod URL-path +const RYU_FLOWENTRY_PATH = "/stats/flowentry/"; +# Ryu ReST API flow_stats URL-path +#const RYU_FLOWSTATS_PATH = "/stats/flow/"; + +# Ryu ReST API action_output type. +type ryu_flow_action: record { + # Ryu uses strings as its ReST API output action. + _type: string; + # The output port for type OUTPUT + _port: count &optional; +}; + +# The ReST API documentation can be found at +# https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf +# Ryu ReST API flow_mod type. +type ryu_ofp_flow_mod: record { + dpid: count; + cookie: count &optional; + cookie_mask: count &optional; + table_id: count &optional; + idle_timeout: count &optional; + hard_timeout: count &optional; + priority: count &optional; + flags: count &optional; + match: OpenFlow::ofp_match; + actions: vector of ryu_flow_action; + out_port: count &optional; + out_group: count &optional; +}; + +# Mapping between ofp flow mod commands and ryu urls +const ryu_url: table[ofp_flow_mod_command] of string = { + [OFPFC_ADD] = "add", + [OFPFC_MODIFY] = "modify", + [OFPFC_MODIFY_STRICT] = "modify_strict", + [OFPFC_DELETE] = "delete", + [OFPFC_DELETE_STRICT] = "delete_strict", +}; + +# Ryu flow_mod function +function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + if ( state$_plugin != RYU ) + { + Reporter::error("Ryu openflow plugin was called with state of non-ryu plugin"); + return F; + } + + # Generate ryu_flow_actions because their type differs (using strings as type). + local flow_actions: vector of ryu_flow_action = vector(); + + for ( i in flow_mod$actions$out_ports ) + flow_actions[|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. + local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( + $dpid=state$ryu_dpid, + $cookie=flow_mod$cookie, + $idle_timeout=flow_mod$idle_timeout, + $hard_timeout=flow_mod$hard_timeout, + $priority=flow_mod$priority, + $flags=flow_mod$flags, + $match=match, + $actions=flow_actions + ); + + if ( flow_mod?$out_port ) + mod$out_port = flow_mod$out_port; + if ( flow_mod?$out_group ) + mod$out_group = flow_mod$out_group; + + # Type of the command + local command_type: string; + + if ( flow_mod$command in ryu_url ) + command_type = ryu_url[flow_mod$command]; + else + { + Reporter::warning(fmt("The given OpenFlow command type '%s' is not available", cat(flow_mod$command))); + return F; + } + + local url=cat("http://", cat(state$ryu_host), ":", cat(state$ryu_port), RYU_FLOWENTRY_PATH, command_type); + + if ( state$ryu_debug ) + { + print url; + print to_json(mod); + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); + return T; + } + + # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=url, + $method="POST", + $client_data=to_json(mod) + ); + + # Execute call to Ryu's ReST API + when ( local result = ActiveHTTP::request(request) ) + { + if(result$code == 200) + event OpenFlow::flow_mod_success(state$_name, match, flow_mod, result$body); + else + { + Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); + event OpenFlow::flow_mod_failure(state$_name, match, flow_mod, result$body); + return F; + } + } + + return T; + } + +function ryu_flow_clear(state: OpenFlow::ControllerState): bool + { + local url=cat("http://", cat(state$ryu_host), ":", cat(state$ryu_port), RYU_FLOWENTRY_PATH, "clear", "/", state$ryu_dpid); + + if ( state$ryu_debug ) + { + print url; + return T; + } + + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=url, + $method="DELETE" + ); + + when ( local result = ActiveHTTP::request(request) ) + { + } + + return T; + } + +function ryu_describe(state: ControllerState): string + { + return fmt("Ryu-%d-http://%s:%d", state$ryu_dpid, state$ryu_host, state$ryu_port); + } + +# Ryu controller constructor +function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller + { + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid), + $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe, $supports_flow_removed=F); + + register_controller(OpenFlow::RYU, cat(host,host_port,dpid), c); + + return c; + } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro new file mode 100644 index 0000000000..f527cd51a7 --- /dev/null +++ b/scripts/base/frameworks/openflow/types.bro @@ -0,0 +1,132 @@ +##! Types used by the OpenFlow framework. + +module OpenFlow; + +@load ./consts + +export { + ## Available openflow plugins + type Plugin: enum { + ## Internal placeholder plugin + INVALID, + }; + + ## Controller related state. + ## Can be redefined by plugins to + ## add state. + type ControllerState: record { + ## Internally set to the type of plugin used. + _plugin: Plugin &optional; + ## Internally set to the unique name of the controller. + _name: string &optional; + ## Internally set to true once the controller is activated + _activated: bool &default=F; + } &redef; + + ## Openflow match definition. + ## + ## The openflow match record describes + ## which packets match to a specific + ## rule in a flow table. + type ofp_match: record { + # Input switch port. + in_port: count &optional; + # Ethernet source address. + dl_src: string &optional; + # Ethernet destination address. + dl_dst: string &optional; + # Input VLAN id. + dl_vlan: count &optional; + # Input VLAN priority. + dl_vlan_pcp: count &optional; + # Ethernet frame type. + dl_type: count &optional; + # IP ToS (actually DSCP field, 6bits). + nw_tos: count &optional; + # IP protocol or lower 8 bits of ARP opcode. + nw_proto: count &optional; + # At the moment, we store both v4 and v6 in the same fields. + # This is not how OpenFlow does it, we might want to change that... + # IP source address. + nw_src: subnet &optional; + # IP destination address. + nw_dst: subnet &optional; + # TCP/UDP source port. + tp_src: count &optional; + # TCP/UDP destination port. + tp_dst: count &optional; + } &log; + + ## The actions that can be taken in a flow. + ## (Sepearate record to make ofp_flow_mod less crowded) + type ofp_flow_action: record { + ## Output ports to send data to. + out_ports: vector of count &default=vector(); + ## set vlan vid to this value + vlan_vid: count &optional; + ## set vlan priority to this value + vlan_pcp: count &optional; + ## strip vlan tag + vlan_strip: bool &default=F; + ## set ethernet source address + dl_src: string &optional; + ## set ethernet destination address + dl_dst: string &optional; + ## set ip tos to this value + nw_tos: count &optional; + ## set source to this ip + nw_src: addr &optional; + ## set destination to this ip + nw_dst: addr &optional; + ## set tcp/udp source port + tp_src: count &optional; + ## set tcp/udp destination port + tp_dst: count &optional; + } &log; + + ## Openflow flow_mod definition, describing the action to perform. + type ofp_flow_mod: record { + ## Opaque controller-issued identifier. + # This is optional in the specification - but let's force + # it so we always can identify our flows... + cookie: count; # &default=BRO_COOKIE_ID * COOKIE_BID_START; + # Flow actions + ## Table to put the flow in. OFPTT_ALL can be used for delete, + ## to delete flows from all matching tables. + table_id: count &optional; + ## One of OFPFC_*. + command: ofp_flow_mod_command; # &default=OFPFC_ADD; + ## Idle time before discarding (seconds). + idle_timeout: count &default=0; + ## Max time before discarding (seconds). + hard_timeout: count &default=0; + ## Priority level of flow entry. + priority: count &default=0; + ## For OFPFC_DELETE* commands, require matching entried to include + ## this as an output port/group. OFPP_ANY/OFPG_ANY means no restrictions. + out_port: count &optional; + out_group: count &optional; + ## Bitmap of the OFPFF_* flags + flags: count &default=0; + ## Actions to take on match + actions: ofp_flow_action &default=ofp_flow_action(); + } &log; + + ## Controller record representing an openflow controller + type Controller: record { + ## Controller related state. + state: ControllerState; + ## Does the controller support the flow_removed event? + supports_flow_removed: bool; + ## function that describes the controller. Has to be implemented. + describe: function(state: ControllerState): string; + ## one-time initialization function. If defined, controller_init_done has to be called once initialization finishes. + init: function (state: ControllerState) &optional; + ## one-time destruction function + destroy: function (state: ControllerState) &optional; + ## flow_mod function + flow_mod: function(state: ControllerState, match: ofp_match, flow_mod: ofp_flow_mod): bool &optional; + ## flow_clear function + flow_clear: function(state: ControllerState): bool &optional; + }; +} diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 94b6ed33e5..9c60d76746 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -39,6 +39,13 @@ type count_set: set[count]; ## directly and then remove this alias. type index_vec: vector of count; +## A vector of subnets. +## +## .. todo:: We need this type definition only for declaring builtin functions +## via ``bifcl``. We should extend ``bifcl`` to understand composite types +## directly and then remove this alias. +type subnet_vec: vector of subnet; + ## A vector of any, used by some builtin functions to store a list of varying ## types. ## @@ -120,6 +127,18 @@ type conn_id: record { resp_p: port; ##< The responder's port number. } &log; +## The identifying 4-tuple of a uni-directional flow. +## +## .. note:: It's actually a 5-tuple: the transport-layer protocol is stored as +## part of the port values, `src_p` and `dst_p`, and can be extracted from +## them with :bro:id:`get_port_transport_proto`. +type flow_id : record { + src_h: addr; ##< The source IP address. + src_p: port; ##< The source port number. + dst_h: addr; ##< The destination IP address. + dst_p: port; ##< The desintation port number. +} &log; + ## Specifics about an ICMP conversation. ICMP events typically pass this in ## addition to :bro:type:`conn_id`. ## diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 473d94fc84..7fefe0111d 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,6 +37,8 @@ @load base/frameworks/reporter @load base/frameworks/sumstats @load base/frameworks/tunnels +@load base/frameworks/openflow +@load base/frameworks/netcontrol @load base/protocols/conn @load base/protocols/dhcp diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index f98e33b315..717b3a0669 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -213,7 +213,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior # on a different file could be checked, but the file size will # be overwritten by the server response to the RETR command # if that's given as well which would be more correct. - c$ftp$file_size = extract_count(msg); + c$ftp$file_size = extract_count(msg, F); } # PASV and EPSV processing diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index 7a95d63cc6..35cfc7681d 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -109,7 +109,7 @@ export { [7] = "client_authz", [8] = "server_authz", [9] = "cert_type", - [10] = "elliptic_curves", + [10] = "elliptic_curves", # new name: supported_groups - draft-ietf-tls-negotiated-ff-dhe [11] = "ec_point_formats", [12] = "srp", [13] = "signature_algorithms", @@ -120,9 +120,10 @@ export { [18] = "signed_certificate_timestamp", [19] = "client_certificate_type", [20] = "server_certificate_type", - [21] = "padding", # temporary till 2016-03-12 + [21] = "padding", [22] = "encrypt_then_mac", [23] = "extended_master_secret", + [24] = "token_binding", # temporary till 2017-02-04 - draft-ietf-tokbind-negotiation [35] = "SessionTicket TLS", [40] = "extended_random", [13172] = "next_protocol_negotiation", @@ -165,7 +166,10 @@ export { [26] = "brainpoolP256r1", [27] = "brainpoolP384r1", [28] = "brainpoolP512r1", - # draft-ietf-tls-negotiated-ff-dhe-05 + # Temporary till 2017-03-01 - draft-ietf-tls-rfc4492bis + [29] = "ecdh_x25519", + [30] = "ecdh_x448", + # draft-ietf-tls-negotiated-ff-dhe-10 [256] = "ffdhe2048", [257] = "ffdhe3072", [258] = "ffdhe4096", diff --git a/scripts/base/utils/json.bro b/scripts/base/utils/json.bro new file mode 100644 index 0000000000..b6d0093b58 --- /dev/null +++ b/scripts/base/utils/json.bro @@ -0,0 +1,105 @@ +##! Functions to assist with generating JSON data from Bro data scructures. +# We might want to implement this in core somtime, this looks... hacky at best. + +@load base/utils/strings + +## A function to convert arbitrary Bro data into a JSON string. +## +## v: The value to convert to JSON. Typically a record. +## +## only_loggable: If the v value is a record this will only cause +## fields with the &log attribute to be included in the JSON. +## +## returns: a JSON formatted string. +function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string + { + local tn = type_name(v); + switch ( tn ) + { + case "type": + return ""; + + case "string": + return cat("\"", gsub(gsub(clean(v), /\\/, "\\\\"), /\"/, "\\\""), "\""); + + case "port": + return cat(port_to_count(to_port(cat(v)))); + + case "addr": + fallthrough; + case "subnet": + return cat("\"", v, "\""); + + case "int": + fallthrough; + case "count": + fallthrough; + case "time": + fallthrough; + case "double": + fallthrough; + case "bool": + fallthrough; + case "enum": + return cat(v); + + default: + break; + } + + if ( /^record/ in tn ) + { + local rec_parts: string_vec = vector(); + + local ft = record_fields(v); + for ( field in ft ) + { + local field_desc = ft[field]; + # replace the escape pattern in the field. + if( field_escape_pattern in field ) + field = cat(sub(field, field_escape_pattern, "")); + if ( field_desc?$value && (!only_loggable || field_desc$log) ) + { + local onepart = cat("\"", field, "\": ", to_json(field_desc$value, only_loggable)); + rec_parts[|rec_parts|] = onepart; + } + } + return cat("{", join_string_vec(rec_parts, ", "), "}"); + } + + # None of the following are supported. + else if ( /^set/ in tn ) + { + local set_parts: string_vec = vector(); + local sa: set[bool] = v; + for ( sv in sa ) + { + set_parts[|set_parts|] = to_json(sv, only_loggable); + } + return cat("[", join_string_vec(set_parts, ", "), "]"); + } + else if ( /^table/ in tn ) + { + local tab_parts: vector of string = vector(); + local ta: table[bool] of any = v; + for ( ti in ta ) + { + local ts = to_json(ti); + local if_quotes = (ts[0] == "\"") ? "" : "\""; + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", to_json(ta[ti], only_loggable)); + } + return cat("{", join_string_vec(tab_parts, ", "), "}"); + } + else if ( /^vector/ in tn ) + { + local vec_parts: string_vec = vector(); + local va: vector of any = v; + for ( vi in va ) + { + vec_parts[|vec_parts|] = to_json(va[vi], only_loggable); + } + return cat("[", join_string_vec(vec_parts, ", "), "]"); + } + + return "\"\""; + } diff --git a/scripts/base/utils/numbers.bro b/scripts/base/utils/numbers.bro index da8c15d7a0..d2adb49ea2 100644 --- a/scripts/base/utils/numbers.bro +++ b/scripts/base/utils/numbers.bro @@ -1,10 +1,26 @@ -## Extract the first integer found in the given string. -## If no integer can be found, 0 is returned. -function extract_count(s: string): count + +## Extract an integer from a string. +## +## s: The string to search for a number. +## +## get_first: Provide `F` if you would like the last number found. +## +## Returns: The request integer from the given string or 0 if +## no integer was found. +function extract_count(s: string, get_first: bool &default=T): count { - local parts = split_string_n(s, /[0-9]+/, T, 1); - if ( 1 in parts ) - return to_count(parts[1]); + local extract_num_pattern = /[0-9]+/; + if ( get_first ) + { + local first_parts = split_string_n(s, extract_num_pattern, T, 1); + if ( 1 in first_parts ) + return to_count(first_parts[1]); + } else - return 0; + { + local last_parts = split_string_all(s, extract_num_pattern); + if ( |last_parts| > 1 ) + return to_count(last_parts[|last_parts|-2]); + } + return 0; } diff --git a/src/Attr.cc b/src/Attr.cc index 4bfbcf2ad7..14b00bd0d7 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -375,12 +375,33 @@ void Attributes::CheckAttr(Attr* a) case ATTR_EXPIRE_READ: case ATTR_EXPIRE_WRITE: case ATTR_EXPIRE_CREATE: + { if ( type->Tag() != TYPE_TABLE ) { Error("expiration only applicable to tables"); break; } + int num_expires = 0; + if ( attrs ) + { + loop_over_list(*attrs, i) + { + Attr* a = (*attrs)[i]; + if ( a->Tag() == ATTR_EXPIRE_READ || + a->Tag() == ATTR_EXPIRE_WRITE || + a->Tag() == ATTR_EXPIRE_CREATE ) + num_expires++; + } + } + + if ( num_expires > 1 ) + { + Error("set/table can only have one of &read_expire, &write_expire, &create_expire"); + break; + } + } + #if 0 //### not easy to test this w/o knowing the ID. if ( ! IsGlobal() ) diff --git a/src/Desc.cc b/src/Desc.cc index 3cdc35bfe5..4654454129 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -351,3 +351,24 @@ void ODesc::Clear() } } +bool ODesc::PushType(const BroType* type) + { + auto res = encountered_types.insert(type); + return std::get<1>(res); + } + +bool ODesc::PopType(const BroType* type) + { + size_t res = encountered_types.erase(type); + return (res == 1); + } + +bool ODesc::FindType(const BroType* type) + { + auto res = encountered_types.find(type); + + if ( res != encountered_types.end() ) + return true; + + return false; + } diff --git a/src/Desc.h b/src/Desc.h index cc6ba3a662..df850378c4 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -23,6 +23,7 @@ typedef enum { class BroFile; class IPAddr; class IPPrefix; +class BroType; class ODesc { public: @@ -140,6 +141,12 @@ public: void Clear(); + // Used to determine recursive types. Records push their types on here; + // if the same type (by address) is re-encountered, processing aborts. + bool PushType(const BroType* type); + bool PopType(const BroType* type); + bool FindType(const BroType* type); + protected: void Indent(); @@ -190,6 +197,8 @@ protected: int do_flush; int include_stats; int indent_with_spaces; + + std::set encountered_types; }; #endif diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index d31203c9d3..007e08349c 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -1,7 +1,7 @@ #include "PrefixTable.h" #include "Reporter.h" -inline static prefix_t* make_prefix(const IPAddr& addr, int width) +prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width) { prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); @@ -13,9 +13,14 @@ inline static prefix_t* make_prefix(const IPAddr& addr, int width) return prefix; } +IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix) + { + return IPPrefix(IPAddr(IPv6, reinterpret_cast(&prefix->add.sin6), IPAddr::Network), prefix->bitlen, 1); + } + void* PrefixTable::Insert(const IPAddr& addr, int width, void* data) { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = patricia_lookup(tree, prefix); Deref_Prefix(prefix); @@ -57,13 +62,39 @@ void* PrefixTable::Insert(const Val* value, void* data) } } +list> PrefixTable::FindAll(const IPAddr& addr, int width) const + { + std::list> out; + prefix_t* prefix = MakePrefix(addr, width); + + int elems = 0; + patricia_node_t** list = nullptr; + + patricia_search_all(tree, prefix, &list, &elems); + + for ( int i = 0; i < elems; ++i ) + out.push_back(std::make_tuple(PrefixToIPPrefix(list[i]->prefix), list[i]->data)); + + Deref_Prefix(prefix); + free(list); + return out; + } + +list> PrefixTable::FindAll(const SubNetVal* value) const + { + return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); + } + void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = exact ? patricia_search_exact(tree, prefix) : patricia_search_best(tree, prefix); + int elems = 0; + patricia_node_t** list = nullptr; + Deref_Prefix(prefix); return node ? node->data : 0; } @@ -94,7 +125,7 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const void* PrefixTable::Remove(const IPAddr& addr, int width) { - prefix_t* prefix = make_prefix(addr, width); + prefix_t* prefix = MakePrefix(addr, width); patricia_node_t* node = patricia_search_exact(tree, prefix); Deref_Prefix(prefix); diff --git a/src/PrefixTable.h b/src/PrefixTable.h index 2e5f43a0a8..6606b77e81 100644 --- a/src/PrefixTable.h +++ b/src/PrefixTable.h @@ -36,6 +36,10 @@ public: void* Lookup(const IPAddr& addr, int width, bool exact = false) const; void* Lookup(const Val* value, bool exact = false) const; + // Returns list of all found matches or empty list otherwise. + list> FindAll(const IPAddr& addr, int width) const; + list> FindAll(const SubNetVal* value) const; + // Returns pointer to data or nil if not found. void* Remove(const IPAddr& addr, int width); void* Remove(const Val* value); @@ -45,6 +49,10 @@ public: iterator InitIterator(); void* GetNext(iterator* i); +private: + static prefix_t* MakePrefix(const IPAddr& addr, int width); + static IPPrefix PrefixToIPPrefix(prefix_t* p); + patricia_tree_t* tree; }; diff --git a/src/Type.cc b/src/Type.cc index 75f1f445df..1a6a4d36b8 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1045,6 +1045,8 @@ TypeDecl* RecordType::FieldDecl(int field) void RecordType::Describe(ODesc* d) const { + d->PushType(this); + if ( d->IsReadable() ) { if ( d->IsShort() && GetName().size() ) @@ -1064,10 +1066,13 @@ void RecordType::Describe(ODesc* d) const d->Add(int(Tag())); DescribeFields(d); } + + d->PopType(this); } void RecordType::DescribeReST(ODesc* d, bool roles_only) const { + d->PushType(this); d->Add(":bro:type:`record`"); if ( num_fields == 0 ) @@ -1075,6 +1080,7 @@ void RecordType::DescribeReST(ODesc* d, bool roles_only) const d->NL(); DescribeFieldsReST(d, false); + d->PopType(this); } const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) @@ -1129,7 +1135,12 @@ void RecordType::DescribeFields(ODesc* d) const const TypeDecl* td = FieldDecl(i); d->Add(td->id); d->Add(":"); - td->type->Describe(d); + + if ( d->FindType(td->type) ) + d->Add(""); + else + td->type->Describe(d); + d->Add(";"); } } @@ -1170,7 +1181,11 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const } const TypeDecl* td = FieldDecl(i); - td->DescribeReST(d); + + if ( d->FindType(td->type) ) + d->Add(""); + else + td->DescribeReST(d); if ( func_args ) continue; diff --git a/src/Type.h b/src/Type.h index e3d1167166..9f7a439986 100644 --- a/src/Type.h +++ b/src/Type.h @@ -182,6 +182,7 @@ public: CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); return (const FuncType*) this; } + FuncType* AsFuncType() { CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); @@ -201,7 +202,7 @@ public: } const VectorType* AsVectorType() const - { + { CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType"); return (VectorType*) this; } @@ -219,19 +220,19 @@ public: } VectorType* AsVectorType() - { + { CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType"); return (VectorType*) this; } const TypeType* AsTypeType() const - { + { CHECK_TYPE_TAG(TYPE_TYPE, "BroType::AsTypeType"); return (TypeType*) this; } TypeType* AsTypeType() - { + { CHECK_TYPE_TAG(TYPE_TYPE, "BroType::AsTypeType"); return (TypeType*) this; } diff --git a/src/Val.cc b/src/Val.cc index 01a849c639..ed4ca40e14 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1787,7 +1787,16 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) { TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index); if ( v ) + { + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) + { + v->SetExpireAccess(network_time); + if ( LoggingAccess() && expire_time ) + ReadOperation(index, v); + } + return v->Value() ? v->Value() : this; + } if ( ! use_default_val ) return 0; @@ -1810,9 +1819,7 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) if ( v ) { - if ( attrs && - ! (attrs->FindAttr(ATTR_EXPIRE_WRITE) || - attrs->FindAttr(ATTR_EXPIRE_CREATE)) ) + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) { v->SetExpireAccess(network_time); if ( LoggingAccess() && expire_time ) @@ -1833,6 +1840,57 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) return def; } +VectorVal* TableVal::LookupSubnets(const SubNetVal* search) + { + if ( ! subnets ) + reporter->InternalError("LookupSubnets called on wrong table type"); + + VectorVal* result = new VectorVal(internal_type("subnet_vec")->AsVectorType()); + + auto matches = subnets->FindAll(search); + for ( auto element : matches ) + { + SubNetVal* s = new SubNetVal(get<0>(element)); + result->Assign(result->Size(), s); + } + + return result; + } + +TableVal* TableVal::LookupSubnetValues(const SubNetVal* search) + { + if ( ! subnets ) + reporter->InternalError("LookupSubnetValues called on wrong table type"); + + TableVal* nt = new TableVal(this->Type()->Ref()->AsTableType()); + + auto matches = subnets->FindAll(search); + for ( auto element : matches ) + { + SubNetVal* s = new SubNetVal(get<0>(element)); + TableEntryVal* entry = reinterpret_cast(get<1>(element)); + + if ( entry && entry->Value() ) + nt->Assign(s, entry->Value()->Ref()); + else + nt->Assign(s, 0); // set + + if ( entry ) + { + if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) + { + entry->SetExpireAccess(network_time); + if ( LoggingAccess() && expire_time ) + ReadOperation(s, entry); + } + } + + Unref(s); // assign does not consume index + } + + return nt; + } + bool TableVal::UpdateTimestamp(Val* index) { TableEntryVal* v; @@ -1854,7 +1912,7 @@ bool TableVal::UpdateTimestamp(Val* index) return false; v->SetExpireAccess(network_time); - if ( attrs->FindAttr(ATTR_EXPIRE_READ) ) + if ( LoggingAccess() && attrs->FindAttr(ATTR_EXPIRE_READ) ) ReadOperation(index, v); return true; @@ -2478,7 +2536,7 @@ bool TableVal::DoUnserialize(UnserialInfo* info) } // If necessary, activate the expire timer. - if ( attrs) + if ( attrs ) { CheckExpireAttr(ATTR_EXPIRE_READ); CheckExpireAttr(ATTR_EXPIRE_WRITE); diff --git a/src/Val.h b/src/Val.h index 86d75af94a..a49a2e2235 100644 --- a/src/Val.h +++ b/src/Val.h @@ -790,6 +790,16 @@ public: // need to Ref/Unref it when calling the default function. Val* Lookup(Val* index, bool use_default_val = true); + // For a table[subnet]/set[subnet], return all subnets that cover + // the given subnet. + // Causes an internal error if called for any other kind of table. + VectorVal* LookupSubnets(const SubNetVal* s); + + // For a set[subnet]/table[subnet], return a new table that only contains + // entries that cover the given subnet. + // Causes an internal error if called for any other kind of table. + TableVal* LookupSubnetValues(const SubNetVal* s); + // Sets the timestamp for the given index to network time. // Returns false if index does not exist. bool UpdateTimestamp(Val* index); @@ -814,6 +824,11 @@ public: int Size() const { return AsTable()->Length(); } int RecursiveSize() const; + // Returns the Prefix table used inside the table (if present). + // This allows us to do more direct queries to this specialized + // type that the general Table API does not allow. + const PrefixTable* Subnets() const { return subnets; } + void Describe(ODesc* d) const override; void InitTimer(double delay); diff --git a/src/analyzer/protocol/finger/Finger.cc b/src/analyzer/protocol/finger/Finger.cc index 6a5865383b..a9818ff7af 100644 --- a/src/analyzer/protocol/finger/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -54,7 +54,9 @@ void Finger_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig if ( long_cnt ) line = skip_whitespace(line+2, end_of_line); - const char* at = strchr_n(line, end_of_line, '@'); + assert(line <= end_of_line); + size_t n = end_of_line >= line ? end_of_line - line : 0; // just to be sure if assertions aren't on. + const char* at = reinterpret_cast(memchr(line, '@', n)); const char* host = 0; if ( ! at ) at = host = end_of_line; diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index fca740777b..490a9d2324 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -1382,7 +1382,7 @@ void HTTP_Analyzer::HTTP_Request() const char* method = (const char*) request_method->AsString()->Bytes(); int method_len = request_method->AsString()->Len(); - if ( strcasecmp_n(method_len, method, "CONNECT") == 0 ) + if ( strncasecmp(method, "CONNECT", method_len) == 0 ) connect_request = true; if ( http_request ) @@ -1576,7 +1576,7 @@ int HTTP_Analyzer::ExpectReplyMessageBody() const BroString* method = UnansweredRequestMethod(); - if ( method && strcasecmp_n(method->Len(), (const char*) (method->Bytes()), "HEAD") == 0 ) + if ( method && strncasecmp((const char*) (method->Bytes()), "HEAD", method->Len()) == 0 ) return HTTP_BODY_NOT_EXPECTED; if ( (reply_code >= 100 && reply_code < 200) || diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 8d57da3477..f668be921c 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -153,8 +153,10 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) else { const char* sys_type = line; - const char* colon = strchr_n(line, end_of_line, ':'); - const char* comma = strchr_n(line, end_of_line, ','); + assert(line <= end_of_line); + size_t n = end_of_line >= line ? end_of_line - line : 0; // just to be sure if assertions aren't on. + const char* colon = reinterpret_cast(memchr(line, ':', n)); + const char* comma = reinterpret_cast(memchr(line, ',', n)); if ( ! colon ) { BadReply(length, orig_line); diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index d968be09cf..bcdfe03248 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -148,7 +148,7 @@ void MIME_Mail::Undelivered(int len) int strcasecmp_n(data_chunk_t s, const char* t) { - return ::strcasecmp_n(s.length, s.data, t); + return strncasecmp(s.data, t, s.length); } int MIME_count_leading_lws(int len, const char* data) diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 2108401436..66710fb2bb 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -19,6 +19,9 @@ refine flow MySQL_Flow += { function proc_mysql_handshake_response_packet(msg: Handshake_Response_Packet): bool %{ + if ( ${msg.version} == 9 || ${msg.version == 10} ) + connection()->bro_analyzer()->ProtocolConfirmation(); + if ( mysql_handshake ) { if ( ${msg.version} == 10 ) diff --git a/src/analyzer/protocol/smtp/SMTP.cc b/src/analyzer/protocol/smtp/SMTP.cc index 6a19848d86..efc55ecc74 100644 --- a/src/analyzer/protocol/smtp/SMTP.cc +++ b/src/analyzer/protocol/smtp/SMTP.cc @@ -809,7 +809,7 @@ void SMTP_Analyzer::ProcessExtension(int ext_len, const char* ext) if ( ! ext ) return; - if ( ! strcasecmp_n(ext_len, ext, "PIPELINING") ) + if ( ! strncasecmp(ext, "PIPELINING", ext_len) ) pipelining = 1; } @@ -819,7 +819,7 @@ int SMTP_Analyzer::ParseCmd(int cmd_len, const char* cmd) return -1; for ( int code = SMTP_CMD_EHLO; code < SMTP_CMD_LAST; ++code ) - if ( ! strcasecmp_n(cmd_len, cmd, smtp_cmd_word[code - SMTP_CMD_EHLO]) ) + if ( ! strncasecmp(cmd, smtp_cmd_word[code - SMTP_CMD_EHLO], cmd_len) ) return code; return -1; diff --git a/src/bro.bif b/src/bro.bif index b0465b9609..2c55c2bc95 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1031,6 +1031,72 @@ function clear_table%(v: any%): any return 0; %} +## Gets all subnets that contain a given subnet from a set/table[subnet] +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: All the keys of the set or table that cover the subnet searched for. +function matching_subnets%(search: subnet, t: any%): subnet_vec + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("matching_subnets needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + return t->AsTableVal()->LookupSubnets(search); + %} + +## For a set[subnet]/table[subnet], create a new table that contains all entries that +## contain a given subnet. +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: A new table that contains all the entries that cover the subnet searched for. +function filter_subnet_table%(search: subnet, t: any%): any + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("filter_subnet_table needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + return t->AsTableVal()->LookupSubnetValues(search); + %} + +## Checks if a specific subnet is a member of a set/table[subnet]. +## In difference to the ``in`` operator, this performs an exact match, not +## a longest prefix match. +## +## search: the subnet to search for. +## +## t: the set[subnet] or table[subnet]. +## +## Returns: True if the exact subnet is a member, false otherwise. +function check_subnet%(search: subnet, t: any%): bool + %{ + if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) + { + reporter->Error("check_subnet needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + const PrefixTable* pt = t->AsTableVal()->Subnets(); + if ( ! pt ) + { + reporter->Error("check_subnet encountered nonexisting prefix table."); + return nullptr; + } + + void* res = pt->Lookup(search, true); + + return new Val (res != nullptr, TYPE_BOOL); + %} + ## Checks whether two objects reference the same internal object. This function ## uses equality comparison of C++ raw pointer values to determine if the two ## objects are the same. @@ -2078,6 +2144,33 @@ function is_v6_addr%(a: addr%): bool return new Val(0, TYPE_BOOL); %} +## Returns whether a subnet specification is IPv4 or not. +## +## s: the subnet to check. +## +## Returns: true if *a* is an IPv4 subnet, else false. +function is_v4_subnet%(s: subnet%): bool + %{ + if ( s->AsSubNet().Prefix().GetFamily() == IPv4 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + +## Returns whether a subnet specification is IPv6 or not. +## +## s: the subnet to check. +## +## Returns: true if *a* is an IPv6 subnet, else false. +function is_v6_subnet%(s: subnet%): bool + %{ + if ( s->AsSubNet().Prefix().GetFamily() == IPv6 ) + return new Val(1, TYPE_BOOL); + else + return new Val(0, TYPE_BOOL); + %} + + # =========================================================================== # # Conversion @@ -2368,6 +2461,44 @@ function to_subnet%(sn: string%): subnet return ret; %} +## Converts a :bro:type:`addr` to a :bro:type:`subnet`. +## +## a: The address to convert. +## +## Returns: The *a* address as a :bro:type:`subnet`. +## +## .. bro:see:: to_subset +function addr_to_subnet%(a: addr%): subnet + %{ + int width = (a->AsAddr().GetFamily() == IPv4 ? 32 : 128); + return new SubNetVal(a->AsAddr(), width); + %} + +## Converts a :bro:type:`subnet` to a :bro:type:`addr` by +## extracting the prefix. +## +## s: The subnet to convert. +## +## Returns: The *s* subnet as a :bro:type:`addr`. +## +## .. bro:see:: to_subset +function subnet_to_addr%(sn: subnet%): addr + %{ + return new AddrVal(sn->Prefix()); + %} + +## Returns the width of a :bro:type:`subnet`. +## +## s: The subnet to convert. +## +## Returns: The width of the subnet. +## +## .. bro:see:: to_subset +function subnet_width%(sn: subnet%): count + %{ + return new Val(sn->Width(), TYPE_COUNT); + %} + ## Converts a :bro:type:`string` to a :bro:type:`double`. ## ## str: The :bro:type:`string` to convert. diff --git a/src/broker/CMakeLists.txt b/src/broker/CMakeLists.txt index 7329bfd46e..988855cafb 100644 --- a/src/broker/CMakeLists.txt +++ b/src/broker/CMakeLists.txt @@ -10,8 +10,8 @@ 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}) +include_directories(BEFORE ${CAF_INCLUDE_DIR_CORE}) +include_directories(BEFORE ${CAF_INCLUDE_DIR_IO}) set(comm_SRCS Data.cc diff --git a/src/patricia.c b/src/patricia.c index c4815b40ec..552019be09 100644 --- a/src/patricia.c +++ b/src/patricia.c @@ -1,3 +1,8 @@ +/* + * Johanna Amann + * + * Added patricia_search_all function. + */ /* * Dave Plonka * @@ -61,6 +66,7 @@ static char copyright[] = #include /* memcpy, strchr, strlen */ #include /* for inet_addr */ #include /* for u_short, etc. */ +#include #include "patricia.h" @@ -561,6 +567,105 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix) return (NULL); } +bool +patricia_search_all (patricia_tree_t *patricia, prefix_t *prefix, patricia_node_t ***list, int *n) +{ + patricia_node_t *node; + patricia_node_t *stack[PATRICIA_MAXBITS + 1]; + u_char *addr; + u_int bitlen; + int cnt = 0; + + assert (patricia); + assert (prefix); + assert (prefix->bitlen <= patricia->maxbits); + assert (n); + assert (list); + assert (*list == NULL); + + *n = 0; + + if (patricia->head == NULL) + return (NULL); + + node = patricia->head; + addr = prefix_touchar (prefix); + bitlen = prefix->bitlen; + + while (node->bit < bitlen) { + + if (node->prefix) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: push %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + stack[cnt++] = node; + } + + if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { +#ifdef PATRICIA_DEBUG + if (node->prefix) + fprintf (stderr, "patricia_search_all: take right %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: take right at %d\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->r; + } else { +#ifdef PATRICIA_DEBUG + if (node->prefix) + fprintf (stderr, "patricia_search_all: take left %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: take left at %d\n", + node->bit); +#endif /* PATRICIA_DEBUG */ + node = node->l; + } + + if (node == NULL) + break; + } + + if (node && node->prefix) + stack[cnt++] = node; + +#ifdef PATRICIA_DEBUG + if (node == NULL) + fprintf (stderr, "patricia_search_all: stop at null\n"); + else if (node->prefix) + fprintf (stderr, "patricia_search_all: stop at %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); + else + fprintf (stderr, "patricia_search_all: stop at %d\n", node->bit); +#endif /* PATRICIA_DEBUG */ + + if (cnt <= 0) + return false; + + // ok, now we have an upper bound of how much we can return. Let's just alloc that... + patricia_node_t **outlist = calloc(cnt, sizeof(patricia_node_t*)); + + while (--cnt >= 0) { + node = stack[cnt]; +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: pop %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + if (comp_with_mask (prefix_tochar (node->prefix), prefix_tochar (prefix), node->prefix->bitlen)) { +#ifdef PATRICIA_DEBUG + fprintf (stderr, "patricia_search_all: found %s/%d\n", + prefix_toa (node->prefix), node->prefix->bitlen); +#endif /* PATRICIA_DEBUG */ + outlist[*n] = node; + (*n)++; + } + } + *list = outlist; + return (*n == 0); +} + /* if inclusive != 0, "best" may be the given prefix itself */ patricia_node_t * diff --git a/src/patricia.h b/src/patricia.h index dc67226362..3a9badd29a 100644 --- a/src/patricia.h +++ b/src/patricia.h @@ -104,6 +104,7 @@ typedef struct _patricia_tree_t { patricia_node_t *patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix); +bool patricia_search_all (patricia_tree_t *patricia, prefix_t *prefix, patricia_node_t ***list, int *n); patricia_node_t *patricia_search_best (patricia_tree_t *patricia, prefix_t *prefix); patricia_node_t * patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inclusive); diff --git a/src/util.cc b/src/util.cc index 6a03859a3c..0ea89beb90 100644 --- a/src/util.cc +++ b/src/util.cc @@ -323,24 +323,6 @@ string to_upper(const std::string& s) return t; } -const char* strchr_n(const char* s, const char* end_of_s, char ch) - { - for ( ; s < end_of_s; ++s ) - if ( *s == ch ) - return s; - - return 0; - } - -const char* strrchr_n(const char* s, const char* end_of_s, char ch) - { - for ( --end_of_s; end_of_s >= s; --end_of_s ) - if ( *end_of_s == ch ) - return end_of_s; - - return 0; - } - int decode_hex(char ch) { if ( ch >= '0' && ch <= '9' ) @@ -382,27 +364,6 @@ const char* strpbrk_n(size_t len, const char* s, const char* charset) return 0; } -int strcasecmp_n(int b_len, const char* b, const char* t) - { - if ( ! b ) - return -1; - - int i; - for ( i = 0; i < b_len; ++i ) - { - char c1 = islower(b[i]) ? toupper(b[i]) : b[i]; - char c2 = islower(t[i]) ? toupper(t[i]) : t[i]; - - if ( c1 < c2 ) - return -1; - - if ( c1 > c2 ) - return 1; - } - - return t[i] != '\0'; - } - #ifndef HAVE_STRCASESTR // This code is derived from software contributed to BSD by Chris Torek. char* strcasestr(const char* s, const char* find) @@ -421,7 +382,7 @@ char* strcasestr(const char* s, const char* find) if ( sc == 0 ) return 0; } while ( char(tolower((unsigned char) sc)) != c ); - } while ( strcasecmp_n(len, s, find) != 0 ); + } while ( strncasecmp(s, find, len) != 0 ); --s; } diff --git a/src/util.h b/src/util.h index 901bb44d1c..15d1a059cd 100644 --- a/src/util.h +++ b/src/util.h @@ -143,11 +143,8 @@ extern char* get_word(char*& s); extern void get_word(int length, const char* s, int& pwlen, const char*& pw); extern void to_upper(char* s); extern std::string to_upper(const std::string& s); -extern const char* strchr_n(const char* s, const char* end_of_s, char ch); -extern const char* strrchr_n(const char* s, const char* end_of_s, char ch); extern int decode_hex(char ch); extern unsigned char encode_hex(int h); -extern int strcasecmp_n(int s_len, const char* s, const char* t); #ifndef HAVE_STRCASESTR extern char* strcasestr(const char* s, const char* find); #endif diff --git a/testing/btest/Baseline/bifs.check_subnet/output b/testing/btest/Baseline/bifs.check_subnet/output new file mode 100644 index 0000000000..d2f111f555 --- /dev/null +++ b/testing/btest/Baseline/bifs.check_subnet/output @@ -0,0 +1,8 @@ +in says: 10.2.0.2/32 is member +check_subnet says: 10.2.0.2/32 is no member +in says: 10.2.0.2/31 is member +check_subnet says: 10.2.0.2/31 is member +in says: 10.0.0.0/9 is member +check_subnet says: 10.0.0.0/9 is no member +in says: 10.0.0.0/8 is member +check_subnet says: 10.0.0.0/8 is member diff --git a/testing/btest/Baseline/bifs.filter_subnet_table/output b/testing/btest/Baseline/bifs.filter_subnet_table/output new file mode 100644 index 0000000000..d86ca621a5 --- /dev/null +++ b/testing/btest/Baseline/bifs.filter_subnet_table/output @@ -0,0 +1,20 @@ +{ +10.0.0.0/8, +10.2.0.2/31, +10.2.0.0/16 +} +{ +[10.0.0.0/8] = a, +[10.2.0.2/31] = c, +[10.2.0.0/16] = b +} +{ +[10.0.0.0/8] = a, +[10.3.0.0/16] = e +} +{ + +} +{ + +} diff --git a/testing/btest/Baseline/bifs.matching_subnets/output b/testing/btest/Baseline/bifs.matching_subnets/output new file mode 100644 index 0000000000..e051d89b79 --- /dev/null +++ b/testing/btest/Baseline/bifs.matching_subnets/output @@ -0,0 +1,18 @@ +{ +10.0.0.0/8, +10.3.0.0/16, +10.2.0.2/31, +2607:f8b0:4007:807::/64, +10.2.0.0/16, +5.2.0.0/32, +5.5.0.0/25, +10.1.0.0/16, +5.0.0.0/8, +2607:f8b0:4007:807::200e/128, +7.2.0.0/32, +2607:f8b0:4008:807::/64 +} +[10.2.0.2/31, 10.2.0.0/16, 10.0.0.0/8] +[2607:f8b0:4007:807::200e/128, 2607:f8b0:4007:807::/64] +[] +[10.0.0.0/8] diff --git a/testing/btest/Baseline/bifs.subnet_to_addr/error b/testing/btest/Baseline/bifs.subnet_to_addr/error new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/bifs.subnet_to_addr/output b/testing/btest/Baseline/bifs.subnet_to_addr/output new file mode 100644 index 0000000000..8c89b3920a --- /dev/null +++ b/testing/btest/Baseline/bifs.subnet_to_addr/output @@ -0,0 +1,3 @@ +subnet_to_addr(0.0.0.0/32) = 0.0.0.0 (SUCCESS) +subnet_to_addr(1.2.0.0/16) = 1.2.0.0 (SUCCESS) +subnet_to_addr(2607:f8b0:4005:803::200e/128) = 2607:f8b0:4005:803::200e (SUCCESS) diff --git a/testing/btest/Baseline/bifs.subnet_version/out b/testing/btest/Baseline/bifs.subnet_version/out new file mode 100644 index 0000000000..328bff6687 --- /dev/null +++ b/testing/btest/Baseline/bifs.subnet_version/out @@ -0,0 +1,4 @@ +T +F +F +T 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 6a240c88ad..85fe19eb96 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 2015-08-31-05-07-15 +#open 2016-02-17-20-30-50 #fields name #types string scripts/base/init-bare.bro @@ -188,6 +188,30 @@ scripts/base/init-default.bro scripts/base/frameworks/sumstats/non-cluster.bro scripts/base/frameworks/tunnels/__load__.bro scripts/base/frameworks/tunnels/main.bro + scripts/base/frameworks/openflow/__load__.bro + scripts/base/frameworks/openflow/consts.bro + scripts/base/frameworks/openflow/types.bro + scripts/base/frameworks/openflow/main.bro + scripts/base/frameworks/openflow/plugins/__load__.bro + scripts/base/frameworks/openflow/plugins/ryu.bro + scripts/base/utils/json.bro + scripts/base/frameworks/openflow/plugins/log.bro + scripts/base/frameworks/openflow/plugins/broker.bro + scripts/base/frameworks/openflow/non-cluster.bro + scripts/base/frameworks/netcontrol/__load__.bro + scripts/base/frameworks/netcontrol/types.bro + scripts/base/frameworks/netcontrol/main.bro + scripts/base/frameworks/netcontrol/plugin.bro + scripts/base/frameworks/netcontrol/plugins/__load__.bro + scripts/base/frameworks/netcontrol/plugins/debug.bro + scripts/base/frameworks/netcontrol/plugins/openflow.bro + scripts/base/frameworks/netcontrol/plugins/packetfilter.bro + scripts/base/frameworks/netcontrol/plugins/broker.bro + scripts/base/frameworks/netcontrol/plugins/acld.bro + scripts/base/frameworks/netcontrol/drop.bro + scripts/base/frameworks/netcontrol/shunt.bro + scripts/base/frameworks/netcontrol/catch-and-release.bro + scripts/base/frameworks/netcontrol/non-cluster.bro scripts/base/protocols/conn/__load__.bro scripts/base/protocols/conn/main.bro scripts/base/protocols/conn/contents.bro @@ -273,4 +297,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 2015-08-31-05-07-15 +#close 2016-02-17-20-30-50 diff --git a/testing/btest/Baseline/coverage.find-bro-logs/out b/testing/btest/Baseline/coverage.find-bro-logs/out index 3deca99848..0b2a9445c1 100644 --- a/testing/btest/Baseline/coverage.find-bro-logs/out +++ b/testing/btest/Baseline/coverage.find-bro-logs/out @@ -23,8 +23,12 @@ loaded_scripts modbus modbus_register_change mysql +net_control +netcontrol_drop +netcontrol_shunt notice notice_alarm +open_flow packet_filter pe radius diff --git a/testing/btest/Baseline/coverage.init-default/missing_loads b/testing/btest/Baseline/coverage.init-default/missing_loads index b5fbf644d5..826ca4af87 100644 --- a/testing/btest/Baseline/coverage.init-default/missing_loads +++ b/testing/btest/Baseline/coverage.init-default/missing_loads @@ -3,6 +3,8 @@ -./frameworks/cluster/nodes/worker.bro -./frameworks/cluster/setup-connections.bro -./frameworks/intel/cluster.bro +-./frameworks/netcontrol/cluster.bro -./frameworks/notice/cluster.bro +-./frameworks/openflow/cluster.bro -./frameworks/packet-filter/cluster.bro -./frameworks/sumstats/cluster.bro diff --git a/testing/btest/Baseline/language.expire_multiple-2/output b/testing/btest/Baseline/language.expire_multiple-2/output new file mode 100644 index 0000000000..ffcdb6ff80 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple-2/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple-2/expire_multiple.test, line 2: set/table can only have one of &read_expire, &write_expire, &create_expire (&write_expire=1.0 sec, &create_expire=3.0 secs) diff --git a/testing/btest/Baseline/language.expire_multiple-3/output b/testing/btest/Baseline/language.expire_multiple-3/output new file mode 100644 index 0000000000..1dc2e3e765 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple-3/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple-3/expire_multiple.test, line 2: set/table can only have one of &read_expire, &write_expire, &create_expire (&write_expire=1.0 sec, &read_expire=3.0 secs) diff --git a/testing/btest/Baseline/language.expire_multiple/output b/testing/btest/Baseline/language.expire_multiple/output new file mode 100644 index 0000000000..a616c84de7 --- /dev/null +++ b/testing/btest/Baseline/language.expire_multiple/output @@ -0,0 +1 @@ +error in /Users/johanna/bro/master/testing/btest/.tmp/language.expire_multiple/expire_multiple.test, line 4: set/table can only have one of &read_expire, &write_expire, &create_expire (&create_expire=1.0 sec, &read_expire=1.0 sec) diff --git a/testing/btest/Baseline/language.expire_subnet/output b/testing/btest/Baseline/language.expire_subnet/output new file mode 100644 index 0000000000..70ca3943cb --- /dev/null +++ b/testing/btest/Baseline/language.expire_subnet/output @@ -0,0 +1,27 @@ +All: +0 --> zero +2 --> two +4 --> four +1 --> one +3 --> three +192.168.3.0/24 --> three +192.168.0.0/16 --> zero +192.168.4.0/24 --> four +192.168.1.0/24 --> one +192.168.2.0/24 --> two +Time: 0 secs + +Accessed table nums: two; three +Accessed table nets: two; three, zero +Time: 7.0 secs 518.0 msecs 828.0 usecs + +Expired Num: 0 --> zero at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 4 --> four at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 1 --> one at 8.0 secs 835.0 msecs 30.0 usecs +Expired Subnet: 192.168.4.0/24 --> four at 8.0 secs 835.0 msecs 30.0 usecs +Expired Subnet: 192.168.1.0/24 --> one at 8.0 secs 835.0 msecs 30.0 usecs +Expired Num: 2 --> two at 15.0 secs 150.0 msecs 681.0 usecs +Expired Num: 3 --> three at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.3.0/24 --> three at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.0.0/16 --> zero at 15.0 secs 150.0 msecs 681.0 usecs +Expired Subnet: 192.168.2.0/24 --> two at 15.0 secs 150.0 msecs 681.0 usecs diff --git a/testing/btest/Baseline/language.record-function-recursion/out b/testing/btest/Baseline/language.record-function-recursion/out new file mode 100644 index 0000000000..b143d5339b --- /dev/null +++ b/testing/btest/Baseline/language.record-function-recursion/out @@ -0,0 +1,2 @@ +[id=, inner=] +record { id:count; inner:record { create:function(input:;) : string; }; } diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 7a5718b1db..25808a20d8 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -164,8 +164,12 @@ 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, 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=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, 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=notice_alarm, 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=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> +0.000000 MetaHookPost CallFunction(Log::__add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> 0.000000 MetaHookPost CallFunction(Log::__add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, 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=packet_filter, 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=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) -> @@ -199,8 +203,12 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) -> +0.000000 MetaHookPost CallFunction(Log::__create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) -> @@ -220,7 +228,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1457718658.75999, 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)) -> @@ -235,8 +243,12 @@ 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Intel::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (KRB::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Modbus::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::DROP)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::LOG)) -> +0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (NetControl::SHUNT)) -> 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, , (OpenFlow::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (PE::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (PacketFilter::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (RADIUS::LOG)) -> @@ -270,8 +282,12 @@ 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, , (KRB::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, , (NetControl::DROP, [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, , (NetControl::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, , (NetControl::SHUNT, [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, , (OpenFlow::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, , (PE::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={}])) -> @@ -305,8 +321,12 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) -> +0.000000 MetaHookPost CallFunction(Log::create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) -> @@ -326,7 +346,9 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(NetControl::check_plugins, , ()) -> +0.000000 MetaHookPost CallFunction(NetControl::init, , ()) -> 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, )) -> @@ -361,6 +383,7 @@ 0.000000 MetaHookPost CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) -> 0.000000 MetaHookPost DrainEvents() -> 0.000000 MetaHookPost LoadFile(../main) -> -1 +0.000000 MetaHookPost LoadFile(../plugin) -> -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 @@ -434,13 +457,16 @@ 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(./acld) -> -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(./broker) -> -1 0.000000 MetaHookPost LoadFile(./broxygen.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./cardinality-counter.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./catch-and-release) -> -1 0.000000 MetaHookPost LoadFile(./comm.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./const.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./consts) -> -1 @@ -448,6 +474,8 @@ 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(./debug) -> -1 +0.000000 MetaHookPost LoadFile(./drop) -> -1 0.000000 MetaHookPost LoadFile(./entities) -> -1 0.000000 MetaHookPost LoadFile(./event.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./exec) -> -1 @@ -463,6 +491,7 @@ 0.000000 MetaHookPost LoadFile(./input) -> -1 0.000000 MetaHookPost LoadFile(./input.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./last) -> -1 +0.000000 MetaHookPost LoadFile(./log) -> -1 0.000000 MetaHookPost LoadFile(./logging.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./magic) -> -1 0.000000 MetaHookPost LoadFile(./main) -> -1 @@ -473,14 +502,19 @@ 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(./openflow) -> -1 +0.000000 MetaHookPost LoadFile(./packetfilter) -> -1 0.000000 MetaHookPost LoadFile(./patterns) -> -1 +0.000000 MetaHookPost LoadFile(./plugin) -> -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(./ryu) -> -1 0.000000 MetaHookPost LoadFile(./sample) -> -1 0.000000 MetaHookPost LoadFile(./scp) -> -1 0.000000 MetaHookPost LoadFile(./sftp) -> -1 +0.000000 MetaHookPost LoadFile(./shunt) -> -1 0.000000 MetaHookPost LoadFile(./site) -> -1 0.000000 MetaHookPost LoadFile(./std-dev) -> -1 0.000000 MetaHookPost LoadFile(./store.bif.bro) -> -1 @@ -489,6 +523,7 @@ 0.000000 MetaHookPost LoadFile(./thresholds) -> -1 0.000000 MetaHookPost LoadFile(./top-k.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./topk) -> -1 +0.000000 MetaHookPost LoadFile(./types) -> -1 0.000000 MetaHookPost LoadFile(./types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./types.bro) -> -1 0.000000 MetaHookPost LoadFile(./unique) -> -1 @@ -548,14 +583,17 @@ 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<...>/json) -> -1 0.000000 MetaHookPost LoadFile(base<...>/krb) -> -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<...>/mysql) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/netcontrol) -> -1 0.000000 MetaHookPost LoadFile(base<...>/notice) -> -1 0.000000 MetaHookPost LoadFile(base<...>/numbers) -> -1 +0.000000 MetaHookPost LoadFile(base<...>/openflow) -> -1 0.000000 MetaHookPost LoadFile(base<...>/packet-filter) -> -1 0.000000 MetaHookPost LoadFile(base<...>/paths) -> -1 0.000000 MetaHookPost LoadFile(base<...>/patterns) -> -1 @@ -588,6 +626,7 @@ 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(NetControl::init()) -> false 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)) @@ -756,8 +795,12 @@ 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, 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=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, 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=notice_alarm, 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=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) +0.000000 MetaHookPre CallFunction(Log::__add_filter, , (OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) 0.000000 MetaHookPre CallFunction(Log::__add_filter, , (PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, 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=packet_filter, 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=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}])) @@ -791,8 +834,12 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) +0.000000 MetaHookPre CallFunction(Log::__create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) @@ -812,7 +859,7 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1457718658.75999, 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)) @@ -827,8 +874,12 @@ 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Intel::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (KRB::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Modbus::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::DROP)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::LOG)) +0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (NetControl::SHUNT)) 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, , (OpenFlow::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (PE::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (PacketFilter::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (RADIUS::LOG)) @@ -862,8 +913,12 @@ 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, , (KRB::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, , (NetControl::DROP, [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, , (NetControl::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, , (NetControl::SHUNT, [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, , (OpenFlow::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, , (PE::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={}])) @@ -897,8 +952,12 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Intel::LOG, [columns=, ev=Intel::log_intel, path=intel])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Notice::LOG, [columns=, ev=Notice::log_notice, path=notice])) +0.000000 MetaHookPre CallFunction(Log::create_stream, , (OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (PE::LOG, [columns=, ev=PE::log_pe, path=pe])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (PacketFilter::LOG, [columns=, ev=, path=packet_filter])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius])) @@ -918,7 +977,9 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(NetControl::check_plugins, , ()) +0.000000 MetaHookPre CallFunction(NetControl::init, , ()) 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, )) @@ -953,6 +1014,7 @@ 0.000000 MetaHookPre CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) 0.000000 MetaHookPre DrainEvents() 0.000000 MetaHookPre LoadFile(../main) +0.000000 MetaHookPre LoadFile(../plugin) 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) @@ -1026,13 +1088,16 @@ 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(./acld) 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(./broker) 0.000000 MetaHookPre LoadFile(./broxygen.bif.bro) 0.000000 MetaHookPre LoadFile(./cardinality-counter.bif.bro) +0.000000 MetaHookPre LoadFile(./catch-and-release) 0.000000 MetaHookPre LoadFile(./comm.bif.bro) 0.000000 MetaHookPre LoadFile(./const.bif.bro) 0.000000 MetaHookPre LoadFile(./consts) @@ -1040,6 +1105,8 @@ 0.000000 MetaHookPre LoadFile(./contents) 0.000000 MetaHookPre LoadFile(./data.bif.bro) 0.000000 MetaHookPre LoadFile(./dcc-send) +0.000000 MetaHookPre LoadFile(./debug) +0.000000 MetaHookPre LoadFile(./drop) 0.000000 MetaHookPre LoadFile(./entities) 0.000000 MetaHookPre LoadFile(./event.bif.bro) 0.000000 MetaHookPre LoadFile(./exec) @@ -1055,6 +1122,7 @@ 0.000000 MetaHookPre LoadFile(./input) 0.000000 MetaHookPre LoadFile(./input.bif.bro) 0.000000 MetaHookPre LoadFile(./last) +0.000000 MetaHookPre LoadFile(./log) 0.000000 MetaHookPre LoadFile(./logging.bif.bro) 0.000000 MetaHookPre LoadFile(./magic) 0.000000 MetaHookPre LoadFile(./main) @@ -1065,14 +1133,19 @@ 0.000000 MetaHookPre LoadFile(./mozilla-ca-list) 0.000000 MetaHookPre LoadFile(./netstats) 0.000000 MetaHookPre LoadFile(./non-cluster) +0.000000 MetaHookPre LoadFile(./openflow) +0.000000 MetaHookPre LoadFile(./packetfilter) 0.000000 MetaHookPre LoadFile(./patterns) +0.000000 MetaHookPre LoadFile(./plugin) 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(./ryu) 0.000000 MetaHookPre LoadFile(./sample) 0.000000 MetaHookPre LoadFile(./scp) 0.000000 MetaHookPre LoadFile(./sftp) +0.000000 MetaHookPre LoadFile(./shunt) 0.000000 MetaHookPre LoadFile(./site) 0.000000 MetaHookPre LoadFile(./std-dev) 0.000000 MetaHookPre LoadFile(./store.bif.bro) @@ -1081,6 +1154,7 @@ 0.000000 MetaHookPre LoadFile(./thresholds) 0.000000 MetaHookPre LoadFile(./top-k.bif.bro) 0.000000 MetaHookPre LoadFile(./topk) +0.000000 MetaHookPre LoadFile(./types) 0.000000 MetaHookPre LoadFile(./types.bif.bro) 0.000000 MetaHookPre LoadFile(./types.bro) 0.000000 MetaHookPre LoadFile(./unique) @@ -1140,14 +1214,17 @@ 0.000000 MetaHookPre LoadFile(base<...>/input.bif) 0.000000 MetaHookPre LoadFile(base<...>/intel) 0.000000 MetaHookPre LoadFile(base<...>/irc) +0.000000 MetaHookPre LoadFile(base<...>/json) 0.000000 MetaHookPre LoadFile(base<...>/krb) 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<...>/mysql) +0.000000 MetaHookPre LoadFile(base<...>/netcontrol) 0.000000 MetaHookPre LoadFile(base<...>/notice) 0.000000 MetaHookPre LoadFile(base<...>/numbers) +0.000000 MetaHookPre LoadFile(base<...>/openflow) 0.000000 MetaHookPre LoadFile(base<...>/packet-filter) 0.000000 MetaHookPre LoadFile(base<...>/paths) 0.000000 MetaHookPre LoadFile(base<...>/patterns) @@ -1180,6 +1257,7 @@ 0.000000 MetaHookPre LoadFile(base<...>/urls) 0.000000 MetaHookPre LoadFile(base<...>/utils) 0.000000 MetaHookPre LoadFile(base<...>/x509) +0.000000 MetaHookPre QueueEvent(NetControl::init()) 0.000000 MetaHookPre QueueEvent(bro_init()) 0.000000 MetaHookPre QueueEvent(filter_change_tracking()) 0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_BACKDOOR) @@ -1347,8 +1425,12 @@ 0.000000 | HookCallFunction Log::__add_filter(Intel::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=intel, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(KRB::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=kerberos, 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=modbus, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::DROP, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_drop, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(NetControl::SHUNT, [name=default, writer=Log::WRITER_ASCII, pred=, path=netcontrol_shunt, 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=notice_alarm, 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=notice, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) +0.000000 | HookCallFunction Log::__add_filter(OpenFlow::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=openflow, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) 0.000000 | HookCallFunction Log::__add_filter(PE::LOG, [name=default, writer=Log::WRITER_ASCII, pred=, path=pe, 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=packet_filter, 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=radius, path_func=, include=, exclude=, log_local=T, log_remote=T, interv=0 secs, postprocessor=, config={}]) @@ -1382,8 +1464,12 @@ 0.000000 | HookCallFunction Log::__create_stream(Intel::LOG, [columns=, ev=Intel::log_intel, path=intel]) 0.000000 | HookCallFunction Log::__create_stream(KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos]) 0.000000 | HookCallFunction Log::__create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol]) +0.000000 | HookCallFunction Log::__create_stream(NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt]) 0.000000 | HookCallFunction Log::__create_stream(Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm]) 0.000000 | HookCallFunction Log::__create_stream(Notice::LOG, [columns=, ev=Notice::log_notice, path=notice]) +0.000000 | HookCallFunction Log::__create_stream(OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow]) 0.000000 | HookCallFunction Log::__create_stream(PE::LOG, [columns=, ev=PE::log_pe, path=pe]) 0.000000 | HookCallFunction Log::__create_stream(PacketFilter::LOG, [columns=, ev=, path=packet_filter]) 0.000000 | HookCallFunction Log::__create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius]) @@ -1403,7 +1489,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1457718658.75999, 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) @@ -1418,8 +1504,12 @@ 0.000000 | HookCallFunction Log::add_default_filter(Intel::LOG) 0.000000 | HookCallFunction Log::add_default_filter(KRB::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Modbus::LOG) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::DROP) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::LOG) +0.000000 | HookCallFunction Log::add_default_filter(NetControl::SHUNT) 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(OpenFlow::LOG) 0.000000 | HookCallFunction Log::add_default_filter(PE::LOG) 0.000000 | HookCallFunction Log::add_default_filter(PacketFilter::LOG) 0.000000 | HookCallFunction Log::add_default_filter(RADIUS::LOG) @@ -1453,8 +1543,12 @@ 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(KRB::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(NetControl::DROP, [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(NetControl::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(NetControl::SHUNT, [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(OpenFlow::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(PE::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={}]) @@ -1488,8 +1582,12 @@ 0.000000 | HookCallFunction Log::create_stream(Intel::LOG, [columns=, ev=Intel::log_intel, path=intel]) 0.000000 | HookCallFunction Log::create_stream(KRB::LOG, [columns=, ev=KRB::log_krb, path=kerberos]) 0.000000 | HookCallFunction Log::create_stream(Modbus::LOG, [columns=, ev=Modbus::log_modbus, path=modbus]) +0.000000 | HookCallFunction Log::create_stream(NetControl::DROP, [columns=, ev=NetControl::log_netcontrol_drop, path=netcontrol_drop]) +0.000000 | HookCallFunction Log::create_stream(NetControl::LOG, [columns=, ev=NetControl::log_netcontrol, path=netcontrol]) +0.000000 | HookCallFunction Log::create_stream(NetControl::SHUNT, [columns=, ev=NetControl::log_netcontrol_shunt, path=netcontrol_shunt]) 0.000000 | HookCallFunction Log::create_stream(Notice::ALARM_LOG, [columns=, ev=, path=notice_alarm]) 0.000000 | HookCallFunction Log::create_stream(Notice::LOG, [columns=, ev=Notice::log_notice, path=notice]) +0.000000 | HookCallFunction Log::create_stream(OpenFlow::LOG, [columns=, ev=OpenFlow::log_openflow, path=openflow]) 0.000000 | HookCallFunction Log::create_stream(PE::LOG, [columns=, ev=PE::log_pe, path=pe]) 0.000000 | HookCallFunction Log::create_stream(PacketFilter::LOG, [columns=, ev=, path=packet_filter]) 0.000000 | HookCallFunction Log::create_stream(RADIUS::LOG, [columns=, ev=RADIUS::log_radius, path=radius]) @@ -1509,7 +1607,9 @@ 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1452883249.168544, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1457718658.75999, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction NetControl::check_plugins() +0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) @@ -1548,10 +1648,12 @@ 0.000000 | HookLoadFile <...>/bro 0.000000 | HookLoadFile base<...>/bif 0.000000 | HookLoadFile base<...>/bro +0.000000 | HookQueueEvent NetControl::init() 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(NetControl::check_conn, , (141.142.228.5)) -> 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={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) -> @@ -1562,6 +1664,7 @@ 1362692526.869344 MetaHookPost UpdateNetworkTime(1362692526.869344) -> 1362692526.869344 MetaHookPre BroObjDtor() 1362692526.869344 MetaHookPre CallFunction(ChecksumOffloading::check, , ()) +1362692526.869344 MetaHookPre CallFunction(NetControl::check_conn, , (141.142.228.5)) 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={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=])) @@ -1573,6 +1676,7 @@ 1362692526.869344 | HookBroObjDtor 1362692526.869344 | HookUpdateNetworkTime 1362692526.869344 1362692526.869344 | HookCallFunction ChecksumOffloading::check() +1362692526.869344 | HookCallFunction NetControl::check_conn(141.142.228.5) 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={}, history=, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=]) diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out new file mode 100644 index 0000000000..d36130b29b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out @@ -0,0 +1,7 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=nullzero, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=nonullzero, cookie=4, arg=192.168.18.50/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out new file mode 100644 index 0000000000..fd7f00bb7c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out new file mode 100644 index 0000000000..6890484529 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out @@ -0,0 +1,7 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=drop, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP, [command=restore, cookie=4, arg=192.168.18.50/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out new file mode 100644 index 0000000000..fd7f00bb7c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=, dst_h=74.125.239.97/32, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log new file mode 100644 index 0000000000..2811185c09 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log @@ -0,0 +1,26 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-10-49 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +1457565049.807080 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457565049.807080 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457565049.807080 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457565051.874738 worker-1:2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565051.874738 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565052.874916 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 1.000000 - Debug-All +1457565053.950376 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +#close 2016-03-09-23-10-54 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout new file mode 100644 index 0000000000..846bb1b653 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout @@ -0,0 +1,11 @@ +netcontrol debug (Debug-All): init +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.17.1/32, src_p=32/tcp, dst_h=192.168.17.2/32, dst_p=32/tcp, src_m=, dst_m=], ip=, mac=], expire=30.0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=1.1.2.2/32, mac=], expire=15.0 secs, priority=0, location=Hi there, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=1.2.3.4/32, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.17.1/32, src_p=32/tcp, dst_h=192.168.17.2/32, dst_p=32/tcp, src_m=, dst_m=], ip=, mac=], expire=30.0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=, dst_p=, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=6, cid=6, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::MODIFY, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=8.8.8.8/32, dst_p=53/udp, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=[src_h=, src_p=, dst_h=127.0.0.3, dst_p=, src_m=, dst_m=, redirect_port=], id=7, cid=7, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::MODIFY, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=8.8.8.8/32, src_p=53/udp, dst_h=127.0.0.2/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=[src_h=8.8.8.8, src_p=, dst_h=, dst_p=, src_m=, dst_m=, redirect_port=], id=8, cid=8, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=127.0.0.3/32, dst_p=80/tcp, src_m=, dst_m=], ip=, mac=], expire=15.0 secs, priority=5, location=, out_port=, mod=, id=9, cid=9, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::MAC, conn=, flow=, ip=, mac=FF:FF:FF:FF:FF:FF], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=10, cid=10, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=, src_m=FF:FF:FF:FF:FF:FF, dst_m=], ip=, mac=], expire=15.0 secs, priority=0, location=, out_port=, mod=, id=11, cid=11, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log new file mode 100644 index 0000000000..da4487f10f --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -0,0 +1,32 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-22-21-13 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +1457562073.119593 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457562073.119593 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457562073.119593 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457562073.119593 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 - - 0 30.000000 - Debug-All +1457562073.119593 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457562073.119593 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457562073.119593 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 -> 5 - 0 30.000000 - Debug-All +1457562073.119593 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457562073.119593 7 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 127.0.0.3/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 8 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->127.0.0.2/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 9 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457562073.119593 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457562073.119593 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457562073.119593 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 - - 0 30.000000 - Debug-All +1457562073.119593 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457562073.119593 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457562073.119593 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.17.1/32/32->192.168.17.2/32/32 -> 5 - 0 30.000000 - Debug-All +1457562073.119593 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457562073.119593 7 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 127.0.0.3/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 8 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->127.0.0.2/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 15.000000 - Debug-All +1457562073.119593 9 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457562073.119593 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457562073.119593 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +#close 2016-03-09-22-21-13 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log new file mode 100644 index 0000000000..e777e7655a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol_drop +#open 2016-02-17-20-21-38 +#fields ts rule_id orig_h orig_p resp_h resp_p expire location +#types time string addr port addr port interval string +1455740498.301865 3 1.1.2.2 - - - 15.000000 Hi there +#close 2016-02-17-20-21-38 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log new file mode 100644 index 0000000000..2f3dc11da7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol_shunt +#open 2016-02-17-19-21-47 +#fields ts rule_id f.src_h f.src_p f.dst_h f.dst_p expire location +#types time string addr port addr port interval string +1455736907.597588 2 192.168.17.1 32 192.168.17.2 32 30.000000 - +#close 2016-02-17-19-21-47 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out new file mode 100644 index 0000000000..3b02eef7c7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out @@ -0,0 +1,5 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +add_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP +remove_rule, 0, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +remove_rule, 0, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log new file mode 100644 index 0000000000..fb1381e291 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log @@ -0,0 +1,23 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-08-22-15-15 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Broker-bro/event/netcontroltest +0.000000 - NetControl::MESSAGE - - - - - - - waiting for plugins to initialize - - - - +1457475314.791475 - NetControl::MESSAGE - - - - - - - activation finished - - - Broker-bro/event/netcontroltest +1457475314.791475 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457475315.175411 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175411 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 2 NetControl::ERROR - - NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - Removal of non-existing rule 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1457475315.175443 3 NetControl::ERROR - - NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Removal of non-existing rule 0 36000.000000 - Broker-bro/event/netcontroltest +#close 2016-03-08-22-15-15 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out new file mode 100644 index 0000000000..31d94be31e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule added, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP +rule timeout, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP, [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=1470/tcp, dst_h=74.53.140.153/32, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], NetControl::DROP +rule timeout, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP, [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log new file mode 100644 index 0000000000..f3bd6fafe0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-42-34 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +1398529018.678276 3 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 3600.000000 Re-drop by catch-and-release - +1398529018.678276 4 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 86400.000000 Re-drop by catch-and-release - +1398529018.678276 5 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 604800.000000 Re-drop by catch-and-release - +1398529018.678276 6 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - discarded duplicate insertion 0 604800.000000 Re-drop by catch-and-release - +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +#close 2016-03-09-23-42-34 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout new file mode 100644 index 0000000000..7d21c082f7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout @@ -0,0 +1,19 @@ +netcontrol debug (Debug-All): init +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _added=F] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=0 secs, priority=5, location=, out_port=, mod=, id=4, cid=4, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=192.168.18.50/32, src_p=56981/tcp, dst_h=74.125.239.97/32, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=0 secs, priority=0, location=, out_port=5, mod=, id=5, cid=5, _plugin_ids={\x0a\x091\x0a}, _active_plugin_ids={\x0a\x091\x0a}, _added=T] +Dumping state +{ + +} +{ + +} +{ + +} diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log new file mode 100644 index 0000000000..780c3d9c64 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-06-58 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1394747126.854788 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - - 0 0.000000 - Debug-All +1394747126.854788 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - - 0 0.000000 - Debug-All +1394747129.505358 3 NetControl::RULE - NetControl::FAILED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.4.149/32 - discarded duplicate insertion 0 0.000000 - - +#close 2016-03-09-23-06-58 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out new file mode 100644 index 0000000000..b29ce14d29 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out @@ -0,0 +1,6 @@ +1 +[ty=NetControl::ADDRESS, conn=, flow=, ip=1.2.3.4/32, mac=] +0 +4 +[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=8.8.8.8/32, dst_p=53/udp, src_m=, dst_m=], ip=, mac=], NetControl::MODIFY +[ty=NetControl::FLOW, conn=, flow=[src_h=127.0.0.2/32, src_p=, dst_h=, dst_p=, src_m=, dst_m=], ip=, mac=], NetControl::DROP diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log new file mode 100644 index 0000000000..2936694e2a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -0,0 +1,16 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-15-50 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 - - 0 30.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 -> 5 - 0 30.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 - - 0 30.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/56981->74.125.239.97/32/443 -> 5 - 0 30.000000 - Debug-All +#close 2016-03-09-23-15-50 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log new file mode 100644 index 0000000000..986c1cd5a2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -0,0 +1,49 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-40-32 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 10 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 10 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529020.091883 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529020.091883 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529020.091883 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529020.091883 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529020.091883 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +1398529020.091883 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529020.091883 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Debug-All +1398529020.091883 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529020.091883 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529020.091883 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Debug-All +1398529020.091883 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529020.091883 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529020.091883 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/56981->74.125.239.97/32/443 -> 5 - 0 0.000000 - Openflow-Log-42 +#close 2016-03-09-23-40-32 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log new file mode 100644 index 0000000000..ead5d70ec7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log @@ -0,0 +1,21 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-03-09-23-40-54 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 74.125.239.97/32 56981 443 4398046511108 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - - 192.168.18.50/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511112 - OpenFlow::OFPFC_ADD 0 0 5 - - 1 4294967290 - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - - - 192.168.18.50/32 - - 4398046511113 - OpenFlow::OFPFC_ADD 0 0 5 - - 1 4294967290 - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 74.125.239.97/32 56981 443 4398046511114 - OpenFlow::OFPFC_ADD 0 0 0 - - 1 5 - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511108 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511110 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511111 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511112 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511113 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +1398529020.091883 42 - - - - - - - - - - - - 4398046511114 - OpenFlow::OFPFC_DELETE 0 0 0 - - 0 (empty) - - F - - - - - - - +#close 2016-03-09-23-40-54 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log new file mode 100644 index 0000000000..abab12a0c9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -0,0 +1,25 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-28-53 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1254722767.875996 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 30.000000 - Openflow-Log-42 +1254722767.875996 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 74.53.140.153/32 - - 0 15.000000 - Openflow-Log-42 +1254722767.875996 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - - 0 30.000000 - Openflow-Log-42 +1254722767.875996 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 74.53.140.153/32 - - 0 15.000000 - Openflow-Log-42 +1437831787.861602 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - - 0 30.000000 - Openflow-Log-42 +1437831787.861602 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.102/32 - - 0 15.000000 - Openflow-Log-42 +1437831787.861602 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - - 0 30.000000 - Openflow-Log-42 +1437831787.861602 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.102/32 - - 0 15.000000 - Openflow-Log-42 +1437831799.610433 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - - 0 30.000000 - Openflow-Log-42 +1437831799.610433 7 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 17.167.150.73/32 - - 0 15.000000 - Openflow-Log-42 +1437831799.610433 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - - 0 30.000000 - Openflow-Log-42 +1437831799.610433 7 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 17.167.150.73/32 - - 0 15.000000 - Openflow-Log-42 +#close 2016-03-09-23-28-53 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log new file mode 100644 index 0000000000..6cff86bdb2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-03-09-23-28-53 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511108 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 74.53.140.153/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 74.53.140.153/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.100/32 192.168.133.102/32 49648 25 4398046511112 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - - 192.168.133.102/32 - - - 4398046511114 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - - - 192.168.133.102/32 - - 4398046511115 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 192.168.133.100/32 17.167.150.73/32 49655 443 4398046511116 - OpenFlow::OFPFC_ADD 0 30 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - - 17.167.150.73/32 - - - 4398046511118 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - - - 17.167.150.73/32 - - 4398046511119 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +#close 2016-03-09-23-28-53 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log new file mode 100644 index 0000000000..f4674275e9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log @@ -0,0 +1,14 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2016-02-12-03-18-52 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1254722767.492060 CXWv6p3arKYeMETxOg 10.10.1.4 56166 10.10.1.1 53 udp dns 0.034025 34 100 SF - - 0 Dd 1 62 1 128 (empty) +1254722776.690444 CCvvfg3TEfuqmmG4bh 10.10.1.20 138 10.10.1.255 138 udp - - - - S0 - - 0 D 1 229 0 0 (empty) +1254722767.529046 CjhGID4nQcgTWjvg4c 10.10.1.4 1470 74.53.140.153 25 tcp - 0.346950 0 0 S1 - - 0 Sh 1 48 1 48 (empty) +1437831787.856895 CRJuHdVW0XPVINV8a 192.168.133.100 49648 192.168.133.102 25 tcp - 0.004707 0 0 S1 - - 0 Sh 1 64 1 60 (empty) +1437831776.764391 CsRx2w45OKnoww6xl4 192.168.133.100 49285 66.196.121.26 5050 tcp - 0.343008 41 0 OTH - - 0 Da 1 93 1 52 (empty) +#close 2016-02-12-03-18-52 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log new file mode 100644 index 0000000000..0da63fd6f5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log @@ -0,0 +1,21 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-08-22-48-10 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->*/* - - 0 36000.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 192.169.18.1/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->192.168.18.50/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->192.169.18.1/32/80 - - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->*/* - - 0 36000.000000 - Openflow-Log-42 +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->8.8.8.8/32/53 Src: _/_ (_) Dst: 192.169.18.1/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->192.168.18.50/32/* Src: 8.8.8.8/_ (_) Dst: _/_ (_) - 5 36000.000000 - Openflow-Log-42 +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 192.168.18.50/32/*->192.169.18.1/32/80 - - 5 36000.000000 - Openflow-Log-42 +#close 2016-03-08-22-48-10 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log new file mode 100644 index 0000000000..64d6cabaf5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-12-03-28-52 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1398529018.678276 42 - - - - - 2048 - - 192.168.18.50/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 36000 0 - - 1 (empty) - - F - - - - - - - +1398529018.678276 42 - - - - - 2048 - 17 192.168.18.50/32 8.8.8.8/32 - 53 4398046511110 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - 192.169.18.1 - - +1398529018.678276 42 - - - - - 2048 - 17 8.8.8.8/32 192.168.18.50/32 53 - 4398046511112 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - 8.8.8.8 - - - +1398529018.678276 42 - - - - - 2048 - 6 192.168.18.50/32 192.169.18.1/32 - 80 4398046511114 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - - - - +#close 2016-02-12-03-28-52 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log new file mode 100644 index 0000000000..957af822e2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log @@ -0,0 +1,17 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-03-09-23-06-49 +#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin +#types time string enum string enum string enum string string string string int interval string string +0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457564809.281931 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564809.281931 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +1457564810.695538 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 1.000000 - Debug-All +#close 2016-03-09-23-06-51 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out new file mode 100644 index 0000000000..ec3b038bd9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out @@ -0,0 +1,5 @@ +BrokerComm::incoming_connection_established +flow_clear, 42 +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=, nw_tos=, nw_proto=, nw_src=, nw_dst=, tp_src=, tp_dst=], [cookie=4398046511105, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0, out_port=, out_group=, flags=0, actions=[out_ports=[3, 7], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=2048, nw_tos=, nw_proto=6, nw_src=10.10.1.4/32, nw_dst=74.53.140.153/32, tp_src=1470, tp_dst=25], [cookie=4398046511146, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, actions=[out_ports=[], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] +got flow_mod, 42, [in_port=, dl_src=, dl_dst=, dl_vlan=, dl_vlan_pcp=, dl_type=2048, nw_tos=, nw_proto=6, nw_src=74.53.140.153/32, nw_dst=10.10.1.4/32, tp_src=25, tp_dst=1470], [cookie=4398046511146, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, actions=[out_ports=[], vlan_vid=, vlan_pcp=, vlan_strip=F, dl_src=, dl_dst=, nw_tos=, nw_src=, nw_dst=, tp_src=, tp_dst=]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out new file mode 100644 index 0000000000..d81ed49aee --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out @@ -0,0 +1,8 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +Flow_mod_success +Flow_mod_failure +connection established +Flow_mod_success +Flow_mod_failure +Flow_mod_success +Flow_mod_failure diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log new file mode 100644 index 0000000000..eed7c20caf --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -0,0 +1,16 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-11-20-32-05 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +0.000000 42 - - - - - - - - - - - - 4398046511105 - OpenFlow::OFPFC_ADD 0 0 0 - - 0 3,7 - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511147 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 1470 4398046511147 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.100/32 192.168.133.102/32 49648 25 4398046511148 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - 6 192.168.133.102/32 192.168.133.100/32 25 49648 4398046511148 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 192.168.133.100/32 17.167.150.73/32 49655 443 4398046511149 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - 6 17.167.150.73/32 192.168.133.100/32 443 49655 4398046511149 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2016-02-11-20-32-05 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log new file mode 100644 index 0000000000..a6b8e30871 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2016-02-11-21-06-45 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1455224805.349129 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511146 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1455224805.349129 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 1470 4398046511146 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2016-02-11-21-06-46 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout new file mode 100644 index 0000000000..f31aec1a92 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -0,0 +1,22 @@ +http://127.0.0.1:8080/stats/flowentry/clear/42 +http://127.0.0.1:8080/stats/flowentry/add +{"match": {}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 0, "actions": [{"port": 3, "type": "OUTPUT"}, {"port": 7, "type": "OUTPUT"}], "cookie": 4398046511105, "idle_timeout": 0} +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 25, "nw_dst": "74.53.140.153/32", "nw_src": "10.10.1.4/32", "dl_type": 2048, "tp_src": 1470, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 1470, "nw_dst": "10.10.1.4/32", "nw_src": "74.53.140.153/32", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 25, "nw_dst": "192.168.133.102/32", "nw_src": "192.168.133.100/32", "dl_type": 2048, "tp_src": 49648, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 49648, "nw_dst": "192.168.133.100/32", "nw_src": "192.168.133.102/32", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 443, "nw_dst": "17.167.150.73/32", "nw_src": "192.168.133.100/32", "dl_type": 2048, "tp_src": 49655, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 49655, "nw_dst": "192.168.133.100/32", "nw_src": "17.167.150.73/32", "dl_type": 2048, "tp_src": 443, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +Flow_mod_success +Flow_mod_success diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log new file mode 100644 index 0000000000..e4e7d8b877 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ftp +#open 2016-03-11-17-40-18 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p user password command arg mime_type file_size reply_code reply_msg data_channel.passive data_channel.orig_h data_channel.resp_h data_channel.resp_p fuid +#types time string addr port addr port string string string string string count count string bool addr addr port string +1457455890.667768 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,187) T 192.168.21.95 164.107.123.6 47035 - +1457455890.667768 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,187) - - - - - +1457455891.781896 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,231) T 192.168.21.95 164.107.123.6 47079 FaFkMs3Gc0F1kvwXD +1457455894.380514 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,211) T 192.168.21.95 164.107.123.6 47059 Fm58Rm14ZG2Ai7nW9g +1457455900.398202 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - PASV - - - 227 Entering Passive Mode (164,107,123,6,183,197) T 192.168.21.95 164.107.123.6 47045 FnxQXApi8WTTWNyH1 +1457455900.530943 CXWv6p3arKYeMETxOg 192.168.21.95 54089 164.107.123.6 21 - RETR ftp://164.107.123.6/mirror/internic/rfc/rfc1001.txt text/plain 154427 226 File send OK. - - - - FJblKh2PaOnGa8zcmg +#close 2016-03-11-17-40-18 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log index 9362c3742e..674c0c0e3e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/conn.log @@ -3,14 +3,14 @@ #empty_field (empty) #unset_field - #path conn -#open 2016-03-07-21-31-43 +#open 2016-03-08-15-45-10 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] 1324071333.493287 CXWv6p3arKYeMETxOg 192.168.1.79 51880 131.159.21.1 22 tcp ssh 6.159326 2669 2501 SF - - 0 ShAdDaFf 25 3981 20 3549 (empty) -1409516196.337184 CjhGID4nQcgTWjvg4c 10.0.0.18 40184 128.2.6.88 41644 tcp ssh 0.392307 3205 2129 S1 - - 0 ShADad 12 3837 12 2761 (empty) +1409516196.337184 CjhGID4nQcgTWjvg4c 10.0.0.18 40184 128.2.6.88 41644 tcp ssh 2.079071 3813 3633 SF - - 0 ShADadFf 22 4965 26 5017 (empty) +1419870189.485611 CCvvfg3TEfuqmmG4bh 192.168.2.1 57189 192.168.2.158 22 tcp ssh 6.641754 5253 3489 SF - - 0 ShADadFf 38 7241 29 5005 (empty) 1419870206.101883 CsRx2w45OKnoww6xl4 192.168.2.1 57191 192.168.2.158 22 tcp ssh 3.862198 576 813 SF - - 0 ShAdDaFf 23 1784 16 1653 (empty) -1419870189.485611 CCvvfg3TEfuqmmG4bh 192.168.2.1 57189 192.168.2.158 22 tcp ssh 5.267866 4601 2805 S1 - - 0 ShADad 22 5757 18 3749 (empty) -1419996264.318569 CRJuHdVW0XPVINV8a 192.168.2.1 55179 192.168.2.158 2200 tcp ssh 1.124642 1909 1161 S1 - - 0 ShADad 16 2753 12 1793 (empty) +1419996264.318569 CRJuHdVW0XPVINV8a 192.168.2.1 55179 192.168.2.158 2200 tcp ssh 2.557930 2757 1721 RSTR - - 0 ShADadFr 37 4693 29 3225 (empty) 1420588548.721272 CPbrpk1qSsw6ESzHV4 192.168.2.1 56594 192.168.2.158 22 tcp ssh 8.841749 480 537 SF - - 0 ShAdDaFf 17 1376 14 1273 (empty) 1420590124.879760 C6pKV8GSxOnSLghOa 192.168.2.1 56821 192.168.2.158 22 tcp ssh 1.106250 820 1125 SF - - 0 ShAdDaFf 26 2184 20 2173 (empty) 1420590308.775525 CIPOse170MGiRM1Qf4 192.168.2.1 56837 192.168.2.158 22 tcp ssh 1.080767 692 997 SF - - 0 ShAdDaFf 25 2004 19 1993 (empty) @@ -19,16 +19,16 @@ 1420590659.422161 CMXxB5GvmoxJFXdTa 192.168.2.1 56878 192.168.2.158 22 tcp ssh 3.628964 684 825 SF - - 0 ShAdDaFf 25 1996 19 1821 (empty) 1420591379.650462 Caby8b1slFea8xwSmb 192.168.2.1 56940 192.168.2.158 22 tcp ssh 0.104978 500 609 SF - - 0 ShAdDaFf 14 1240 10 1137 (empty) 1420599430.822385 Che1bq3i2rO3KD1Syg 192.168.2.1 57831 192.168.2.158 22 tcp ssh 2.758790 576 813 SF - - 0 ShAdDaFf 23 1784 18 1757 (empty) -1420851448.309629 C3SfNE4BWaU4aSuwkc 192.168.2.1 59246 192.168.2.158 22 tcp ssh 2.046715 2421 3505 S1 - - 0 ShADad 18 3369 13 4189 (empty) -1420860616.400297 CwSkQu4eWZCH7OONC1 192.168.1.32 33910 128.2.13.133 22 tcp ssh 0.660753 3383 2645 S1 - - 0 ShADad 18 4327 16 3485 (empty) -1420860283.029061 CEle3f3zno26fFZkrh 192.168.1.32 41164 128.2.10.238 22 tcp ssh 7.498828 5479 2327 S1 - - 0 ShADad 21 6579 18 3271 (empty) +1420851448.309629 C3SfNE4BWaU4aSuwkc 192.168.2.1 59246 192.168.2.158 22 tcp ssh 3.076752 3049 4165 SF - - 0 ShADadFf 32 4725 23 5369 (empty) +1420860283.029061 CEle3f3zno26fFZkrh 192.168.1.32 41164 128.2.10.238 22 tcp ssh 8.485357 6087 3015 SF - - 0 ShADadFf 32 7759 33 4763 (empty) +1420860616.400297 CwSkQu4eWZCH7OONC1 192.168.1.32 33910 128.2.13.133 22 tcp ssh 1.910959 6471 6037 SF - - 0 ShADadFf 33 8195 29 7565 (empty) 1420868281.639103 CfTOmO0HKorjr8Zp7 192.168.1.32 41268 128.2.10.238 22 tcp ssh 2.710778 5613 2487 SF - - 0 ShADadFf 24 6869 20 3535 (empty) +1420917487.220407 Cab0vO1xNYSS2hJkle 192.168.1.31 52294 192.168.1.32 22 tcp ssh 3.658968 3729 2229 SF - - 0 ShADadFf 36 5613 24 3497 (empty) 1420917487.213378 CzA03V1VcgagLjnO92 192.168.1.31 57621 192.168.1.255 57621 udp - - - - S0 - - 0 D 1 72 0 0 (empty) 1420917487.213468 CyAhVIzHqb7t7kv28 192.168.1.32 57621 192.168.1.31 57621 udp - - - - S0 - - 0 D 1 72 0 0 (empty) -1420917487.220407 Cab0vO1xNYSS2hJkle 192.168.1.31 52294 192.168.1.32 22 tcp ssh 2.807865 3169 1329 S1 - - 0 ShADad 19 4169 13 2013 (empty) 1421006072.431795 Cx3C534wEyF3OvvcQe 192.168.1.31 51476 192.168.1.32 8118 tcp - 0.000539 76 0 SF - - 0 DaFfA 6 388 5 284 (empty) -1421006072.001012 Cx2FqO23omNawSNrxj 192.168.1.31 51489 192.168.1.32 22 tcp ssh 2.408961 3469 1565 S1 - - 0 ShAdDa 25 4805 16 2421 (empty) +1421006072.001012 Cx2FqO23omNawSNrxj 192.168.1.31 51489 192.168.1.32 22 tcp ssh 4.926958 4029 2497 SF - - 0 ShAdDaFf 42 6249 27 3937 (empty) 1421041176.944687 CkDsfG2YIeWJmXWNWj 192.168.1.32 58641 131.103.20.168 22 tcp ssh 0.587601 2885 2309 SF - - 0 ShADdaFf 16 3725 13 2993 (empty) -1421041299.738916 CUKS0W3HFYOnBqSE5e 192.168.1.32 58646 131.103.20.168 22 tcp ssh 0.538385 3517 3197 S1 - - 0 ShADad 18 4461 16 4037 (empty) -1421041526.312919 CRrfvP2lalMAYOCLhj 192.168.1.32 58649 131.103.20.168 22 tcp ssh 0.542213 3517 3197 S1 - - 0 ShADad 17 4409 16 4037 (empty) -#close 2016-03-07-21-31-43 +1421041299.738916 CUKS0W3HFYOnBqSE5e 192.168.1.32 58646 131.103.20.168 22 tcp ssh 2.236727 4477 535101 SF - - 0 ShADadFf 179 13793 226 546861 (empty) +1421041526.312919 CRrfvP2lalMAYOCLhj 192.168.1.32 58649 131.103.20.168 22 tcp ssh 2.066433 4477 534861 SF - - 0 ShADadFf 183 14001 236 547141 (empty) +#close 2016-03-08-15-45-10 diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log index 5b75945aeb..b69c74b717 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events-no-args.log @@ -1,5 +1,6 @@ 0.000000 bro_init 0.000000 filter_change_tracking + 0.000000 NetControl::init 1254722767.492060 protocol_confirmation 1254722767.492060 ChecksumOffloading::check 1254722767.492060 filter_change_tracking diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log index 485c4318e2..27cf2dab34 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log @@ -1,5 +1,6 @@ 0.000000 bro_init 0.000000 filter_change_tracking + 0.000000 NetControl::init 1254722767.492060 protocol_confirmation [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, 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=1254722767.49206, duration=0.0, service={\x0a\x0a}, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, vlan=, inner_vlan=, dpd=, conn=, extract_orig=F, extract_resp=F, thresholds=, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, krb=, modbus=, mysql=, radius=, rdp=, sip=, sip_state=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_DNS diff --git a/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap b/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap new file mode 100644 index 0000000000..02b4254ef2 Binary files /dev/null and b/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap differ diff --git a/testing/btest/bifs/check_subnet.bro b/testing/btest/bifs/check_subnet.bro new file mode 100644 index 0000000000..b725cae73c --- /dev/null +++ b/testing/btest/bifs/check_subnet.bro @@ -0,0 +1,39 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testt: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +function check_member(s: subnet) + { + if ( s in testt ) + print fmt("in says: %s is member", s); + else + print fmt("in says: %s is no member", s); + + if ( check_subnet(s, testt) ) + print fmt("check_subnet says: %s is member", s); + else + print fmt("check_subnet says: %s is no member", s); + + } + +event bro_init() + { + check_member(10.2.0.2/32); + check_member(10.2.0.2/31); + check_member(10.6.0.0/9); + check_member(10.2.0.0/8); + } diff --git a/testing/btest/bifs/filter_subnet_table.bro b/testing/btest/bifs/filter_subnet_table.bro new file mode 100644 index 0000000000..7659096a71 --- /dev/null +++ b/testing/btest/bifs/filter_subnet_table.bro @@ -0,0 +1,49 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testa: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +global testb: table[subnet] of string = { + [10.0.0.0/8] = "a", + [10.2.0.0/16] = "b", + [10.2.0.2/31] = "c", + [10.1.0.0/16] = "d", + [10.3.0.0/16] = "e", + [5.0.0.0/8] = "f", + [5.5.0.0/25] = "g", + [5.2.0.0/32] = "h", + [7.2.0.0/32] = "i", + [[2607:f8b0:4008:807::200e]/64] = "j", + [[2607:f8b0:4007:807::200e]/64] = "k", + [[2607:f8b0:4007:807::200e]/128] = "l" +}; + + +event bro_init() + { + local c = filter_subnet_table(10.2.0.2/32, testa); + print c; + c = filter_subnet_table(10.2.0.2/32, testb); + print c; + c = filter_subnet_table(10.3.0.2/32, testb); + print c; + c = filter_subnet_table(1.0.0.0/8, testb); + print c; + + local unspecified: table[subnet] of string = table(); + c = filter_subnet_table(10.2.0.2/32, unspecified); + print c; + } diff --git a/testing/btest/bifs/matching_subnets.bro b/testing/btest/bifs/matching_subnets.bro new file mode 100644 index 0000000000..87effed19f --- /dev/null +++ b/testing/btest/bifs/matching_subnets.bro @@ -0,0 +1,30 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global testt: set[subnet] = { + 10.0.0.0/8, + 10.2.0.0/16, + 10.2.0.2/31, + 10.1.0.0/16, + 10.3.0.0/16, + 5.0.0.0/8, + 5.5.0.0/25, + 5.2.0.0/32, + 7.2.0.0/32, + [2607:f8b0:4008:807::200e]/64, + [2607:f8b0:4007:807::200e]/64, + [2607:f8b0:4007:807::200e]/128 +}; + +event bro_init() + { + print testt; + local c = matching_subnets(10.2.0.2/32, testt); + print c; + c = matching_subnets([2607:f8b0:4007:807::200e]/128, testt); + print c; + c = matching_subnets(128.0.0.1/32, testt); + print c; + c = matching_subnets(10.0.0.2/8, testt); + print c; + } diff --git a/testing/btest/bifs/subnet_to_addr.bro b/testing/btest/bifs/subnet_to_addr.bro new file mode 100644 index 0000000000..02bb6254e0 --- /dev/null +++ b/testing/btest/bifs/subnet_to_addr.bro @@ -0,0 +1,14 @@ +# @TEST-EXEC: bro -b %INPUT >output 2>error +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff error + +function test_to_addr(sn: subnet, expect: addr) + { + local result = subnet_to_addr(sn); + print fmt("subnet_to_addr(%s) = %s (%s)", sn, result, + result == expect ? "SUCCESS" : "FAILURE"); + } + +test_to_addr(0.0.0.0/32, 0.0.0.0); +test_to_addr(1.2.3.4/16, 1.2.0.0); +test_to_addr([2607:f8b0:4005:803::200e]/128, [2607:f8b0:4005:803::200e]); diff --git a/testing/btest/bifs/subnet_version.bro b/testing/btest/bifs/subnet_version.bro new file mode 100644 index 0000000000..1efd633f68 --- /dev/null +++ b/testing/btest/bifs/subnet_version.bro @@ -0,0 +1,7 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +print is_v4_subnet(1.2.3.4/16); +print is_v4_subnet([2607:f8b0:4005:801::200e]/64); +print is_v6_subnet(1.2.3.4/24); +print is_v6_subnet([2607:f8b0:4005:801::200e]/12); diff --git a/testing/btest/language/expire_multiple.test b/testing/btest/language/expire_multiple.test new file mode 100644 index 0000000000..1e4aaa0975 --- /dev/null +++ b/testing/btest/language/expire_multiple.test @@ -0,0 +1,12 @@ +# @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output + +global s: set[string] &create_expire=1secs &read_expire=1secs; + +# @TEST-START-NEXT: + +global s: set[string] &write_expire=1secs &create_expire=3secs; + +# @TEST-START-NEXT: + +global s: set[string] &write_expire=1secs &read_expire=3secs; diff --git a/testing/btest/language/expire_subnet.test b/testing/btest/language/expire_subnet.test new file mode 100644 index 0000000000..12d5e56b5a --- /dev/null +++ b/testing/btest/language/expire_subnet.test @@ -0,0 +1,96 @@ +# @TEST-EXEC: bro -C -r $TRACES/var-services-std-ports.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +redef table_expire_interval = 1sec; + +global start_time: time; + +function time_past(): interval + { + return network_time() - start_time; + } + +function expire_nums(tbl: table[count] of string, idx: count): interval + { + print fmt("Expired Num: %s --> %s at %s", idx, tbl[idx], time_past()); + return 0sec; + } + +function expire_nets(tbl: table[subnet] of string, idx: subnet): interval + { + print fmt("Expired Subnet: %s --> %s at %s", idx, tbl[idx], time_past()); + return 0sec; + } + +global nums: table[count] of string &read_expire=8sec &expire_func=expire_nums; +global nets: table[subnet] of string &read_expire=8sec &expire_func=expire_nets; +global step: count; + +### Test ### + +function execute_test() + { + local num_a = nums[2]; + local num_b = nums[3]; + + local net_a = nets[192.168.2.0/24]; + #local net_b = nets[192.168.3.0/24]; + local nets_b = ""; + local nets_b_tbl: table[subnet] of string; + + nets_b_tbl = filter_subnet_table(192.168.3.0/24, nets); + for ( idx in nets_b_tbl ) + nets_b += cat(", ", nets_b_tbl[idx]); + nets_b = nets_b[2:]; + + # writing resets expire as expected + #nets[192.168.2.0/24] = "accessed"; + #nets[192.168.3.0/24] = "accessed"; + + print fmt("Accessed table nums: %s; %s", num_a, num_b); + print fmt("Accessed table nets: %s; %s", net_a, nets_b); + print fmt("Time: %s", time_past()); + print ""; + } + +### Events ### + +event bro_init() + { + step = 0; + + nums[0] = "zero"; + nums[1] = "one"; + nums[2] = "two"; + nums[3] = "three"; + nums[4] = "four"; + + nets[192.168.0.0/16] = "zero"; + nets[192.168.1.0/24] = "one"; + nets[192.168.2.0/24] = "two"; + nets[192.168.3.0/24] = "three"; + nets[192.168.4.0/24] = "four"; + } + +event new_packet(c: connection, p: pkt_hdr) + { + if ( step == 0 ) + { + ++step; + start_time = network_time(); + + print "All:"; + for ( num in nums ) + print fmt("%s --> %s", num, nums[num]); + for ( net in nets ) + print fmt("%s --> %s", net, nets[net]); + print fmt("Time: %s", time_past()); + print ""; + } + + if ( (time_past() > 7sec) && (step == 1) ) + { + ++step; + execute_test(); + } + } diff --git a/testing/btest/language/record-function-recursion.bro b/testing/btest/language/record-function-recursion.bro new file mode 100644 index 0000000000..90832bfa69 --- /dev/null +++ b/testing/btest/language/record-function-recursion.bro @@ -0,0 +1,20 @@ +# @TEST-EXEC: bro -b %INPUT 2>&1 >out +# @TEST-EXEC: btest-diff out + +type Outer: record { + id: count &optional; +}; + +type Inner: record { + create: function(input: Outer) : string; +}; + +redef record Outer += { + inner: Inner &optional; +}; + +event bro_init() { + local o = Outer(); + print o; + print type_name(o); +} diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro new file mode 100644 index 0000000000..566739c0b7 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro @@ -0,0 +1,122 @@ +# @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 -r $TRACES/tls/ecdhe.pcap --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >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 send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_acld = NetControl::create_acld(NetControl::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/netcontroltest")); + NetControl::activate(netcontrol_acld, 0); + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +hook NetControl::acld_rule_policy(p: NetControl::PluginState, r: NetControl::Rule, ar: NetControl::AclRule) + { + # use nullzero instead of drop for address drops + if ( r$ty == NetControl::DROP && r$entity$ty == NetControl::ADDRESS && ar$command == "drop" ) + ar$command = "nullzero"; + } + +event connection_established(c: connection) + { + local id = c$id; + + local flow1 = NetControl::Flow( + $src_h=addr_to_subnet(c$id$orig_h), + $dst_h=addr_to_subnet(c$id$resp_h) + ); + local e1: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow1]; + local r1: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + + local flow2 = NetControl::Flow( + $dst_p=c$id$resp_p + ); + local e2: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow2]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="there"]; + + NetControl::add_rule(r1); + NetControl::add_rule(r2); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "add_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_added, id, r, ar$command)); + } + +event NetControl::acld_remove_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "remove_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_removed, id, r, ar$command)); + + if ( r$cid == 4 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro new file mode 100644 index 0000000000..dfeaee1055 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -0,0 +1,115 @@ +# @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 -r $TRACES/tls/ecdhe.pcap --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >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 send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_acld = NetControl::create_acld(NetControl::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/netcontroltest")); + NetControl::activate(netcontrol_acld, 0); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + local id = c$id; + + local flow1 = NetControl::Flow( + $src_h=addr_to_subnet(c$id$orig_h), + $dst_h=addr_to_subnet(c$id$resp_h) + ); + local e1: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow1]; + local r1: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + + local flow2 = NetControl::Flow( + $dst_p=c$id$resp_p + ); + local e2: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow2]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="there"]; + + NetControl::add_rule(r1); + NetControl::add_rule(r2); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "add_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_added, id, r, ar$command)); + } + +event NetControl::acld_remove_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) + { + print "remove_rule", id, r$entity, r$ty, ar; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_removed, id, r, ar$command)); + + if ( r$cid == 4 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro new file mode 100644 index 0000000000..5c42f0d8eb --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -0,0 +1,62 @@ +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=manager-1 bro %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-1 bro --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-2 bro --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT" +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff manager-1/netcontrol.log + +@TEST-START-FILE cluster-layout.bro +redef Cluster::nodes = { + ["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=37757/tcp, $workers=set("worker-1", "worker-2")], + ["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37760/tcp, $manager="manager-1", $interface="eth0"], + ["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37761/tcp, $manager="manager-1", $interface="eth0"], +}; +@TEST-END-FILE + +redef Log::default_rotation_interval = 0secs; +#redef exit_only_after_terminate = T; + +@load base/frameworks/netcontrol + +@if ( Cluster::local_node_type() == Cluster::WORKER ) +event bro_init() + { + suspend_processing(); + } +@endif + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +@if ( Cluster::local_node_type() == Cluster::WORKER ) +event remote_connection_handshake_done(p: event_peer) + { + continue_processing(); + } +@endif + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 1sec); + NetControl::drop_address(id$orig_h, 1sec); + } + +event terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string &default="") + { + print "Rule added", r$id, r$cid; + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro new file mode 100644 index 0000000000..1efe420d73 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -0,0 +1,44 @@ +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff netcontrol_shunt.log +# @TEST-EXEC: btest-diff netcontrol_drop.log +# @TEST-EXEC: btest-diff .stdout + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +function test_mac_flow() + { + local flow = NetControl::Flow( + $src_m = "FF:FF:FF:FF:FF:FF" + ); + local e: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow]; + local r: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e, $expire=15sec]; + + NetControl::add_rule(r); + } + +function test_mac() + { + local e: NetControl::Entity = [$ty=NetControl::MAC, $mac="FF:FF:FF:FF:FF:FF"]; + local r: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e, $expire=15sec]; + + NetControl::add_rule(r); + } + +event NetControl::init_done() &priority=-5 + { + NetControl::shunt_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 30sec); + NetControl::drop_address(1.1.2.2, 15sec, "Hi there"); + NetControl::whitelist_address(1.2.3.4, 15sec); + NetControl::redirect_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 5, 30sec); + NetControl::quarantine_host(127.0.0.2, 8.8.8.8, 127.0.0.3, 15sec); + test_mac(); + test_mac_flow(); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro new file mode 100644 index 0000000000..56a76433f2 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -0,0 +1,107 @@ +# @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 -r $TRACES/smtp.trace --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >send.out" + +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff send/netcontrol.log +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +@load base/frameworks/netcontrol + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event NetControl::init() + { + suspend_processing(); + local netcontrol_broker = NetControl::create_broker(127.0.0.1, broker_port, "bro/event/netcontroltest", T); + NetControl::activate(netcontrol_broker, 0); + } + +event NetControl::init_done() + { + continue_processing(); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 10hrs); + NetControl::drop_address(id$orig_h, 10hrs); + } + +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule added", r$entity, r$ty; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r$entity, r$ty; + } + +event NetControl::rule_timeout(r: NetControl::Rule, i: NetControl::FlowInfo, p: NetControl::PluginState) + { + print "rule timeout", r$entity, r$ty, i; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/netcontrol +@load base/frameworks/broker + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event NetControl::broker_add_rule(id: count, r: NetControl::Rule) + { + print "add_rule", id, r$entity, r$ty; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_added, id, r, "")); + } + +event NetControl::broker_remove_rule(id: count, r: NetControl::Rule) + { + print "remove_rule", id, r$entity, r$ty; + + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_timeout, id, r, NetControl::FlowInfo())); + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_removed, id, r, "")); + + if ( r$cid == 3 ) + terminate(); + } + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro new file mode 100644 index 0000000000..a809833ecf --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -0,0 +1,31 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +module NetControl; + +event connection_established(c: connection) + { + local id = c$id; + NetControl::drop_address_catch_release(id$orig_h); + # second one should be ignored because duplicate + NetControl::drop_address_catch_release(id$orig_h); + + # mean call directly into framework - simulate new connection + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + delete current_blocks[id$orig_h]; + check_conn(id$orig_h); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro b/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro new file mode 100644 index 0000000000..9b8c995fac --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro @@ -0,0 +1,54 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff .stdout + +# Verify the state of internal tables after rules have been deleted... + +@load base/frameworks/netcontrol + +module NetControl; + +export { + global dump_state: function(); +} + +function dump_state() + { + print "Dumping state"; + print rules; + print rule_entities; + print rules_by_subnets; + } + +module GLOBAL; + +global rules: vector of string; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 10); + } + +event remove_all() + { + for ( i in rules ) + NetControl::remove_rule(rules[i]); + } + +event dump_info() + { + NetControl::dump_state(); + } + +event connection_established(c: connection) + { + 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[|rules|] = NetControl::drop_address(id$orig_h, 0secs); + rules[|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); + + schedule 1sec { remove_all() }; + schedule 2sec { dump_info() }; + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro b/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro new file mode 100644 index 0000000000..c64bd9e16b --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b -r $TRACES/tls/google-duplicate.trace %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + NetControl::drop_address(c$id$orig_h, 0secs); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro b/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro new file mode 100644 index 0000000000..e7bb61cc04 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro @@ -0,0 +1,34 @@ +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff out + +@load base/frameworks/netcontrol + +global outfile: file; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event NetControl::init_done() &priority=-5 + { + NetControl::shunt_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 30sec); + NetControl::drop_address(1.1.2.2, 15sec, "Hi there"); + NetControl::whitelist_address(1.2.3.4, 15sec); + NetControl::redirect_flow([$src_h=192.168.17.1, $src_p=32/tcp, $dst_h=192.168.17.2, $dst_p=32/tcp], 5, 30sec); + NetControl::quarantine_host(127.0.0.2, 8.8.8.8, 127.0.0.3, 15sec); + + outfile = open("out"); + local rules = NetControl::find_rules_addr(1.2.3.4); + print outfile, |rules|; + print outfile, rules[0]$entity; + rules = NetControl::find_rules_addr(1.2.3.5); + print outfile, |rules|; + rules = NetControl::find_rules_addr(127.0.0.2); + print outfile, |rules|; + print outfile, rules[0]$entity, rules[0]$ty; + print outfile, rules[3]$entity, rules[3]$ty; + close(outfile); + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro new file mode 100644 index 0000000000..02056a1e0a --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro @@ -0,0 +1,27 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + NetControl::drop_address(id$orig_h, 15sec); + NetControl::whitelist_address(id$orig_h, 15sec); + NetControl::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); + } + +hook NetControl::rule_policy(r: NetControl::Rule) + { + if ( r$expire == 15sec ) + break; + + r$entity$flow$src_h = 0.0.0.0/0; + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro new file mode 100644 index 0000000000..56a764f2e9 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -0,0 +1,37 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global rules: vector of string; + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + local netcontrol_debug_2 = NetControl::create_debug(T); + local of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_debug, 10); + NetControl::activate(netcontrol_of, 10); + NetControl::activate(netcontrol_debug_2, 0); + } + +event remove_all() + { + for ( i in rules ) + NetControl::remove_rule(rules[i]); + } + + +event connection_established(c: connection) + { + 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[|rules|] = NetControl::drop_address(id$orig_h, 0secs); + rules[|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); + + schedule 1sec { remove_all() }; + } + diff --git a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro new file mode 100644 index 0000000000..36c06fcc3d --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro @@ -0,0 +1,21 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global of_controller: OpenFlow::Controller; + +event NetControl::init() + { + of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_of, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + NetControl::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + NetControl::drop_address(id$resp_h, 15sec); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro new file mode 100644 index 0000000000..46a1193a21 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro @@ -0,0 +1,18 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff conn.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_packetfilter = NetControl::create_packetfilter(); + NetControl::activate(netcontrol_packetfilter, 0); + } + +event connection_established(c: connection) + { + local e = NetControl::Entity($ty=NetControl::ADDRESS, $ip=addr_to_subnet(c$id$orig_h)); + local r = NetControl::Rule($ty=NetControl::DROP, $target=NetControl::MONITOR, $entity=e, $expire=10min); + + NetControl::add_rule(r); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro new file mode 100644 index 0000000000..9356253c98 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/netcontrol + +global of_controller: OpenFlow::Controller; + +event NetControl::init() + { + of_controller = OpenFlow::log_new(42); + local netcontrol_of = NetControl::create_openflow(of_controller); + NetControl::activate(netcontrol_of, 0); + } + +event connection_established(c: connection) + { + NetControl::quarantine_host(c$id$orig_h, 8.8.8.8, 192.169.18.1, 10hrs); + } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro b/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro new file mode 100644 index 0000000000..e308205ffc --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/timeout.bro @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b -r $TRACES/tls/ecdhe.pcap --pseudo-realtime %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event NetControl::init() + { + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); + } + +event connection_established(c: connection) + { + NetControl::drop_address(c$id$orig_h, 1secs); + } diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro new file mode 100644 index 0000000000..e973517d44 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -0,0 +1,120 @@ +# @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 -r $TRACES/smtp.trace --pseudo-realtime ../send.bro broker_port=$BROKER_PORT >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 send.bro + +@load base/protocols/conn +@load base/frameworks/openflow + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + suspend_processing(); + of_controller = OpenFlow::broker_new("broker1", 127.0.0.1, broker_port, "bro/event/openflow", 42); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event OpenFlow::controller_activated(name: string, controller: OpenFlow::Controller) + { + continue_processing(); + OpenFlow::flow_clear(of_controller); + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + print "connection established"; + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } + +event OpenFlow::flow_mod_failure(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_failure"; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/openflow + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +global msg_count: count = 0; + +event bro_init() + { + BrokerComm::enable(); + BrokerComm::subscribe_to_events("bro/event/openflow"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +function got_message() + { + ++msg_count; + + if ( msg_count >= 4 ) + terminate(); + } + +event OpenFlow::broker_flow_mod(name: string, dpid: count, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod) + { + print "got flow_mod", dpid, match, flow_mod; + BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_success, name, match, flow_mod, "")); + BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_failure, name, match, flow_mod, "")); + got_message(); + } + +event OpenFlow::broker_flow_clear(name: string, dpid: count) + { + print "flow_clear", dpid; + got_message(); + } + + +@TEST-END-FILE + diff --git a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro new file mode 100644 index 0000000000..d4f08e7822 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro @@ -0,0 +1,32 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff openflow.log + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +global cookie_id: count = 42; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event connection_established(c: connection) + { + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(++cookie_id), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } diff --git a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro new file mode 100644 index 0000000000..cccf60cf99 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro @@ -0,0 +1,55 @@ +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run manager-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=manager-1 bro %INPUT" +# @TEST-EXEC: sleep 1 +# @TEST-EXEC: btest-bg-run worker-1 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-1 bro --pseudo-realtime -C -r $TRACES/smtp.trace %INPUT" +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff manager-1/openflow.log + +@TEST-START-FILE cluster-layout.bro +redef Cluster::nodes = { + ["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=37757/tcp, $workers=set("worker-1", "worker-2")], + ["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37760/tcp, $manager="manager-1", $interface="eth0"], +}; +@TEST-END-FILE + +redef Log::default_rotation_interval = 0secs; +#redef exit_only_after_terminate = T; + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + } + +event connection_established(c: connection) + { + print "conn established"; + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + + terminate(); + } + +event terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + diff --git a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro new file mode 100644 index 0000000000..3bfaa4c076 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -0,0 +1,37 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +@load base/protocols/conn +@load base/frameworks/openflow + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::ryu_new(127.0.0.1, 8080, 42); + of_controller$state$ryu_debug=T; + + OpenFlow::flow_clear(of_controller); + OpenFlow::flow_mod(of_controller, [], [$cookie=OpenFlow::generate_cookie(1), $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +event connection_established(c: connection) + { + local match = OpenFlow::match_conn(c$id); + local match_rev = OpenFlow::match_conn(c$id, T); + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=OpenFlow::generate_cookie(42), + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=30, + $priority=5 + ]; + + OpenFlow::flow_mod(of_controller, match, flow_mod); + OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + } + +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } diff --git a/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro b/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro new file mode 100644 index 0000000000..4791d31460 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro @@ -0,0 +1,5 @@ +# This tests extracting the server reported file size +# from FTP sessions. +# +# @TEST-EXEC: bro -r $TRACES/ftp/ftp-with-numbers-in-filename.pcap +# @TEST-EXEC: btest-diff ftp.log